import { Button, Drawer, Form, Input, message, Tag, Typography, Tree } from "antd";
import type { DataNode } from "antd/es/tree";
import { useEffect, useMemo, useState } from "react";
import {
  createRole,
  listPermissions,
  listRolePermissions,
  listRoles,
  saveRolePermissions,
  updateRole
} from "../api";
import type { SysPermission, SysRole } from "../types";
import { usePermission } from "../hooks/usePermission";
import { EditOutlined, PlusOutlined, SafetyCertificateOutlined } from "@ant-design/icons";
import "./Roles.css";

const { Title, Text } = Typography;

const DEFAULT_STATUS = 1;

type PermissionNode = SysPermission & { key: number; children?: PermissionNode[] };

const buildPermissionTree = (list: SysPermission[]): PermissionNode[] => {
  const active = list.filter((p) => p.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 && map.has(node.parentId)) {
      map.get(node.parentId)!.children!.push(node);
    } else {
      roots.push(node);
    }
  });

  const sortNodes = (nodes: PermissionNode[]) => {
    nodes.sort((a, b) => (a.sortOrder || 0) - (b.sortOrder || 0));
    nodes.forEach((n) => n.children && sortNodes(n.children));
  };
  sortNodes(roots);
  return roots;
};

const toTreeData = (nodes: PermissionNode[]): DataNode[] =>
  nodes.map((node) => ({
    key: node.permId,
    title: (
      <span className="role-permission-node">
        <span>{node.name}</span>
        {node.permType === "button" && <Tag color="blue">按钮</Tag>}
      </span>
    ),
    children: node.children ? toTreeData(node.children) : undefined
  }));

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

