<template>
  <PageContainer title="菜单与权限">
    <el-tabs v-model="activeTab" @tab-change="onTabChange">
      <el-tab-pane label="菜单管理" name="menus">
        <QueryToolbar>
          <el-button v-if="canManage" type="primary" @click="openCreateDrawer">新增菜单</el-button>
          <el-button v-if="canManage" :disabled="rows.length === 0" @click="handleSaveOrder">保存排序</el-button>
          <el-button v-if="canRead" @click="load">刷新</el-button>
        </QueryToolbar>

        <el-table :data="rows" class="mt-md" empty-text="暂无数据">
          <el-table-column prop="menuCode" label="菜单编码" width="160" />
          <el-table-column prop="menuName" label="菜单名称" width="160" />
          <el-table-column prop="routePath" label="路由地址" />
          <el-table-column prop="permissionCode" label="权限码" width="180" />
          <el-table-column label="排序" width="120">
            <template #default="{ row }">
              <el-input-number v-if="canManage" v-model="row.sortNo" :min="1" />
              <span v-else>{{ row.sortNo }}</span>
            </template>
          </el-table-column>
          <el-table-column prop="status" label="状态" width="100" :formatter="statusFormatter" />
          <el-table-column label="操作" width="280">
            <template #default="{ row }">
              <el-button v-if="canManage" size="small" :disabled="!canMoveUp(row)" @click="moveUp(row)">上移</el-button>
              <el-button v-if="canManage" size="small" :disabled="!canMoveDown(row)" @click="moveDown(row)">下移</el-button>
              <el-button
                v-if="canManage"
                size="small"
                :type="row.status === 'ENABLED' ? 'warning' : 'success'"
                @click="toggleStatus(row)"
              >
                {{ row.status === "ENABLED" ? "停用" : "启用" }}
              </el-button>
              <el-button v-if="canManage" size="small" @click="openEdit(row)">编辑</el-button>
            </template>
          </el-table-column>
        </el-table>
      </el-tab-pane>
      <el-tab-pane label="权限管理" name="permissions">
        <el-button v-if="canReadPermissions" type="primary" @click="loadPermissions">刷新</el-button>
        <el-table :data="permissions" class="mt-md" empty-text="暂无数据">
          <el-table-column prop="permissionCode" label="权限码" min-width="260" />
          <el-table-column prop="permissionName" label="权限名称" min-width="220" />
          <el-table-column prop="module" label="模块" width="160" />
        </el-table>
      </el-tab-pane>
    </el-tabs>

    <el-drawer v-model="createVisible" title="新增菜单" :size="DRAWER_SIZE.md" destroy-on-close>
      <el-form ref="formRef" :model="form" label-position="left" :label-width="LABEL_WIDTH.md" :rules="formRules">
        <el-form-item label="菜单编码" prop="menuCode">
          <el-input v-model="form.menuCode" />
        </el-form-item>
        <el-form-item label="菜单名称" prop="menuName">
          <el-input v-model="form.menuName" />
        </el-form-item>
        <el-form-item label="路由" prop="routePath">
          <el-input v-model="form.routePath" placeholder="/projects" />
        </el-form-item>
        <el-form-item label="权限码" prop="permissionCode">
          <el-input v-model="form.permissionCode" placeholder="如 project.create" />
        </el-form-item>
        <el-form-item label="排序">
          <el-input-number v-model="form.sortNo" :min="1" />
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="createVisible = false">取消</el-button>
        <el-button v-if="canManage" type="primary" @click="handleCreate">创建</el-button>
      </template>
    </el-drawer>

    <el-dialog v-model="editVisible" title="编辑菜单" :width="DIALOG_WIDTH.md">
      <el-form ref="editFormRef" :model="editForm" label-position="left" :label-width="LABEL_WIDTH.md" :rules="formRules">
        <el-form-item label="菜单名称" prop="menuName">
          <el-input v-model="editForm.menuName" />
        </el-form-item>
        <el-form-item label="路由地址" prop="routePath">
          <el-input v-model="editForm.routePath" />
        </el-form-item>
        <el-form-item label="权限码" prop="permissionCode">
          <el-input v-model="editForm.permissionCode" />
        </el-form-item>
        <el-form-item label="排序">
          <el-input-number v-model="editForm.sortNo" :min="1" />
        </el-form-item>
        <el-form-item label="状态">
          <el-select v-model="editForm.status">
            <el-option label="启用" value="ENABLED" />
            <el-option label="停用" value="DISABLED" />
          </el-select>
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="editVisible = false">取消</el-button>
        <el-button type="primary" @click="handleSave">保存</el-button>
      </template>
    </el-dialog>
  </PageContainer>
</template>

<script setup lang="ts">
import { computed, onMounted, ref } from "vue";
import PageContainer from "../../components/PageContainer.vue";
import QueryToolbar from "../../components/QueryToolbar.vue";
import { DRAWER_SIZE, DIALOG_WIDTH, LABEL_WIDTH } from "../../constants/ui";
import { ElMessage, ElMessageBox } from "element-plus";
import type { FormInstance, FormRules } from "element-plus";
import { useRoute, useRouter } from "vue-router";
import { createMenu, fetchMenuRoles, fetchMenus, fetchPermissions, reorderMenus, updateMenu } from "../../api/modules";
import { PERMS } from "../../constants/permissions";
import { useAuthStore } from "../../stores/auth";
import { toZhStatus } from "../../utils/status";

