import { Button, Card, Col, message, Row, Space, Table, Tag, Tree, Typography } from "antd";
import type { DataNode } from "antd/es/tree";
import { useEffect, useMemo, useState } from "react";
import { listPermissions, listRolePermissions, listRoles, saveRolePermissions } from "../api";
import type { SysPermission, SysRole } from "../types";

const { Title, Text } = Typography;

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

function buildPermissionTree(list: SysPermission[]): PermissionNode[] {
  const map = new Map<number, PermissionNode>();
  const roots: PermissionNode[] = [];

  list.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;
}

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

export default function RolePermissionBinding() {
  const [roles, setRoles] = useState<SysRole[]>([]);
  const [permissions, setPermissions] = useState<SysPermission[]>([]);
  const [loadingRoles, setLoadingRoles] = useState(false);
  const [loadingPerms, setLoadingPerms] = useState(false);
  const [saving, setSaving] = useState(false);
  const [selectedRoleId, setSelectedRoleId] = useState<number | null>(null);
  const [checkedPermIds, setCheckedPermIds] = useState<number[]>([]);

  const selectedRole = useMemo(
    () => roles.find((r) => r.roleId === selectedRoleId) || null,
    [roles, selectedRoleId]
  );

  const loadRoles = async () => {
    setLoadingRoles(true);
    try {
      const list = await listRoles();
      setRoles(list || []);
    } finally {
      setLoadingRoles(false);
    }
  };

  const loadPermissions = async () => {
    setLoadingPerms(true);
    try {
      const list = await listPermissions();
      setPermissions(list || []);
    } catch (e) {
      message.error("加载权限失败，请确认接口已实现");
    } finally {
      setLoadingPerms(false);
    }
  };

  const loadRolePermissions = async (roleId: number) => {
    try {
      const list = await listRolePermissions(roleId);
      setCheckedPermIds(list || []);
    } catch (e) {
      setCheckedPermIds([]);
      message.error("加载角色权限失败，请确认接口已实现");
    }
  };

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

  useEffect(() => {
    if (selectedRoleId) {
      loadRolePermissions(selectedRoleId);
    } else {
      setCheckedPermIds([]);
    }
  }, [selectedRoleId]);

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

  const handleSave = async () => {
    if (!selectedRoleId) {
      message.warning("请先选择角色");
      return;
    }
    setSaving(true);
    try {
      await saveRolePermissions(selectedRoleId, checkedPermIds);
      message.success("角色权限绑定已保存");
    } catch (e) {
      message.error("保存失败，请确认接口已实现");
    } finally {
      setSaving(false);
    }
  };

  return (
    <div className="page-shell">
      <div className="page-header">
        <div>
          <Title level={4} className="page-title">角色权限绑定</Title>
          <Text type="secondary" className="page-subtitle">为角色配置菜单与按钮权限</Text>
        </div>
        <Button type="primary" onClick={handleSave} loading={saving} disabled={!selectedRoleId}>
          保存绑定
        </Button>
      </div>

      <Row gutter={[24, 24]}>
        <Col xs={24} lg={10}>
          <Card title="选择角色" bordered={false} className="surface-card">
            <Table
              rowKey="roleId"
              size="middle"
              loading={loadingRoles}
              dataSource={roles}
              rowSelection={{
                type: "radio",
                selectedRowKeys: selectedRoleId ? [selectedRoleId] : [],
                onChange: (keys) => setSelectedRoleId(keys[0] as number)
              }}
              pagination={{ pageSize: 8 }}
              columns={[
                { title: "ID", dataIndex: "roleId", width: 80 },
                { title: "角色编码", dataIndex: "roleCode" },
                { title: "角色名称", dataIndex: "roleName" },
                {
                  title: "状态",
                  dataIndex: "status",
                  width: 90,
                  render: (v) => (v === 1 ? <Tag color="green">启用</Tag> : <Tag color="red">禁用</Tag>)
                }
              ]}
            />
          </Card>
        </Col>
        <Col xs={24} lg={14}>
          <Card
            title="配置权限"
            bordered={false}
            className="surface-card"
            extra={
              <Text type="secondary">
                {selectedRole ? `当前角色：${selectedRole.roleName}` : "未选择角色"}
              </Text>
            }
          >
            <Tree
              checkable
              selectable={false}
              treeData={treeData}
              checkedKeys={checkedPermIds}
              onCheck={(keys) => setCheckedPermIds(keys as number[])}
              defaultExpandAll
            />
            {!permissions.length && !loadingPerms && (
              <div style={{ marginTop: 12 }}>
                <Text type="secondary">暂无权限数据</Text>
              </div>
            )}
          </Card>
        </Col>
      </Row>
    </div>
  );
}
