<template>
  <PageContainer title="角色管理">
    <QueryToolbar>
      <el-button
        v-if="canCreateRole"
        type="primary"
        @click="openCreateDrawer"
      >
        新增角色
      </el-button>
      <el-button
        v-if="canReadRole"
        @click="load"
      >
        刷新
      </el-button>
    </QueryToolbar>
    
    <el-table :data="rows" class="mt-md" empty-text="暂无数据">
      <el-table-column prop="roleCode" label="角色编码" />
      <el-table-column prop="roleName" label="角色名称" />
      <el-table-column prop="status" label="状态" width="120" :formatter="statusFormatter" />
      <el-table-column label="操作" width="280">
        <template #default="{ row }">
          <el-button v-if="canUpdateRole" size="small" @click="handleRename(row)">改名</el-button>
          <el-button v-if="canBindPermissions" size="small" @click="openBindPermissions(row)">绑权限</el-button>
          <el-button v-if="canBindPermissions" size="small" @click="openBindMenus(row)">绑菜单</el-button>
          <el-button
            v-if="canDisableRole && row.status === 'ENABLED'"
            size="small"
            type="warning"
            @click="handleDisable(row.id)"
          >
            停用
          </el-button>
          <el-button
            v-else-if="canEnableRole"
            size="small"
            type="success"
            @click="handleEnable(row.id)"
          >
            启用
          </el-button>
          <el-button
            v-if="canDeleteRole && row.status === 'DISABLED'"
            size="small"
            type="danger"
            @click="handleDeleteRole(row.id, row.roleName)"
          >
            删除
          </el-button>
        </template>
      </el-table-column>
    </el-table>

    <el-pagination
      class="mt-md"
      background
      layout="total, prev, pager, next, sizes"
      :total="totalCount"
      v-model:current-page="pageNo"
      v-model:page-size="pageSize"
      :page-sizes="[10, 20, 50, 100]"
      @size-change="load"
      @current-change="load"
    />

    <el-drawer v-model="createVisible" title="新增角色" :size="DRAWER_SIZE.sm" destroy-on-close>
      <el-form ref="formRef" :model="form" label-position="left" :label-width="LABEL_WIDTH.md" :rules="formRules">
        <el-form-item label="角色编码" prop="roleCode">
          <el-input v-model="form.roleCode" />
        </el-form-item>
        <el-form-item label="角色名称" prop="roleName">
          <el-input v-model="form.roleName" />
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="createVisible = false">取消</el-button>
        <el-button v-if="canCreateRole" type="primary" @click="handleCreate">创建</el-button>
      </template>
    </el-drawer>

    <el-dialog v-model="bindDialogVisible" title="角色权限绑定" :width="DIALOG_WIDTH.md">
      <div v-if="permissionGroups.length === 0">暂无可绑定权限</div>
      <div v-for="group in permissionGroups" :key="group.module" class="mb-md">
        <div class="text-title mb-xs">{{ group.module }}</div>
        <el-checkbox-group v-model="selectedPermissionIds">
          <el-checkbox
            v-for="perm in group.items"
            :key="perm.id"
            :label="perm.id"
            class="mr-lg"
          >
            {{ perm.permissionName }}（{{ perm.permissionCode }}）
          </el-checkbox>
        </el-checkbox-group>
      </div>
      <template #footer>
        <el-button @click="bindDialogVisible = false">取消</el-button>
        <el-button type="primary" @click="submitBindPermissions">保存</el-button>
      </template>
    </el-dialog>
    <el-dialog v-model="bindMenuVisible" title="角色菜单绑定" :width="DIALOG_WIDTH.md">
      <div v-if="menus.length === 0">暂无可绑定菜单</div>
      <el-checkbox-group v-model="selectedMenuIds">
        <el-checkbox v-for="menu in menus" :key="menu.id" :label="menu.id" class="mr-lg mb-xs">
          {{ menu.menuName }}（{{ menu.routePath }}）
        </el-checkbox>
      </el-checkbox-group>
      <template #footer>
        <el-button @click="bindMenuVisible = false">取消</el-button>
        <el-button type="primary" @click="submitBindMenus">保存</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 {
  bindRoleMenus,
  bindRolePermissions,
  createRole,
  deleteRole,
  disableRole,
  enableRole,
  fetchMenus,
  fetchPermissions,
  fetchRoleMenus,
  fetchRolePermissions,
  fetchRoles,
  updateRole,
} from "../../api/modules";
import { PERMS } from "../../constants/permissions";
import { useAuthStore } from "../../stores/auth";
import { toZhStatus } from "../../utils/status";

