import { Avatar, Button, Card, Col, Drawer, Empty, Form, Input, List, Pagination, Radio, Modal, Popconfirm, Select, Space, Table, Tabs, Tag, Tooltip, Tree, Typography, Row, App } from 'antd';
import type { DataNode } from "antd/es/tree";
import { useEffect, useMemo, useState } from "react";
import {
  ApartmentOutlined,
  CheckCircleFilled,
  DeleteOutlined,
  EditOutlined,
  FilterOutlined,
  KeyOutlined,
  PlusOutlined,
  SafetyCertificateOutlined,
  SaveOutlined,
  SearchOutlined,
  TeamOutlined,
  UserAddOutlined,
  UserOutlined
} from "@ant-design/icons";
import {
  bindUsersToRole,
  createRole,
  deleteRole,
  fetchUsersByRoleId,
  getRoleDataScope,
  listOrgs,
  listPermissions,
  listRolePermissions,
  listTenants,
  listUsers,
  pageRoles,
  saveRoleDataScope,
  saveRolePermissions,
  unbindUserFromRole,
  updateRole
} from "@/api";
import { useDict } from "@/hooks/useDict";
import { usePermission } from "@/hooks/usePermission";
import PageHeader from "@/components/shared/PageHeader";
import type { RoleDataScope, SysOrg, SysPermission, SysRole, SysTenant, SysUser } from "@/types";
import "./index.less";

const { Text, Title } = Typography;

type PermissionNode = SysPermission & { key: number; children?: PermissionNode[] };
type OrgTreeNode = SysOrg & { key: number; children?: OrgTreeNode[] };
type RoleTabKey = "permissions" | "dataScope" | "users";

const DEFAULT_STATUS = 1;
const DEFAULT_ROLE_PAGE_SIZE = 10;
const BUTTON_SHORT_LABEL = "按钮";
const DATA_SCOPE_OPTIONS = [
  { label: "全部", value: "ALL" },
  { label: "个人", value: "SELF" },
  { label: "本部门", value: "DEPT" },
  { label: "本部门及下级部门", value: "DEPT_AND_CHILD" },
  { label: "自定义部门", value: "CUSTOM" }
] as const;

function normalizeNumber(value: unknown): number | undefined {
  if (typeof value === "number") {
    return Number.isFinite(value) ? value : undefined;
  }
  if (typeof value === "string" && value.trim() !== "") {
    const parsed = Number(value);
    return Number.isFinite(parsed) ? parsed : undefined;
  }
  if (value && typeof value === "object" && "value" in value) {
    return normalizeNumber((value as { value?: unknown }).value);
  }
  return undefined;
}

function buildPermissionTree(list: SysPermission[]): PermissionNode[] {
  const active = (list || []).filter((permission) => permission.status !== 0);
  const map = new Map<number, PermissionNode>();
  const roots: PermissionNode[] = [];

  active.forEach((item) => {
    map.set(item.permId, { ...item, key: item.permId, children: [] });
  });

  map.forEach((node) => {
    if (node.parentId && node.parentId !== 0) {
      const parent = map.get(node.parentId);
      if (parent) {
        parent.children!.push(node);
      }
    } else {
      roots.push(node);
    }
  });

  const sortNodes = (nodes: PermissionNode[]) => {
    nodes.sort((left, right) => (left.sortOrder || 0) - (right.sortOrder || 0));
    nodes.forEach((node) => node.children && sortNodes(node.children));
  };

  sortNodes(roots);
  return roots;
}

function toPermissionTreeData(nodes: PermissionNode[], buttonShortLabel: string): DataNode[] {
  return nodes.map((node) => ({
    key: node.permId,
    title: (
      <Space>
        <span>{node.name}</span>
        {node.permType === "button" ? <Tag color="cyan" style={{ fontSize: 10 }}>{buttonShortLabel}</Tag> : null}
      </Space>
    ),
    children: node.children?.length ? toPermissionTreeData(node.children, buttonShortLabel) : undefined
  }));
}

