import {
  Button,
  Card,
  Drawer,
  Form,
  Input,
  message,
  Popconfirm,
  Space,
  Table,
  Tag,
  Typography,
  Tree,
  Row,
  Col,
  Tabs,
  Empty,
  Select,
  Modal
} from "antd";
import type { DataNode } from "antd/es/tree";
import { useEffect, useMemo, useState } from "react";
import { useTranslation } from "react-i18next";
import {
  createRole,
  listPermissions,
  listRolePermissions,
  listRoles,
  saveRolePermissions,
  updateRole,
  deleteRole,
  fetchUsersByRoleId,
  bindUsersToRole,
  unbindUserFromRole,
  listUsers
} from "../api";
import type { SysPermission, SysRole, SysUser } from "../types";
import { usePermission } from "../hooks/usePermission";
import {
  EditOutlined,
  PlusOutlined,
  SafetyCertificateOutlined,
  SearchOutlined,
  DeleteOutlined,
  KeyOutlined,
  UserOutlined,
  SaveOutlined,
  UserAddOutlined
} 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[], t: any): 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 }}>{t('permissions.permType') === '按钮' ? '按钮' : 'Button'}</Tag>}
      </span>
    ),
    children: node.children && node.children.length > 0 ? toTreeData(node.children, t) : undefined
  }));

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

