import {
  Button,
  Card,
  Drawer,
  Form,
  Input,
  message,
  Popconfirm,
  Space,
  Table,
  Tag,
  Typography,
  Tree,
  Row,
  Col,
  Tabs,
  Empty
} from "antd";
import type { DataNode } from "antd/es/tree";
import { useEffect, useMemo, useState } from "react";
import {
  createRole,
  listPermissions,
  listRolePermissions,
  listRoles,
  saveRolePermissions,
  updateRole,
  deleteRole,
  fetchUsersByRoleId
} from "../api";
import type { SysPermission, SysRole, SysUser } from "../types";
import { usePermission } from "../hooks/usePermission";
import {
  EditOutlined,
  PlusOutlined,
  SafetyCertificateOutlined,
  SearchOutlined,
  DeleteOutlined,
  KeyOutlined,
  UserOutlined,
  SaveOutlined
} 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[] => {
  if (!list || list.length === 0) return [];
  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 && 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((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" style={{ marginLeft: 8 }}>按钮</Tag>}
      </span>
    ),
    children: node.children && node.children.length > 0 ? 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 [selectedRole, setSelectedRole] = useState<SysRole | null>(null);
  
  // Right side states
  const [selectedPermIds, setSelectedPermIds] = useState<number[]>([]);
  const [halfCheckedIds, setHalfCheckedIds] = useState<number[]>([]);
  const [roleUsers, setRoleUsers] = useState<SysUser[]>([]);
  const [loadingUsers, setLoadingUsers] = useState(false);

  // Search
  const [searchText, setSearchText] = useState("");

  // Drawer (Only for Add/Edit basic info)
  const [drawerOpen, setDrawerOpen] = useState(false);
  const [editing, setEditing] = useState<SysRole | null>(null);
  const [form] = Form.useForm();
  
  const { can } = usePermission();

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

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

  const loadRoles = async () => {
    setLoading(true);
    try {
      const list = await listRoles();
      const roles = list || [];
      setData(roles);
      if (roles.length > 0 && !selectedRole) {
        selectRole(roles[0]);
      } else if (selectedRole) {
          const updated = roles.find(r => r.roleId === selectedRole.roleId);
          if (updated) setSelectedRole(updated);
      }
      await loadPermissions();
    } finally {
      setLoading(false);
    }
  };

  const selectRole = async (role: SysRole) => {
    setSelectedRole(role);
    try {
      // Load permissions for this role
      const ids = await listRolePermissions(role.roleId);
      const normalized = (ids || []).map((id) => Number(id)).filter((id) => !Number.isNaN(id));
      
      // Filter out parents for Tree回显
      const leafIds = normalized.filter(id => {
        return !permissions.some(p => p.parentId === id);
      });
      setSelectedPermIds(leafIds);
      setHalfCheckedIds([]);

      // Load users for this role
      setLoadingUsers(true);
      const users = await fetchUsersByRoleId(role.roleId);
      setRoleUsers(users || []);
    } catch (e) {
      message.error("加载角色详情失败");
    } finally {
      setLoadingUsers(false);
    }
  };

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

  // Reload role detail if permissions list loaded later
  useEffect(() => {
    if (selectedRole && permissions.length > 0) {
        // We don't want to infinite loop, but we need to ensure leafIds are correct
        // after permissions are loaded.
        const leafIds = selectedPermIds.filter(id => {
            return !permissions.some(p => p.parentId === id);
        });
        if (leafIds.length !== selectedPermIds.length) {
            setSelectedPermIds(leafIds);
        }
    }
  }, [permissions]);

  const filteredData = useMemo(() => {
    if (!searchText) return data;
    const lower = searchText.toLowerCase();
    return data.filter(r => 
      r.roleName.toLowerCase().includes(lower) || 
      r.roleCode.toLowerCase().includes(lower)
    );
  }, [data, searchText]);

  const openCreate = () => {
    setEditing(null);
    form.resetFields();
    form.setFieldsValue({ status: 1 });
    setDrawerOpen(true);
  };

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

  const handleRemove = async (e: React.MouseEvent, id: number) => {
    e.stopPropagation();
    try {
      await deleteRole(id);
      message.success("角色已删除");
      if (selectedRole?.roleId === id) setSelectedRole(null);
      loadRoles();
    } catch (e) {
      message.error("删除失败");
    }
  };

  const submitBasic = async () => {
    try {
      const values = await form.validateFields();
      setSaving(true);
      const payload: Partial<SysRole> = {
        roleCode: editing?.roleCode || values.roleCode || generateRoleCode(),
        roleName: values.roleName,
        remark: values.remark,
        status: values.status ?? DEFAULT_STATUS
      };
      
      if (editing) {
        await updateRole(editing.roleId, payload);
        message.success("角色已更新");
      } else {
        await createRole(payload);
        message.success("角色已创建");
      }
      
      setDrawerOpen(false);
      loadRoles();
    } catch (e) {
      if (e instanceof Error && e.message) message.error(e.message);
    } finally {
      setSaving(false);
    }
  };

  const savePermissions = async () => {
    if (!selectedRole) return;
    setSaving(true);
    try {
      const allPermIds = Array.from(new Set([...selectedPermIds, ...halfCheckedIds]));
      await saveRolePermissions(selectedRole.roleId, allPermIds);
      message.success("权限已保存并生效");
    } catch (e) {
      message.error("保存权限失败");
    } finally {
      setSaving(false);
    }
  };

  return (
    <div className="roles-page-v2">
      <Row gutter={24} style={{ height: 'calc(100vh - 120px)' }}>
        {/* Left: Role List */}
        <Col span={8} style={{ height: '100%' }}>
          <Card 
            title="系统角色" 
            className="full-height-card"
            extra={can("sys_role:create") && <Button type="primary" size="small" icon={<PlusOutlined />} onClick={openCreate}>新增</Button>}
          >
            <div className="mb-4">
              <Input
                placeholder="搜索角色..."
                prefix={<SearchOutlined />}
                value={searchText}
                onChange={e => setSearchText(e.target.value)}
                allowClear
              />
            </div>
            <div className="role-list-container">
              <Table
                rowKey="roleId"
                showHeader={false}
                dataSource={filteredData}
                loading={loading}
                pagination={false}
                onRow={(record) => ({
                  onClick: () => selectRole(record),
                  className: `cursor-pointer role-row ${selectedRole?.roleId === record.roleId ? 'role-row-selected' : ''}`
                })}
                columns={[
                  {
                    title: '角色',
                    render: (_, record) => (
                      <div className="role-item-content">
                        <div className="role-item-main">
                          <div className="role-item-name">{record.roleName}</div>
                          <div className="role-item-code">{record.roleCode}</div>
                        </div>
                        <div className="role-item-actions">
                          {can("sys_role:update") && <Button type="text" size="small" icon={<EditOutlined />} onClick={e => openEditBasic(e, record)} />}
                          {can("sys_role:delete") && record.roleCode !== 'ADMIN' && (
                            <Popconfirm title="删除角色？" onConfirm={e => handleRemove(e!, record.roleId)}>
                              <Button type="text" size="small" danger icon={<DeleteOutlined />} onClick={e => e.stopPropagation()} />
                            </Popconfirm>
                          )}
                        </div>
                      </div>
                    )
                  }
                ]}
              />
            </div>
          </Card>
        </Col>

        {/* Right: Detail Tabs */}
        <Col span={16} style={{ height: '100%' }}>
          {selectedRole ? (
            <Card 
              className="full-height-card"
              title={
                <Space>
                  <SafetyCertificateOutlined style={{ color: '#1890ff' }} />
                  <span>{selectedRole.roleName}</span>
                  <Tag color="blue">{selectedRole.roleCode}</Tag>
                </Space>
              }
              extra={
                <Button 
                  type="primary" 
                  icon={<SaveOutlined />} 
                  loading={saving} 
                  onClick={savePermissions}
                  disabled={!can("sys_role:permission:save")}
                >
                  保存权限配置
                </Button>
              }
            >
              <Tabs defaultActiveKey="permissions" className="role-tabs">
                <Tabs.TabPane 
                  tab={<Space><KeyOutlined />功能权限</Space>} 
                  key="permissions"
                >
                  <div className="role-permission-tree-v2">
                    <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(k => Number(k)));
                        setHalfCheckedIds(halfChecked.map(k => Number(k)));
                      }}
                      defaultExpandAll
                    />
                  </div>
                </Tabs.TabPane>
                <Tabs.TabPane 
                  tab={<Space><UserOutlined />关联用户 ({roleUsers.length})</Space>} 
                  key="users"
                >
                  <Table
                    rowKey="userId"
                    size="small"
                    loading={loadingUsers}
                    dataSource={roleUsers}
                    pagination={{ pageSize: 10 }}
                    columns={[
                      { 
                        title: '用户', 
                        render: (_, r) => (
                          <Space>
                            <UserOutlined />
                            <div>
                                <div style={{ fontWeight: 500 }}>{r.displayName}</div>
                                <div style={{ fontSize: 12, color: '#8c8c8c' }}>@{r.username}</div>
                            </div>
                          </Space>
                        )
                      },
                      { title: '手机号', dataIndex: 'phone' },
                      { title: '邮箱', dataIndex: 'email' },
                      { 
                        title: '状态', 
                        dataIndex: 'status',
                        render: s => <Tag color={s === 1 ? 'green' : 'red'}>{s === 1 ? '正常' : '禁用'}</Tag>
                      }
                    ]}
                  />
                </Tabs.TabPane>
              </Tabs>
            </Card>
          ) : (
            <Card className="full-height-card flex-center">
              <Empty description="请从左侧选择一个角色以查看详情" />
            </Card>
          )}
        </Col>
      </Row>

      {/* Basic Info Drawer */}
      <Drawer
        title={editing ? "修改角色基础信息" : "新增系统角色"}
        open={drawerOpen}
        onClose={() => setDrawerOpen(false)}
        width={400}
        destroyOnClose
        footer={
          <div className="flex justify-end gap-2">
            <Button onClick={() => setDrawerOpen(false)}>取消</Button>
            <Button type="primary" loading={saving} onClick={submitBasic}>提交</Button>
          </div>
        }
      >
        <Form form={form} layout="vertical">
          <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={[{label: '启用', value: 1}, {label: '禁用', value: 0}]} />
          </Form.Item>
          <Form.Item label="备注" name="remark">
            <Input.TextArea rows={3} />
          </Form.Item>
        </Form>
      </Drawer>
    </div>
  );
}

import { Select } from "antd";