function buildOrgTree(list: SysOrg[]): OrgTreeNode[] {
  const map = new Map<number, OrgTreeNode>();
  const roots: OrgTreeNode[] = [];

  list.forEach((item) => {
    map.set(item.id, { ...item, key: item.id, children: [] });
  });

  map.forEach((node) => {
    if (node.parentId && map.has(node.parentId)) {
      map.get(node.parentId)!.children!.push(node);
    } else {
      roots.push(node);
    }
  });

  const sortNodes = (nodes: OrgTreeNode[]) => {
    nodes.sort((left, right) => (left.sortOrder || 0) - (right.sortOrder || 0));
    nodes.forEach((node) => node.children && sortNodes(node.children));
  };

  sortNodes(roots);
  return roots;
}

function toOrgTreeData(nodes: OrgTreeNode[]): DataNode[] {
  return nodes.map((node) => ({
    key: node.id,
    title: node.orgName,
    children: node.children?.length ? toOrgTreeData(node.children) : undefined
  }));
}

function getDataScopeDescription(scopeType: string) {
  switch (scopeType) {
    case "ALL":
      return "当前角色可访问当前租户全部数据。";
    case "SELF":
      return "当前角色仅可访问本人数据。";
    case "DEPT":
      return "当前角色可访问本人所在部门的数据。";
    case "DEPT_AND_CHILD":
      return "当前角色可访问本人所在部门及所有下级部门的数据。";
    case "CUSTOM":
      return "当前角色可访问选中部门的数据。";
    default:
      return "";
  }
}

const generateRoleCode = () => `ROLE_${Date.now().toString(36).toUpperCase()}`;

