import React, { useState, useMemo, useCallback } from 'react';
import { Table, Modal, Form, Input, Space, Tag, Popconfirm, Card, Checkbox } from 'antd';
import { PlusOutlined, EditOutlined, StopOutlined } from '@ant-design/icons';
import api from '../../api';
import PermissionButton from '../../components/PermissionButton';
import EditableCell from '../../components/EditableCell';
import { message } from '../../ui/app-message';
import { useQuery } from '@tanstack/react-query';
import { useApiMutation } from '../../hooks/useApiMutation';
import { validateResponse } from '../../utils/validate';
import { permissionTreeSchema, rolesSchema } from '../../api/schemas';
import { getErrorMessage } from '../../utils/error';
import { useDirtyGuard } from '../../hooks/useDirtyGuard';
import { usePermission } from '../../hooks/usePermission';
import { QueryEmpty } from '../../components/QueryState';

interface PermissionItem {
  id: number;
  code: string;
  name: string;
  group: string;
}

interface RoleItem {
  id: number;
  name: string;
  description: string;
  isSystem: boolean;
  status: number;
  permissions: PermissionItem[];
}

const RolesPage: React.FC = () => {
  const { hasPermission } = usePermission();
  const [modalOpen, setModalOpen] = useState(false);
  const [editing, setEditing] = useState<RoleItem | null>(null);
  const [form] = Form.useForm();
  const roleGuard = useDirtyGuard(form);
  const [selectedPermIds, setSelectedPermIds] = useState<number[]>([]);
  const [saving, setSaving] = useState(false);

  const {
    data: fetchResult = { roles: [], permTree: [] },
    isLoading,
    isFetching,
  } = useQuery<{
    roles: RoleItem[];
    permTree: { group: string; permissions: PermissionItem[] }[];
  }>({
    queryKey: ['rbac', 'roles', 'permission-tree'],
    queryFn: async () => {
      try {
        const [roles, permTree] = await Promise.all([
          api.get('/rbac/roles') as Promise<RoleItem[]>,
          api.get('/rbac/permissions/tree') as Promise<
            { group: string; permissions: PermissionItem[] }[]
          >,
        ]);
        return {
          roles: validateResponse<RoleItem[]>(rolesSchema, roles),
          permTree: validateResponse<{ group: string; permissions: PermissionItem[] }[]>(
            permissionTreeSchema,
            permTree,
          ),
        };
      } catch (e: unknown) {
        message.error(getErrorMessage(e, '加载失败，请稍后重试'));
        return { roles: [], permTree: [] };
      }
    },
  });
  const data = fetchResult.roles;
  const allPerms = fetchResult.permTree;
  const loading = isLoading || isFetching;

  const saveMutation = useApiMutation(
    async (values: { name: string; description?: string; permissionIds: number[] }) =>
      editing
        ? api.put(`/rbac/roles/${editing.id}`, values)
        : api.post('/rbac/roles', values),
    { invalidate: [['rbac', 'roles', 'permission-tree']] },
  );
  const disableMutation = useApiMutation(
    async (id: number) => api.delete(`/rbac/roles/${id}`),
    { invalidate: [['rbac', 'roles', 'permission-tree']] },
  );
  const saveCellMutation = useApiMutation(
    async ({ record, field, value }: { record: RoleItem; field: string; value: unknown }) =>
      api.put(`/rbac/roles/${record.id}`, { [field]: value }),
    { invalidate: [['rbac', 'roles', 'permission-tree']] },
  );

  const handleAdd = () => {
    setEditing(null);
    form.resetFields();
    setSelectedPermIds([]);
    roleGuard.snapshot();
    setModalOpen(true);
  };

  const handleEdit = useCallback(
    (record: RoleItem) => {
      setEditing(record);
      form.setFieldsValue({ name: record.name, description: record.description });
      setSelectedPermIds(record.permissions.map((p) => p.id));
      roleGuard.snapshot();
      setModalOpen(true);
    },
    [form, roleGuard],
  );

  const handleSubmit = async () => {
    const values = await form.validateFields();
    setSaving(true);
    try {
      await saveMutation.mutateAsync({
        name: values.name,
        description: values.description,
        permissionIds: selectedPermIds,
      });
      message.success(editing ? '角色更新成功' : '角色创建成功');
      setModalOpen(false);
    } catch {
      // 错误提示由 useApiMutation 统一处理
    } finally {
      setSaving(false);
    }
  };

  const handleDisable = useCallback(
    async (id: number) => {
      try {
        await disableMutation.mutateAsync(id);
        message.success('角色已停用');
      } catch {
        // 错误提示由 useApiMutation 统一处理
      }
    },
    [disableMutation],
  );

  const groupNames: Record<string, string> = {
    dashboard: '数据面板',
    notification: '通知中心',
    student: '学生管理',
    'student-scope': '学生范围权限',
    teacher: '教师管理',
    'teacher-workspace': '教师工作台',
    room: '宿舍管理',
    occupancy: '入住管理',
    expense: '费用管理',
    bill: '账单管理',
    deposit: '押金管理',
    wallet: '学生余额',
    classroom: '教室管理',
    organization: '机构管理',
    rental: '租赁订单',
    class: '班级管理',
    schedule: '排课管理',
    attendance: '考勤管理',
    'attendance-scope': '考勤范围权限',
    log: '操作日志',
    user: '用户管理',
    role: '角色管理',
    sync: '数据同步',
    integration: '集成配置',
    ai: 'AI 配置',
    'ai-chat': 'AI 助手',
  };

  const permissionOptions = useMemo(
    () =>
      allPerms
        .flatMap((group) => group.permissions)
        .map((item) => ({ value: item.id, label: `${item.group} · ${item.name}` })),
    [allPerms],
  );
  const saveCell = useCallback(
    async (record: RoleItem, field: string, value: unknown) => {
      try {
        await saveCellMutation.mutateAsync({ record, field, value });
        message.success('已保存');
      } catch {
        // 错误提示由 useApiMutation 统一处理
      }
    },
    [saveCellMutation],
  );

  const columns = useMemo(
    () => [
      { title: 'ID', dataIndex: 'id', width: 80 },
      {
        title: '名称',
        dataIndex: 'name',
        width: 120,
        render: (v: string, r: RoleItem) => (
          <EditableCell
            value={v}
            required
            permission="role:edit"
            onSave={(next) => saveCell(r, 'name', next)}
          >
            {v}
          </EditableCell>
        ),
      },
      {
        title: '描述',
        dataIndex: 'description',
        width: 200,
        render: (v: string, r: RoleItem) => (
          <EditableCell
            value={v}
            editor="textarea"
            permission="role:edit"
            onSave={(next) => saveCell(r, 'description', next)}
          >
            {v || '-'}
          </EditableCell>
        ),
      },
      {
        title: '权限标签',
        dataIndex: 'permissions',
        width: 150,
        render: (perms: PermissionItem[], record: RoleItem) => (
          <EditableCell
            value={perms?.map((item) => item.id) || []}
            editor="multi-select"
            options={permissionOptions}
            permission="role:edit"
            onSave={(next) => saveCell(record, 'permissionIds', next)}
          >
            {perms?.length > 0 ? (
              <Tag color="blue">{perms.length} 个权限</Tag>
            ) : (
              <Tag color="default">无权限</Tag>
            )}
          </EditableCell>
        ),
      },
      {
        title: '系统',
        dataIndex: 'isSystem',
        width: 80,
        render: (v: boolean) => (v ? <Tag color="orange">系统</Tag> : null),
      },
      {
        title: '操作',
        width: 180,
        fixed: 'right' as const,
        render: (_: any, record: RoleItem) => (
          <Space>
            <PermissionButton
              permission="role:edit"
              type="link"
              size="small"
              icon={<EditOutlined />}
              onClick={() => handleEdit(record)}
            >
              编辑
            </PermissionButton>
            {!record.isSystem && (
              <Popconfirm title="确认停用该角色？" onConfirm={() => handleDisable(record.id)}>
                <PermissionButton
                  permission="role:delete"
                  type="link"
                  size="small"
                  icon={<StopOutlined />}
                >
                  停用
                </PermissionButton>
              </Popconfirm>
            )}
          </Space>
        ),
      },
    ],
    [permissionOptions, saveCell, handleEdit, handleDisable],
  );

  const handleGroupCheckAll = (group: string, checked: boolean) => {
    const groupPermIds =
      allPerms.find((g) => g.group === group)?.permissions.map((p) => p.id) || [];
    if (checked) {
      setSelectedPermIds((prev) => [...new Set([...prev, ...groupPermIds])]);
    } else {
      setSelectedPermIds((prev) => prev.filter((id) => !groupPermIds.includes(id)));
    }
  };

  const isGroupAllChecked = (group: string) => {
    const groupPermIds =
      allPerms.find((g) => g.group === group)?.permissions.map((p) => p.id) || [];
    return groupPermIds.length > 0 && groupPermIds.every((id) => selectedPermIds.includes(id));
  };

  const isGroupIndeterminate = (group: string) => {
    const groupPermIds =
      allPerms.find((g) => g.group === group)?.permissions.map((p) => p.id) || [];
    const checkedCount = groupPermIds.filter((id) => selectedPermIds.includes(id)).length;
    return checkedCount > 0 && checkedCount < groupPermIds.length;
  };

  return (
    <div>
      <div
        style={{
          marginBottom: 16,
          display: 'flex',
          justifyContent: 'space-between',
          alignItems: 'center',
          flexWrap: 'wrap',
          gap: 8,
        }}
      >
        <h2 style={{ margin: 0 }}>角色管理</h2>
        <PermissionButton
          permission="role:create"
          type="primary"
          icon={<PlusOutlined />}
          onClick={handleAdd}
        >
          新增角色
        </PermissionButton>
      </div>
      <Table
        columns={columns}
        dataSource={data}
        rowKey="id"
        loading={loading}
        locale={{
          emptyText: (
            <QueryEmpty
              description="暂无角色数据"
              action={
                hasPermission('role:create')
                  ? { label: '添加角色', icon: <PlusOutlined />, onClick: handleAdd }
                  : undefined
              }
            />
          ),
        }}
        scroll={{ x: 900 }}
        pagination={false}
      />

      <Modal
        title={editing ? '编辑角色' : '新增角色'}
        open={modalOpen}
        onOk={handleSubmit}
        onCancel={() => roleGuard.confirmClose(() => setModalOpen(false))}
        width={700}
        forceRender
        confirmLoading={saving}
      >
        <Form form={form} layout="vertical">
          <Form.Item
            name="name"
            label="角色名称"
            rules={[{ required: true, message: '请输入角色名称' }]}
          >
            <Input disabled={editing?.isSystem} />
          </Form.Item>
          <Form.Item name="description" label="角色描述">
            <Input.TextArea rows={2} />
          </Form.Item>
          <Form.Item label="权限分配">
            <div style={{ maxHeight: 400, overflow: 'auto' }}>
              {allPerms.map((group) => (
                <Card
                  key={group.group}
                  size="small"
                  title={
                    <Checkbox
                      checked={isGroupAllChecked(group.group)}
                      indeterminate={isGroupIndeterminate(group.group)}
                      onChange={(e) => handleGroupCheckAll(group.group, e.target.checked)}
                    >
                      {groupNames[group.group] || group.group}
                    </Checkbox>
                  }
                  style={{ marginBottom: 8 }}
                >
                  <Checkbox.Group
                    value={selectedPermIds}
                    onChange={(vals) => setSelectedPermIds(vals as number[])}
                  >
                    <Space wrap>
                      {group.permissions.map((p) => (
                        <Checkbox key={p.id} value={p.id}>
                          {p.name}
                        </Checkbox>
                      ))}
                    </Space>
                  </Checkbox.Group>
                </Card>
              ))}
            </div>
          </Form.Item>
        </Form>
      </Modal>
    </div>
  );
};

export default RolesPage;