const rows = ref<any[]>([]);
const pageNo = ref(1);
const pageSize = ref(20);
const totalCount = ref(0);
const authStore = useAuthStore();
const canReadRole = computed(() => authStore.hasPermission(PERMS.role.read));
const canCreateRole = computed(() => authStore.hasPermission(PERMS.role.create));
const canUpdateRole = computed(() => authStore.hasPermission(PERMS.role.update));
const canEnableRole = computed(() => authStore.hasPermission(PERMS.role.enable));
const canDisableRole = computed(() => authStore.hasPermission(PERMS.role.disable));
const canDeleteRole = computed(() => authStore.hasPermission(PERMS.role.delete));
const canBindPermissions = computed(() => authStore.hasPermission(PERMS.role.permissionBind));
const canReadPermissions = computed(() => authStore.hasPermission(PERMS.permission.read));
const createVisible = ref(false);
const form = ref({
  roleCode: "CUSTOM_" + Date.now(),
  roleName: "自定义角色",
});

const formRef = ref<FormInstance>();
const formRules = {
  roleCode: [{ required: true, message: "请输入角色编码", trigger: "blur" }],
  roleName: [{ required: true, message: "请输入角色名称", trigger: "blur" }],
};

const bindDialogVisible = ref(false);
const bindMenuVisible = ref(false);
const selectedRoleId = ref<number | null>(null);
const selectedPermissionIds = ref<number[]>([]);
const permissions = ref<any[]>([]);
const menus = ref<any[]>([]);
const selectedMenuIds = ref<number[]>([]);
const statusFormatter = (_row: any, _column: any, value: unknown) => toZhStatus(value);

const openCreateDrawer = () => {
  form.value = {
    roleCode: "CUSTOM_" + Date.now(),
    roleName: "自定义角色",
  };
  createVisible.value = true;
};

const load = async () => {
  if (!canReadRole.value) {
    rows.value = [];
    return;
  }
  const resp = await fetchRoles({ pageNo: pageNo.value, pageSize: pageSize.value });
  rows.value = resp?.data?.list || [];
  totalCount.value = Number(resp?.data?.total || 0);
};

const permissionGroups = computed(() => {
  const grouped: Record<string, any[]> = {};
  permissions.value.forEach((p) => {
    const key = p.module || "other";
    if (!grouped[key]) {
      grouped[key] = [];
    }
    grouped[key].push(p);
  });
  return Object.keys(grouped).map((module) => ({ module, items: grouped[module] }));
});

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

  await createRole(form.value);
  ElMessage.success("角色创建成功");
  createVisible.value = false;
  await load();
};

const handleRename = async (row: any) => {
  const dialog = await ElMessageBox.prompt("请输入新的角色名称", "编辑角色", {
    confirmButtonText: "确定",
    cancelButtonText: "取消",
    inputValue: row.roleName,
  }).catch(() => null);
  if (!dialog) {
    return;
  }
  await updateRole(row.id, { roleName: dialog.value });
  ElMessage.success("角色更新成功");
  await load();
};

const handleEnable = async (id: number) => {
  await enableRole(id);
  ElMessage.success("角色已启用");
  await load();
};

const handleDisable = async (id: number) => {
  await disableRole(id);
  ElMessage.success("角色已停用");
  await load();
};

const handleDeleteRole = async (id: number, roleName: string) => {
  await ElMessageBox.confirm(`确认删除角色「${roleName}」？删除后不可恢复。`, "删除角色", {
    type: "warning",
    confirmButtonText: "确认删除",
    cancelButtonText: "取消",
  });
  await deleteRole(id);
  ElMessage.success("角色已删除");
  await load();
};

const openBindPermissions = async (row: any) => {
  if (!canReadPermissions.value) {
    ElMessage.warning("当前账号没有 permission.read 权限");
    return;
  }
  selectedRoleId.value = row.id;
  const [permResp, rolePermResp] = await Promise.all([
    fetchPermissions(),
    fetchRolePermissions(row.id),
  ]);
  permissions.value = permResp?.data?.list || [];
  selectedPermissionIds.value = rolePermResp?.data || [];
  bindDialogVisible.value = true;
};

const submitBindPermissions = async () => {
  if (!selectedRoleId.value) {
    return;
  }
  await bindRolePermissions(selectedRoleId.value, { permissionIds: selectedPermissionIds.value });
  ElMessage.success("权限绑定成功，请重新登录以刷新权限");
  bindDialogVisible.value = false;
};

const openBindMenus = async (row: any) => {
  selectedRoleId.value = row.id;
  const [menuResp, roleMenuResp] = await Promise.all([fetchMenus(), fetchRoleMenus(row.id)]);
  menus.value = menuResp?.data?.list || [];
  const validMenuIds = new Set((menus.value || []).map((m: any) => Number(m.id)));
  selectedMenuIds.value = (roleMenuResp?.data || []).filter((id: number) => validMenuIds.has(Number(id)));
  bindMenuVisible.value = true;
};

const submitBindMenus = async () => {
  if (!selectedRoleId.value) {
    return;
  }
  const validMenuIds = new Set((menus.value || []).map((m: any) => Number(m.id)));
  const filteredMenuIds = (selectedMenuIds.value || []).filter((id: number) => validMenuIds.has(Number(id)));
  await bindRoleMenus(selectedRoleId.value, { menuIds: filteredMenuIds });
  ElMessage.success("菜单绑定成功，请重新登录以刷新菜单");
  bindMenuVisible.value = false;
};

onMounted(load);
</script>