export default function Roles() {
  const { message } = App.useApp();
  const { can } = usePermission();
  const { items: statusDict } = useDict("sys_common_status");
  const [loading, setLoading] = useState(false);
  const [saving, setSaving] = useState(false);
  const [data, setData] = useState<SysRole[]>([]);
  const [permissions, setPermissions] = useState<SysPermission[]>([]);
  const [selectedRole, setSelectedRole] = useState<SysRole | null>(null);
  const [selectedPermIds, setSelectedPermIds] = useState<number[]>([]);
  const [halfCheckedIds, setHalfCheckedIds] = useState<number[]>([]);
  const [roleUsers, setRoleUsers] = useState<SysUser[]>([]);
  const [loadingUsers, setLoadingUsers] = useState(false);
  const [allUsers, setAllUsers] = useState<SysUser[]>([]);
  const [userModalOpen, setUserModalOpen] = useState(false);
  const [selectedUserKeys, setSelectedUserKeys] = useState<number[]>([]);
  const [userSearchText, setUserSearchText] = useState("");
  const [searchText, setSearchText] = useState("");
  const [rolePage, setRolePage] = useState({ current: 1, size: DEFAULT_ROLE_PAGE_SIZE, total: 0 });
  const [filterTenantId, setFilterTenantId] = useState<number | undefined>(undefined);
  const [drawerOpen, setDrawerOpen] = useState(false);
  const [editing, setEditing] = useState<SysRole | null>(null);
  const [tenants, setTenants] = useState<SysTenant[]>([]);
  const [activeTab, setActiveTab] = useState<RoleTabKey>("permissions");
  const [dataScopeType, setDataScopeType] = useState("SELF");
  const [scopeOrgIds, setScopeOrgIds] = useState<number[]>([]);
  const [scopeOrgTree, setScopeOrgTree] = useState<DataNode[]>([]);
  const [form] = Form.useForm();

  const isPlatformMode = useMemo(() => {
    const profileStr = sessionStorage.getItem("userProfile");
    if (!profileStr) return false;
    const profile = JSON.parse(profileStr);
    return !!profile.isPlatformAdmin;
  }, []);

  const activeTenantId = useMemo(() => normalizeNumber(localStorage.getItem("activeTenantId")) ?? 0, []);
  const permissionTreeData = useMemo(() => toPermissionTreeData(buildPermissionTree(permissions), BUTTON_SHORT_LABEL), [permissions]);
  const filteredModalUsers = useMemo(() => {
    const existingIds = new Set(roleUsers.map((user) => user.userId));
    return allUsers.filter(
      (user) =>
        !existingIds.has(user.userId) &&
        (user.username.toLowerCase().includes(userSearchText.toLowerCase()) || user.displayName.toLowerCase().includes(userSearchText.toLowerCase()))
    );
  }, [allUsers, roleUsers, userSearchText]);

  useEffect(() => {
    if (!isPlatformMode) return;
    listTenants({ current: 1, size: 100 }).then((response) => setTenants(response.records || [])).catch(() => {});
  }, [isPlatformMode]);

  const loadPermissions = async () => {
    try {
      const list = await listPermissions();
      setPermissions(list || []);
      return list || [];
    } catch {
      setPermissions([]);
      return [] as SysPermission[];
    }
  };

  const selectRole = async (role: SysRole, permissionList: SysPermission[] = permissions) => {
    setSelectedRole(role);
    setLoadingUsers(true);
    try {
      const [ids, users, dataScope, orgs] = await Promise.all([
        listRolePermissions(role.roleId),
        fetchUsersByRoleId(role.roleId),
        getRoleDataScope(role.roleId),
        listOrgs(role.tenantId)
      ]);
      const normalized = (ids || []).map((id) => Number(id)).filter((id) => !Number.isNaN(id));
      const leafIds = normalized.filter((id) => !permissionList.some((permission) => permission.parentId === id));
      setSelectedPermIds(leafIds);
      setHalfCheckedIds([]);
      setRoleUsers(users || []);
      setDataScopeType(dataScope?.scopeType || role.dataScopeType || "SELF");
      setScopeOrgIds((dataScope?.orgIds || []).map((id) => Number(id)).filter((id) => !Number.isNaN(id)));
      setScopeOrgTree(toOrgTreeData(buildOrgTree(orgs || [])));
    } finally {
      setLoadingUsers(false);
    }
  };

  const loadRoles = async (page = rolePage.current, size = rolePage.size) => {
    setLoading(true);
    try {
      const permissionList = await loadPermissions();
      const response = await pageRoles({
        current: page,
        size,
        tenantId: isPlatformMode ? filterTenantId : activeTenantId,
        keyword: searchText || undefined
      });
      const roles = response?.records || [];
      setRolePage({ current: page, size, total: response?.total || 0 });
      setData(roles);
      if (roles.length === 0) {
        setSelectedRole(null);
        setRoleUsers([]);
        setSelectedPermIds([]);
        setHalfCheckedIds([]);
        setDataScopeType("SELF");
        setScopeOrgIds([]);
        setScopeOrgTree([]);
      } else if (!selectedRole) {
        await selectRole(roles[0], permissionList);
      } else {
        const updated = roles.find((role) => role.roleId === selectedRole.roleId);
        if (updated) {
          await selectRole(updated, permissionList);
        } else {
          await selectRole(roles[0], permissionList);
        }
      }
    } finally {
      setLoading(false);
    }
  };

  useEffect(() => {
    void loadRoles(rolePage.current, rolePage.size);
  }, [filterTenantId, rolePage.current, rolePage.size, searchText]);

  const loadAllUsers = async () => {
    try {
      const list = await listUsers();
      setAllUsers(list || []);
    } catch {
      setAllUsers([]);
    }
  };

  const openUserModal = () => {
    void loadAllUsers();
    setSelectedUserKeys([]);
    setUserModalOpen(true);
  };

  const handleAddUsers = async () => {
    if (!selectedRole || selectedUserKeys.length === 0) return;
    await bindUsersToRole(selectedRole.roleId, selectedUserKeys);
    message.success("操作成功");
    setUserModalOpen(false);
    await selectRole(selectedRole);
  };

  const handleUnbindUser = async (userId: number) => {
    if (!selectedRole) return;
    if (selectedRole.roleCode === "TENANT_ADMIN" && roleUsers.length <= 1) {
      message.warning("租户管理员角色至少需要保留一个绑定用户");
      return;
    }
    await unbindUserFromRole(selectedRole.roleId, userId);
    message.success("操作成功");
    await selectRole(selectedRole);
  };

  const openCreate = () => {
    setEditing(null);
    form.resetFields();
    form.setFieldsValue({ status: 1, tenantId: isPlatformMode ? undefined : activeTenantId });
    setDrawerOpen(true);
  };

  const openEditBasic = (event: React.MouseEvent, record: SysRole) => {
    event.stopPropagation();
    setEditing(record);
    form.setFieldsValue(record);
    setDrawerOpen(true);
  };

  const handleRemove = async (event: React.MouseEvent, id: number) => {
    event.stopPropagation();
    await deleteRole(id);
    message.success("操作成功");
    if (selectedRole?.roleId === id) setSelectedRole(null);
    await loadRoles(rolePage.current, rolePage.size);
  };

  const submitBasic = async () => {
    const values = await form.validateFields();
    setSaving(true);
    try {
      const payload: Partial<SysRole> = {
        roleCode: editing?.roleCode || values.roleCode || generateRoleCode(),
        roleName: values.roleName,
        remark: values.remark,
        status: values.status ?? DEFAULT_STATUS,
        tenantId: values.tenantId,
        dataScopeType: editing?.dataScopeType || "SELF"
      };
      if (editing) {
        await updateRole(editing.roleId, payload);
      } else {
        await createRole(payload);
      }
      message.success("操作成功");
      setDrawerOpen(false);
      await loadRoles(rolePage.current, rolePage.size);
    } finally {
      setSaving(false);
    }
  };

  const handleRolePageChange = (page: number, pageSize: number) => {
    setRolePage((prev) => ({ ...prev, current: page, size: pageSize }));
  };

  const savePermissions = async () => {
    if (!selectedRole) return;
    setSaving(true);
    try {
      await saveRolePermissions(selectedRole.roleId, Array.from(new Set([...selectedPermIds, ...halfCheckedIds])));
      message.success("操作成功");
    } finally {
      setSaving(false);
    }
  };

  const saveDataScope = async () => {
    if (!selectedRole) return;
    if (dataScopeType === "CUSTOM" && scopeOrgIds.length === 0) {
      message.warning("请选择至少一个部门");
      return;
    }
    setSaving(true);
    try {
      const payload: RoleDataScope = {
        roleId: selectedRole.roleId,
        scopeType: dataScopeType,
        orgIds: dataScopeType === "CUSTOM" ? scopeOrgIds : []
      };
      await saveRoleDataScope(selectedRole.roleId, payload);
      message.success("操作成功");
      setSelectedRole((prev) => (prev ? { ...prev, dataScopeType } : prev));
      setData((prev) => prev.map((item) => item.roleId === selectedRole.roleId ? { ...item, dataScopeType } : item));
    } finally {
      setSaving(false);
    }
  };

  const handlePrimarySave = () => {
    if (activeTab === "permissions") {
      void savePermissions();
      return;
    }
    if (activeTab === "dataScope") {
      void saveDataScope();
    }
  };

  const saveDisabled = !selectedRole || activeTab === "users" || (activeTab === "permissions" && !can("sys:role:permission:save")) || (activeTab === "dataScope" && !can("sys:role:update"));
  const saveLabel = activeTab === "dataScope" ? "保存数据权限" : "保存";

  return (
    <div className="app-page roles-page-v2">
      <PageHeader title="角色管理" subtitle="维护角色基础信息、功能权限、数据权限与成员绑定" />

      <div className="app-page__page-actions">
        {can("sys:role:create") && <Button type="primary" icon={<PlusOutlined />} onClick={openCreate}>{"新增角色"}</Button>}
      </div>

      <div className="roles-layout">
        <Row gutter={24} className="roles-layout__row">
          <Col span={7} className="roles-layout__side">
            <Card title={<Space><ApartmentOutlined /><span>{"角色列表"}</span></Space>} variant="borderless" className="app-page__panel-card roles-side-card">
              <div className="role-search-panel">
                {isPlatformMode && (
                  <Select
                    placeholder="按租户筛选"
                    style={{ width: "100%" }}
                    allowClear
                    suffixIcon={<FilterOutlined />}
                    value={filterTenantId}
                    onChange={(value) => { setFilterTenantId(normalizeNumber(value)); setRolePage((prev) => ({ ...prev, current: 1 })); }}
                    options={tenants.map((tenant) => ({ label: tenant.tenantName, value: tenant.id }))}
                  />
                )}
                <div className="role-search-bar">
                  <Input placeholder="输入角色名称或编码搜索" prefix={<SearchOutlined style={{ color: "#94a3b8" }} />} value={searchText} onChange={(event) => setSearchText(event.target.value)} allowClear />
                  <Button type="default" onClick={() => { setSearchText(""); setFilterTenantId(undefined); setRolePage((prev) => ({ ...prev, current: 1 })); }}>{"重置"}</Button>
                </div>
              </div>

              <div className="role-list-container-v3">
                <List
                  loading={loading}
                  dataSource={data}
                  pagination={false}
                  locale={{ emptyText: <Empty description="暂无角色数据" image={Empty.PRESENTED_IMAGE_SIMPLE} /> }}
                  renderItem={(item) => (
                    <div key={item.roleId} className={`role-item-card-v3 ${selectedRole?.roleId === item.roleId ? "active" : ""}`} onClick={() => void selectRole(item)}>
                      <div className="role-item-symbol" aria-hidden="true">
                        <SafetyCertificateOutlined />
                      </div>
                      <div className="role-item-main">
                        <div className="role-item-name-row">
                          <Text strong className="role-name">{item.roleName}</Text>
                          {isPlatformMode && <Tag color="blue" style={{ fontSize: 10, scale: "0.8", margin: "0 0 0 4px", borderRadius: "10px" }}>{item.tenantId === 0 ? "平台租户" : tenants.find((tenant) => tenant.id === item.tenantId)?.tenantName || `租户:${item.tenantId}`}</Tag>}
                          {item.status === 0 && <Tag color="error" style={{ fontSize: 10, scale: "0.8", margin: 0 }}>{"停用"}</Tag>}
                        </div>
                        <Text type="secondary" className="role-code">{item.roleCode}</Text>
                      </div>
                      {selectedRole?.roleId === item.roleId ? (
                        <div className="role-item-selected-mark" aria-hidden="true">
                          <CheckCircleFilled />
                        </div>
                      ) : null}
                      <div className="role-item-actions">
                        <Space size={4}>
                          <Tooltip title="编辑">
                            <Button type="text" size="small" icon={<EditOutlined />} onClick={(event) => openEditBasic(event, item)} />
                          </Tooltip>
                          {item.roleCode !== "ADMIN" && (
                            <Popconfirm title="确定删除该角色吗？" okText="确定" cancelText="取消" onConfirm={(event) => void handleRemove(event!, item.roleId)}>
                              <Button type="text" size="small" danger icon={<DeleteOutlined />} onClick={(event) => event.stopPropagation()} />
                            </Popconfirm>
                          )}
                        </Space>
                      </div>
                    </div>
                  )}
                />
              </div>
              <div className="role-list-pagination">
                <Pagination
                  current={rolePage.current}
                  pageSize={rolePage.size}
                  total={rolePage.total}
                  size="small"
                  onChange={handleRolePageChange}
                  showSizeChanger
                  pageSizeOptions={["10", "20", "50"]}
                />
              </div>
            </Card>
          </Col>

          <Col span={17} className="roles-layout__detail">
            {selectedRole ? (
              <Card
                className="app-page__panel-card roles-detail-card"
                variant="borderless"
                title={<div className="role-detail-header"><div className="role-detail-icon"><SafetyCertificateOutlined /></div><div className="role-detail-heading"><div className="role-detail-title">{selectedRole.roleName}</div><Text type="secondary" className="role-detail-code">{selectedRole.roleCode}</Text></div></div>}
                extra={<Button type="primary" icon={<SaveOutlined />} loading={saving} onClick={handlePrimarySave} disabled={saveDisabled} style={{ borderRadius: "6px" }}>{saveLabel}</Button>}
              >
                <Tabs 
                  activeKey={activeTab} 
                  onChange={(key) => setActiveTab(key as RoleTabKey)} 
                  className="role-detail-tabs"
                  items={[
                    {
                      key: "permissions",
                      label: <Space><KeyOutlined />{"功能权限"}</Space>,
                      children: (
                        <div className="role-detail-pane">
                          <div className="permission-tree-wrapper">
                            <Tree
                              checkable
                              selectable={false}
                              checkStrictly={false}
                              treeData={permissionTreeData}
                              checkedKeys={selectedPermIds}
                              onCheck={(keys, info) => {
                                const checked = Array.isArray(keys) ? keys : keys.checked;
                                const halfChecked = info.halfCheckedKeys || [];
                                setSelectedPermIds(checked.map((key) => Number(key)));
                                setHalfCheckedIds(halfChecked.map((key) => Number(key)));
                              }}
                              defaultExpandAll
                            />
                          </div>
                        </div>
                      )
                    },
                    {
                      key: "dataScope",
                      label: <Space><ApartmentOutlined />{"数据权限"}</Space>,
                      children: (
                        <div className="role-detail-pane">
                          <div style={{ marginBottom: 16 }}>
                            <Radio.Group value={dataScopeType} onChange={(event) => setDataScopeType(event.target.value)} optionType="button" buttonStyle="solid">
                              {DATA_SCOPE_OPTIONS.map((item) => (
                                <Radio.Button key={item.value} value={item.value}>{item.label}</Radio.Button>
                              ))}
                            </Radio.Group>
                          </div>
                          <div style={{ marginBottom: 16, color: "#64748b" }}>{getDataScopeDescription(dataScopeType)}</div>
                          {dataScopeType === "CUSTOM" ? (
                            <div className="permission-tree-wrapper">
                              <Tree
                                checkable
                                selectable={false}
                                treeData={scopeOrgTree}
                                checkedKeys={scopeOrgIds}
                                onCheck={(keys) => {
                                  const checked = Array.isArray(keys) ? keys : keys.checked;
                                  setScopeOrgIds(checked.map((key) => Number(key)));
                                }}
                                defaultExpandAll
                              />
                            </div>
                          ) : (
                            <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} description="当前范围不需要选择部门" />
                          )}
                        </div>
                      )
                    },
                    {
                      key: "users",
                      label: <Space><TeamOutlined />{`成员管理 (${roleUsers.length})`}</Space>,
                      children: (
                        <div className="role-detail-pane">
                          <div className="role-members-toolbar">
                            <Title level={5} style={{ margin: 0 }}>{"已绑定用户"}</Title>
                            <Button type="primary" ghost icon={<UserAddOutlined />} onClick={openUserModal} disabled={!can("sys:role:update")}>{"绑定用户"}</Button>
                          </div>
                          <Table
                            rowKey="userId"
                            size="small"
                            loading={loadingUsers}
                            dataSource={roleUsers}
                            pagination={{ pageSize: 10, size: "small" }}
                            columns={[
                              {
                                title: "用户信息",
                                render: (_: unknown, user: SysUser) => (
                                  <Space>
                                    <Avatar size="small" icon={<UserOutlined />} style={{ backgroundColor: "#f0f2f5", color: "#8c8c8c" }} />
                                    <div>
                                      <div style={{ fontWeight: 500 }}>{user.displayName}</div>
                                      <div style={{ fontSize: 11, color: "#bfbfbf" }}>@{user.username}</div>
                                    </div>
                                  </Space>
                                )
                              },
                              { title: "手机号", dataIndex: "phone", className: "tabular-nums" },
                              { title: "状态", dataIndex: "status", width: 80, render: (status: number) => <Tag color={status === 1 ? "green" : "red"}>{status === 1 ? "启用" : "停用"}</Tag> },
                              {
                                title: "操作",
                                key: "action",
                                width: 80,
                                render: (_: unknown, user: SysUser) => (
                                  <Popconfirm title="确定解除该用户绑定吗？" okText="确定" cancelText="取消" onConfirm={() => void handleUnbindUser(user.userId)} disabled={!can("sys:role:update")}>
                                    <Button type="text" danger size="small" icon={<DeleteOutlined />} disabled={!can("sys:role:update")} />
                                  </Popconfirm>
                                )
                              }
                            ]}
                          />
                        </div>
                      )
                    }
                  ]}
                />
              </Card>
            ) : (
              <div className="app-page__empty-state"><Empty description="请选择左侧角色查看详情" /></div>
            )}
          </Col>
        </Row>
      </div>

      <Modal title="绑定用户到角色" open={userModalOpen} onCancel={() => setUserModalOpen(false)} onOk={() => void handleAddUsers()} okText="确定" cancelText="取消" width={650} destroyOnHidden>
        <div style={{ marginBottom: 16 }}>
          <Input placeholder="搜索用户名或显示名称" prefix={<SearchOutlined />} value={userSearchText} onChange={(event) => setUserSearchText(event.target.value)} allowClear />
        </div>
        <Table rowKey="userId" size="small" dataSource={filteredModalUsers} pagination={{ pageSize: 6 }} rowSelection={{ selectedRowKeys: selectedUserKeys, onChange: (keys) => setSelectedUserKeys(keys as number[]) }} columns={[{ title: "显示名称", dataIndex: "displayName" }, { title: "用户名", dataIndex: "username" }, { title: "手机号", dataIndex: "phone" }]} />
      </Modal>

      <Drawer title={editing ? "编辑角色" : "新增角色"} open={drawerOpen} onClose={() => setDrawerOpen(false)} width={420} destroyOnHidden forceRender footer={<div className="app-page__drawer-footer"><Button onClick={() => setDrawerOpen(false)}>{"取消"}</Button><Button type="primary" loading={saving} onClick={() => void submitBasic()}>{"保存"}</Button></div>}>
        <Form form={form} layout="vertical">
          <Form.Item label="租户" name="tenantId" rules={[{ required: true }]} hidden={!isPlatformMode}>
            <Select options={tenants.map((tenant) => ({ label: tenant.tenantName, value: tenant.id }))} disabled={!!editing} />
          </Form.Item>
          <Form.Item label="角色名称" name="roleName" rules={[{ required: true }]}>
            <Input placeholder="请输入角色名称" />
          </Form.Item>
          <Form.Item label="角色编码" name="roleCode" rules={[{ required: true }]}>
            <Input placeholder="请输入角色编码" disabled={!!editing} />
          </Form.Item>
          <Form.Item label="状态" name="status" initialValue={1}>
            <Select options={statusDict.map((item) => ({ label: item.itemLabel, value: Number(item.itemValue) }))} />
          </Form.Item>
          <Form.Item label="备注" name="remark">
            <Input.TextArea rows={4} placeholder="请输入角色说明或适用范围" />
          </Form.Item>
        </Form>
      </Drawer>
    </div>
  );
}