export default function Roles() {
  const [loading, setLoading] = useState(false);
  const [saving, setSaving] = useState(false);
  const [data, setData] = useState<SysRole[]>([]);
  const [permissions, setPermissions] = useState<SysPermission[]>([]);
  const [rolePermMap, setRolePermMap] = useState<Record<number, number[]>>({});
  const [drawerOpen, setDrawerOpen] = useState(false);
  const [editing, setEditing] = useState<SysRole | null>(null);
  const [selectedPermIds, setSelectedPermIds] = useState<number[]>([]);
  const [form] = Form.useForm();
  const { can } = usePermission();

  const permissionMap = useMemo(() => {
    const map = new Map<number, SysPermission>();
    permissions.forEach((p) => map.set(p.permId, p));
    return map;
  }, [permissions]);

  const permissionTreeData = useMemo(
    () => toTreeData(buildPermissionTree(permissions)),
    [permissions]
  );

  const loadPermissions = async () => {
    try {
      const list = await listPermissions();
      setPermissions(list || []);
    } catch (e) {
      setPermissions([]);
      message.error("加载权限失败，请确认有管理员权限");
    }
  };

  const loadRolePermissions = async (roles: SysRole[]) => {
    const entries = await Promise.all(
      roles.map(async (role) => {
        try {
          const ids = await listRolePermissions(role.roleId);
          const normalized = (ids || []).map((id) => Number(id)).filter((id) => !Number.isNaN(id));
          return [role.roleId, normalized] as const;
        } catch (e) {
          return [role.roleId, []] as const;
        }
      })
    );
    setRolePermMap(Object.fromEntries(entries));
  };

  const loadRoles = async () => {
    setLoading(true);
    try {
      const list = await listRoles();
      const roles = list || [];
      setData(roles);
      await loadPermissions();
      await loadRolePermissions(roles);
    } finally {
      setLoading(false);
    }
  };

  useEffect(() => {
    loadRoles();
  }, []);

  const openCreate = () => {
    setEditing(null);
    setSelectedPermIds([]);
    form.resetFields();
    setDrawerOpen(true);
  };

  const openEdit = (record: SysRole) => {
    setEditing(record);
    setSelectedPermIds(rolePermMap[record.roleId] || []);
    form.setFieldsValue({
      roleName: record.roleName,
      remark: record.remark
    });
    setDrawerOpen(true);
  };

  useEffect(() => {
    if (editing) {
      setSelectedPermIds(rolePermMap[editing.roleId] || []);
    }
  }, [editing, rolePermMap]);

  const handleClose = () => {
    setDrawerOpen(false);
  };

  const submit = async () => {
    try {
      const values = await form.validateFields();
      setSaving(true);
      const payload: Partial<SysRole> = {
        roleCode: editing?.roleCode || generateRoleCode(),
        roleName: values.roleName,
        remark: values.remark,
        status: editing?.status ?? DEFAULT_STATUS
      };
      let roleId = editing?.roleId;
      if (editing) {
        await updateRole(editing.roleId, payload);
      } else {
        await createRole(payload);
      }

      const list = await listRoles();
      const roles = list || [];
      setData(roles);
      if (!roleId) {
        roleId = roles.find((r) => r.roleCode === payload.roleCode)?.roleId;
      }
      if (roleId) {
        await saveRolePermissions(roleId, selectedPermIds);
      }
      await loadRolePermissions(roles);
      setDrawerOpen(false);
      message.success(editing ? "角色已更新" : "角色已创建");
    } catch (e) {
      if (e instanceof Error && e.message) {
        message.error(e.message);
      }
    } finally {
      setSaving(false);
    }
  };

  const renderRolePermissions = (role: SysRole) => {
    const permIds = rolePermMap[role.roleId] || [];
    const perms = permIds
      .map((id) => permissionMap.get(id))
      .filter((p): p is SysPermission => Boolean(p));
    const preview = perms.slice(0, 3);
    const totalCount = permIds.length;

    return (
      <>
        <div className="role-permission-summary">
          <span>权限概览</span>
          <span className="role-permission-badge">{`${totalCount}个权限`}</span>
        </div>
        <div className="role-permission-tags">
          {preview.length ? (
            preview.map((p) => (
              <Tag key={p.permId} className="role-permission-tag">
                {p.name}
              </Tag>
            ))
          ) : (
            <Tag className="role-permission-tag">
              {totalCount ? "已选权限" : "暂无权限"}
            </Tag>
          )}
        </div>
      </>
    );
  };

  return (
    <div className="roles-page">
      <div className="roles-header">
        <div>
          <Title level={4} className="roles-title">
            系统角色权限
          </Title>
          <Text type="secondary" className="roles-subtitle">
            设置系统中不同角色的访问权限和操作边界
          </Text>
        </div>
        {can("sys_role:create") && (
          <Button type="primary" icon={<PlusOutlined />} onClick={openCreate}>
            添加角色
          </Button>
        )}
      </div>

      <div className="roles-grid">
        {data.map((role) => (
          <div key={role.roleId} className="role-card">
            <div className="role-card-header">
              <div className="role-icon">
                <SafetyCertificateOutlined />
              </div>
              {can("sys_role:update") && (
                <Button
                  type="text"
                  className="role-edit-btn"
                  icon={<EditOutlined />}
                  onClick={() => openEdit(role)}
                />
              )}
            </div>

            <div className="role-main">
              <div className="role-name">{role.roleName}</div>
              <div className="role-id">{`ID: ${role.roleCode || role.roleId}`}</div>
            </div>

            {renderRolePermissions(role)}

            <div className="role-footer">
              <span>最后同步</span>
              <span>{role.updatedAt ? "刚刚" : "刚刚"}</span>
            </div>
          </div>
        ))}
        {!data.length && !loading && (
          <div className="roles-empty">暂无角色</div>
        )}
      </div>

      <Drawer
        open={drawerOpen}
        onClose={handleClose}
        width={420}
        closable
        title={
          <div className="role-drawer-title">
            <div className="role-drawer-icon">
              <SafetyCertificateOutlined />
            </div>
            <div>
              <div className="role-drawer-heading">
                {editing ? "编辑角色" : "创建新角色"}
              </div>
            </div>
          </div>
        }
        footer={
          <div className="role-drawer-footer">
            <Button type="link" className="role-drawer-cancel" onClick={handleClose}>
              取消更改
            </Button>
            <Button
              type="primary"
              className="role-drawer-submit"
              loading={saving}
              onClick={submit}
            >
              确认并同步到系统
            </Button>
          </div>
        }
      >
        <Form form={form} layout="vertical" className="role-form">
          <Form.Item
            label="角色名称"
            name="roleName"
            rules={[{ required: true, message: "请输入角色名称" }]}
          >
            <Input placeholder="例如：Auditor" />
          </Form.Item>
          <Form.Item label="描述" name="remark">
            <Input placeholder="该角色的职责描述..." />
          </Form.Item>
        </Form>

        <div className="role-permission-section">
          <div className="role-permission-group-title">
            <span className="role-permission-group-icon">
              <SafetyCertificateOutlined />
            </span>
            <span>权限选择</span>
          </div>
          <div className="role-permission-tree">
            <Tree
              checkable
              selectable={false}
              checkStrictly={false}
              treeData={permissionTreeData}
              checkedKeys={selectedPermIds}
              onCheck={(keys) => {
                const raw = Array.isArray(keys) ? keys : keys.checked;
                const normalized = (raw as Array<string | number>).map((k) => Number(k));
                setSelectedPermIds(normalized.filter((id) => !Number.isNaN(id)));
              }}
              defaultExpandAll
            />
          </div>
        </div>
      </Drawer>
    </div>
  );
}