const authStore = useAuthStore();
const canRead = computed(() => authStore.hasPermission(PERMS.role.read));
const canReadPermissions = computed(() => authStore.hasPermission(PERMS.permission.read));
const canManage = computed(() => authStore.hasPermission(PERMS.role.permissionBind));
const route = useRoute();
const router = useRouter();
const activeTab = ref(String(route.query.tab || "menus") === "permissions" ? "permissions" : "menus");
const rows = ref<any[]>([]);
const permissions = ref<any[]>([]);
const createVisible = ref(false);
const editVisible = ref(false);
const editId = ref<number | null>(null);
const editForm = ref<any>({});
const form = ref({
  menuCode: "",
  menuName: "",
  routePath: "",
  permissionCode: "",
  sortNo: 100,
});
const formRef = ref<FormInstance>();
const editFormRef = ref<FormInstance>();
const formRules = ref<FormRules>({
  menuCode: [{ required: true, message: "请输入菜单编码", trigger: "blur" }],
  menuName: [{ required: true, message: "请输入菜单名称", trigger: "blur" }],
  routePath: [{ required: true, message: "请输入路由地址", trigger: "blur" }],
});
const statusFormatter = (_row: any, _column: any, value: unknown) => toZhStatus(value);

const openCreateDrawer = () => {
  form.value = {
    menuCode: "",
    menuName: "",
    routePath: "",
    permissionCode: "",
    sortNo: 100,
  };
  createVisible.value = true;
};

const load = async () => {
  const resp = await fetchMenus();
  rows.value = resp?.data?.list || [];
};

const loadPermissions = async () => {
  const resp = await fetchPermissions();
  permissions.value = resp?.data?.list || [];
};

const onTabChange = async (name: string | number) => {
  const tab = String(name);
  await router.replace({ path: "/menus", query: tab === "permissions" ? { tab: "permissions" } : {} });
  if (tab === "permissions") {
    await loadPermissions();
  } else {
    await load();
  }
};

const canMoveUp = (row: any) => {
  const idx = rows.value.findIndex((x) => x.id === row.id);
  return idx > 0;
};

const canMoveDown = (row: any) => {
  const idx = rows.value.findIndex((x) => x.id === row.id);
  return idx >= 0 && idx < rows.value.length - 1;
};

const saveMenu = async (row: any, patch: any) => {
  await updateMenu(row.id, {
    menuName: String(patch.menuName ?? row.menuName).trim(),
    routePath: String(patch.routePath ?? row.routePath).trim(),
    permissionCode: String(patch.permissionCode ?? row.permissionCode).trim(),
    sortNo: Number(patch.sortNo ?? row.sortNo),
    status: String(patch.status ?? row.status) as "ENABLED" | "DISABLED",
  });
};

const handleCreate = async () => {
  if (!formRef.value) return;
  const valid = await formRef.value.validate().catch(() => false);
  if (!valid) return;

  await createMenu({
    menuCode: form.value.menuCode.trim(),
    menuName: form.value.menuName.trim(),
    routePath: form.value.routePath.trim(),
    permissionCode: form.value.permissionCode.trim(),
    sortNo: form.value.sortNo,
  });
  ElMessage.success("菜单创建成功");
  createVisible.value = false;
  await load();
};

const openEdit = (row: any) => {
  editId.value = row.id;
  editForm.value = { ...row };
  editVisible.value = true;
};

const handleSave = async () => {
  if (!editId.value) return;
  
  if (!editFormRef.value) return;
  const valid = await editFormRef.value.validate().catch(() => false);
  if (!valid) return;

  await saveMenu(editForm.value, { ...editForm.value, id: editId.value });
  ElMessage.success("菜单更新成功");
  editVisible.value = false;
  await load();
};

const moveUp = async (row: any) => {
  const idx = rows.value.findIndex((x) => x.id === row.id);
  if (idx <= 0) {
    return;
  }
  const prev = rows.value[idx - 1];
  await Promise.all([saveMenu(row, { sortNo: prev.sortNo }), saveMenu(prev, { sortNo: row.sortNo })]);
  ElMessage.success("菜单排序已更新");
  await load();
};

const moveDown = async (row: any) => {
  const idx = rows.value.findIndex((x) => x.id === row.id);
  if (idx < 0 || idx >= rows.value.length - 1) {
    return;
  }
  const next = rows.value[idx + 1];
  await Promise.all([saveMenu(row, { sortNo: next.sortNo }), saveMenu(next, { sortNo: row.sortNo })]);
  ElMessage.success("菜单排序已更新");
  await load();
};

const toggleStatus = async (row: any) => {
  const nextStatus = row.status === "ENABLED" ? "DISABLED" : "ENABLED";
  if (nextStatus === "DISABLED") {
    const roleResp = await fetchMenuRoles(row.id);
    const roleNames: string[] = roleResp?.data || [];
    const tip = roleNames.length > 0 ? `该菜单已绑定角色：${roleNames.join("、")}。停用后这些角色将看不到该菜单，确认继续？` : "确认停用该菜单？";
    await ElMessageBox.confirm(tip, "停用影响提示", {
      confirmButtonText: "确认停用",
      cancelButtonText: "取消",
      type: "warning",
    });
  }
  await saveMenu(row, { status: nextStatus });
  ElMessage.success(nextStatus === "ENABLED" ? "菜单已启用" : "菜单已停用");
  await load();
};

const handleSaveOrder = async () => {
  await reorderMenus({
    menus: rows.value.map((x) => ({
      id: Number(x.id),
      sortNo: Number(x.sortNo),
    })),
  });
  ElMessage.success("菜单排序已批量保存");
  await load();
};

onMounted(async () => {
  if (activeTab.value === "permissions") {
    if (canReadPermissions.value) {
      await loadPermissions();
    }
  } else if (canRead.value) {
    await load();
  }
});
</script>