export default function Roles() {
  const { t } = useTranslation();
  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);
  
  // Platform admin check
  const isPlatformMode = useMemo(() => {
    const profileStr = sessionStorage.getItem("userProfile");
    if (profileStr) {
      const profile = JSON.parse(profileStr);
      return profile.isPlatformAdmin && localStorage.getItem("activeTenantId") === "0";
    }
    return false;
  }, []);

  const activeTenantId = useMemo(() => Number(localStorage.getItem("activeTenantId") || 0), []);

  // Right side states
  const [selectedPermIds, setSelectedPermIds] = useState<number[]>([]);
  const [halfCheckedIds, setHalfCheckedIds] = useState<number[]>([]);
  const [roleUsers, setRoleUsers] = useState<SysUser[]>([]);
  const [loadingUsers, setLoadingUsers] = useState(false);

  // User selection states
  const [allUsers, setAllUsers] = useState<SysUser[]>([]);
  const [userModalOpen, setUserModalOpen] = useState(false);
  const [selectedUserKeys, setSelectedUserKeys] = useState<number[]>([]);
  const [userSearchText, setUserSearchText] = useState("");

  // Search
  const [searchText, setSearchText] = useState("");
  const [filterTenantId, setFilterTenantId] = useState<number | undefined>(undefined);

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

  const loadTenants = async () => {
    if (!isPlatformMode) return;
    try {
      const resp = await (await import("../api")).listTenants({ current: 1, size: 100 });
      setTenants(resp.records || []);
    } catch (e) {}
  };

  useEffect(() => {
    loadTenants();
  }, [isPlatformMode]);

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

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

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

  const handleAddUsers = async () => {
    if (!selectedRole || selectedUserKeys.length === 0) return;
    try {
      await bindUsersToRole(selectedRole.roleId, selectedUserKeys);
      message.success(t('common.success'));
      setUserModalOpen(false);
      selectRole(selectedRole);
    } catch (e) {
      message.error(t('common.error'));
    }
  };

  const handleUnbindUser = async (userId: number) => {
    if (!selectedRole) return;
    try {
      await unbindUserFromRole(selectedRole.roleId, userId);
      message.success(t('common.success'));
      selectRole(selectedRole);
    } catch (e) {
      message.error(t('common.error'));
    }
  };

  const filteredModalUsers = useMemo(() => {
    const existingIds = new Set(roleUsers.map(u => u.userId));
    return allUsers.filter(u => 
      !existingIds.has(u.userId) && 
      (u.username.toLowerCase().includes(userSearchText.toLowerCase()) || 
       u.displayName.toLowerCase().includes(userSearchText.toLowerCase()))
    );
  }, [allUsers, roleUsers, userSearchText]);

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

  const loadRoles = async () => {
    setLoading(true);
    try {
      const list = await listRoles();
      let roles = list || [];
      
      if (isPlatformMode && filterTenantId !== undefined) {
          roles = roles.filter(r => r.tenantId === filterTenantId);
      } else if (!isPlatformMode) {
          roles = roles.filter(r => r.tenantId === activeTenantId);
      }

      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(t('common.error'));
    } finally {
      setLoadingUsers(false);
    }
  };

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

  // Reload role detail if permissions list loaded later
  useEffect(() => {
    if (selectedRole && permissions.length > 0) {
        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,
      tenantId: isPlatformMode ? undefined : activeTenantId
    });
    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(t('common.success'));
      if (selectedRole?.roleId === id) setSelectedRole(null);
      loadRoles();
    } catch (e) {
      message.error(t('common.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,
        tenantId: values.tenantId
      };
      
      if (editing) {
        await updateRole(editing.roleId, payload);
        message.success(t('common.success'));
      } else {
        await createRole(payload);
        message.success(t('common.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(t('common.success'));
    } catch (e) {
      message.error(t('common.error'));
    } finally {
      setSaving(false);
    }
  };

  return (
    <div className="roles-page-v2 p-6">
      <Row gutter={24} style={{ height: 'calc(100vh - 180px)' }}>
        {/* Left: Role List */}
        <Col span={8} style={{ height: '100%' }}>
          <Card 
            title={t('roles.title')} 
            className="full-height-card shadow-sm"
            extra={can("sys_role:create") && (
              <Button 
                type="primary" 
                size="small" 
                icon={<PlusOutlined aria-hidden="true" />} 
                onClick={openCreate}
              >
                {t('common.create')}
              </Button>
            )}
          >
            <div className="mb-4 flex gap-2">
              {isPlatformMode && (
                <Select
                  placeholder={t('users.tenantFilter')}
                  style={{ width: 150 }}
                  allowClear
                  value={filterTenantId}
                  onChange={setFilterTenantId}
                  options={tenants.map(t => ({ label: t.tenantName, value: t.id }))}
                />
              )}
              <Input
                placeholder={t('roles.searchPlaceholder')}
                prefix={<SearchOutlined aria-hidden="true" />}
                value={searchText}
                onChange={e => setSearchText(e.target.value)}
                allowClear
                aria-label={t('roles.searchPlaceholder')}
              />
            </div>
            <div className="role-list-container" style={{ height: 'calc(100% - 60px)', overflowY: 'auto' }}>
              <Table
                rowKey="roleId"
                showHeader={false}
                dataSource={filteredData}
                loading={loading}
                pagination={false}
                locale={{ emptyText: <Empty description={t('roles.selectRole')} /> }}
                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 flex justify-between items-center p-2">
                        <div className="role-item-main min-w-0">
                          <div className="role-item-name font-medium truncate">{record.roleName}</div>
                          <div className="role-item-code text-xs text-gray-400 truncate">{record.roleCode}</div>
                        </div>
                        <div className="role-item-actions flex gap-1">
                          {can("sys_role:update") && (
                            <Button 
                              type="text" 
                              size="small" 
                              icon={<EditOutlined aria-hidden="true" />} 
                              onClick={e => openEditBasic(e, record)} 
                            />
                          )}
                          {can("sys_role:delete") && record.roleCode !== 'ADMIN' && (
                            <Popconfirm 
                              title={`确定删除角色 "${record.roleName}" 吗？`}
                              onConfirm={e => handleRemove(e!, record.roleId)}
                            >
                              <Button 
                                type="text" 
                                size="small" 
                                danger 
                                icon={<DeleteOutlined aria-hidden="true" />} 
                                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 shadow-sm"
              title={
                <Space>
                  <SafetyCertificateOutlined style={{ color: '#1890ff' }} aria-hidden="true" />
                  <span className="truncate max-w-[200px] inline-block align-bottom">{selectedRole.roleName}</span>
                  <Tag color="blue">{selectedRole.roleCode}</Tag>
                </Space>
              }
              extra={
                <Button 
                  type="primary" 
                  icon={<SaveOutlined aria-hidden="true" />} 
                  loading={saving} 
                  onClick={savePermissions}
                  disabled={!can("sys_role:permission:save")}
                >
                  {t('roles.savePerms')}
                </Button>
              }
            >
              <Tabs defaultActiveKey="permissions" className="role-tabs">
                <Tabs.TabPane 
                  tab={<Space><KeyOutlined aria-hidden="true" />{t('roles.funcPerms')}</Space>} 
                  key="permissions"
                >
                  <div className="role-permission-tree-v2" style={{ maxHeight: 'calc(100vh - 400px)', overflowY: 'auto' }}>
                    <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 aria-hidden="true" />{t('roles.assignedUsers')} ({roleUsers.length})</Space>} 
                  key="users"
                >
                  <div className="mb-4 flex justify-end">
                    <Button 
                      type="primary" 
                      icon={<UserAddOutlined aria-hidden="true" />} 
                      onClick={openUserModal}
                      disabled={!can("sys_role:update")}
                    >
                      {t('common.create')}
                    </Button>
                  </div>
                  <Table
                    rowKey="userId"
                    size="small"
                    loading={loadingUsers}
                    dataSource={roleUsers}
                    pagination={{ pageSize: 10, showTotal: (total) => t('common.total', { total }) }}
                    columns={[
                      { 
                        title: t('users.userInfo'), 
                        render: (_, r) => (
                          <Space>
                            <UserOutlined aria-hidden="true" />
                            <div className="min-w-0">
                                <div style={{ fontWeight: 500 }} className="truncate">{r.displayName}</div>
                                <div style={{ fontSize: 12, color: '#8c8c8c' }} className="truncate">@{r.username}</div>
                            </div>
                          </Space>
                        )
                      },
                      { title: t('users.phone'), dataIndex: 'phone', className: 'tabular-nums' },
                      { title: t('users.email'), dataIndex: 'email' },
                      { 
                        title: t('common.status'), 
                        dataIndex: 'status',
                        width: 80,
                        render: s => <Tag color={s === 1 ? 'green' : 'red'}>{s === 1 ? '正常' : '禁用'}</Tag>
                      },
                      {
                        title: t('common.action'),
                        key: 'action',
                        width: 100,
                        render: (_, record) => (
                          <Popconfirm
                            title={t('common.delete') + "?"}
                            onConfirm={() => handleUnbindUser(record.userId)}
                            disabled={!can("sys_role:update")}
                          >
                            <Button 
                              type="text" 
                              danger 
                              size="small" 
                              icon={<DeleteOutlined aria-hidden="true" />}
                              disabled={!can("sys_role:update")}
                            />
                          </Popconfirm>
                        )
                      }
                    ]}
                  />
                </Tabs.TabPane>
              </Tabs>
            </Card>
          ) : (
            <Card className="full-height-card flex items-center justify-center shadow-sm">
              <Empty description={t('roles.selectRole')} />
            </Card>
          )}
        </Col>
      </Row>

      {/* User Selection Modal */}
      <Modal
        title={t('roles.assignedUsers')}
        open={userModalOpen}
        onCancel={() => setUserModalOpen(false)}
        onOk={handleAddUsers}
        width={600}
        destroyOnClose
      >
        <div className="mb-4">
          <Input
            placeholder={t('users.searchPlaceholder')}
            prefix={<SearchOutlined aria-hidden="true" />}
            value={userSearchText}
            onChange={e => setUserSearchText(e.target.value)}
            allowClear
          />
        </div>
        <Table
          rowKey="userId"
          size="small"
          dataSource={filteredModalUsers}
          pagination={{ pageSize: 5 }}
          rowSelection={{
            selectedRowKeys: selectedUserKeys,
            onChange: (keys) => setSelectedUserKeys(keys as number[])
          }}
          columns={[
            { title: t('users.displayName'), dataIndex: 'displayName' },
            { title: t('users.username'), dataIndex: 'username' },
            { title: t('users.org'), dataIndex: 'orgId', render: () => '-' } // Simplification
          ]}
        />
      </Modal>

      {/* Basic Info Drawer */}
      <Drawer
        title={editing ? t('roles.drawerTitleEdit') : t('roles.drawerTitleCreate')}
        open={drawerOpen}
        onClose={() => setDrawerOpen(false)}
        width={400}
        destroyOnClose
        footer={
          <div className="flex justify-end gap-2 p-2">
            <Button onClick={() => setDrawerOpen(false)}>{t('common.cancel')}</Button>
            <Button type="primary" loading={saving} onClick={submitBasic}>{t('common.confirm')}</Button>
          </div>
        }
      >
        <Form form={form} layout="vertical">
          <Form.Item 
            label={t('users.tenant')} 
            name="tenantId" 
            rules={[{ required: true }]}
            hidden={!isPlatformMode}
          >
            <Select 
              options={tenants.map(t => ({ label: t.tenantName, value: t.id }))} 
              disabled={!!editing}
            />
          </Form.Item>
          {!isPlatformMode && (
            <Form.Item label={t('users.tenant')}>
              <Input value={tenants.find(t => t.id === activeTenantId)?.tenantName || "当前租户"} disabled />
            </Form.Item>
          )}
          <Form.Item label={t('roles.roleName')} name="roleName" rules={[{ required: true }]}>
            <Input placeholder={t('roles.roleName')} />
          </Form.Item>
          <Form.Item label={t('roles.roleCode')} name="roleCode" rules={[{ required: true }]}>
            <Input placeholder={t('roles.roleCode')} disabled={!!editing} />
          </Form.Item>
          <Form.Item label={t('common.status')} name="status" initialValue={1}>
             <Select options={[{label: '启用', value: 1}, {label: '禁用', value: 0}]} />
          </Form.Item>
          <Form.Item label={t('common.remark')} name="remark">
            <Input.TextArea rows={3} />
          </Form.Item>
        </Form>
      </Drawer>
    </div>
  );
}
