import React, { useState, useMemo, useCallback } from 'react';
import { App, Button, Table, Modal, Form, Input, Select, Switch, Space, Tag, Popconfirm } from 'antd';
import {
  PlusOutlined,
  EditOutlined,
  KeyOutlined,
  IdcardOutlined,
  InboxOutlined,
} from '@ant-design/icons';
import dayjs from 'dayjs';
import api from '../../api';
import PermissionButton from '../../components/PermissionButton';
import EditableCell from '../../components/EditableCell';
import { message } from '../../ui/app-message';
import { userProfileResponseToFormValues, type UserProfileResponse } from './user-profile-form';
import { usePermission } from '../../hooks/usePermission';
import { useQuery } from '@tanstack/react-query';
import { useApiMutation } from '../../hooks/useApiMutation';
import { useDirtyGuard } from '../../hooks/useDirtyGuard';
import { validateResponse } from '../../utils/validate';
import { rolesSchema, usersSchema } from '../../api/schemas';
import { getErrorMessage } from '../../utils/error';

const USER_FIELDS = {
  username: 'username',
  name: 'name',
  phone: 'phone',
  email: 'email',
  status: 'status',
} as const;

const UsersPage: React.FC = () => {
  const { modal } = App.useApp();
  const { hasPermission } = usePermission();
  const canPurgeUser = hasPermission('user:purge');
  const [modalOpen, setModalOpen] = useState(false);
  const [pwdModalOpen, setPwdModalOpen] = useState(false);
  const [editing, setEditing] = useState<any>(null);
  const [resetTarget, setResetTarget] = useState<any>(null);
  const [profileModalOpen, setProfileModalOpen] = useState(false);
  const [profileUser, setProfileUser] = useState<any>(null);
  const [profileForm] = Form.useForm();
  const [form] = Form.useForm();
  const [pwdForm] = Form.useForm();
  const [saving, setSaving] = useState(false);
  const [showArchived, setShowArchived] = useState(false);

  // 弹窗「未保存内容」保护
  const accountGuard = useDirtyGuard(form);
  const pwdGuard = useDirtyGuard(pwdForm);
  const profileGuard = useDirtyGuard(profileForm);

  const handleOpenProfile = useCallback(
    async (record: any) => {
      setProfileUser(record);
      try {
        const res = await api.get<UserProfileResponse>(`/rbac/users/${record.id}/profile`);
        profileForm.setFieldsValue(userProfileResponseToFormValues(res));
      } catch {
        profileForm.setFieldsValue({});
      }
      profileGuard.snapshot();
      setProfileModalOpen(true);
    },
    [profileForm, profileGuard],
  );

  const handleProfileSubmit = async () => {
    setSaving(true);
    const values = await profileForm.validateFields();
    try {
      await profileMutation.mutateAsync({ id: profileUser.id, values });
      message.success('档案更新成功');
      setProfileModalOpen(false);
    } catch {
      // 错误提示由 useApiMutation 统一处理
    } finally {
      setSaving(false);
    }
  };

  const {
    data: fetchResult = { users: [], roles: [] },
    isLoading,
    isFetching,
  } = useQuery<{ users: any[]; roles: any[] }>({
    queryKey: ['rbac', 'users', showArchived],
    queryFn: async () => {
      try {
        const [users, rolesRes] = await Promise.all([
          api.get(`/rbac/users?isArchived=${showArchived}`) as Promise<any[]>,
          api.get('/rbac/roles') as Promise<any[]>,
        ]);
        return {
          users: validateResponse<any[]>(usersSchema, users),
          roles: validateResponse<any[]>(rolesSchema, rolesRes),
        };
      } catch (e: unknown) {
        message.error(getErrorMessage(e, '加载失败，请稍后重试'));
        return { users: [], roles: [] };
      }
    },
  });
  const data = fetchResult.users;
  const roles = fetchResult.roles;
  const loading = isLoading || isFetching;

  const profileMutation = useApiMutation(
    async ({ id, values }: { id: number; values: any }) =>
      api.put(`/rbac/users/${id}/profile`, values),
    { invalidate: [['rbac', 'users']] },
  );
  const saveMutation = useApiMutation(
    async (values: { username: string; password?: string; name: string; roleIds: number[] }) =>
      editing
        ? api.put(`/rbac/users/${editing.id}`, values)
        : api.post('/rbac/users', values),
    { invalidate: [['rbac', 'users']] },
  );
  const archiveMutation = useApiMutation(
    async ({ id, archive }: { id: number; archive: boolean }) =>
      api.put(`/rbac/users/${id}/${archive ? 'archive' : 'restore'}`),
    { invalidate: [['rbac', 'users']] },
  );
  const purgeMutation = useApiMutation(
    async (id: number) => api.delete(`/rbac/users/${id}/permanent`),
    { invalidate: [['rbac', 'users']] },
  );
  const pwdMutation = useApiMutation(
    async ({ id, password }: { id: number; password: string }) =>
      api.put(`/rbac/users/${id}/password`, { password }),
    { invalidate: [['rbac', 'users']] },
  );
  const saveCellMutation = useApiMutation(
    async ({ record, field, value }: { record: any; field: string; value: unknown }) =>
      api.put(`/rbac/users/${record.id}`, { [field]: value }),
    { invalidate: [['rbac', 'users']] },
  );

  const handleAdd = () => {
    setEditing(null);
    form.resetFields();
    accountGuard.snapshot();
    setModalOpen(true);
  };

  const handleEdit = useCallback(
    (record: any) => {
      setEditing(record);
      form.setFieldsValue({
        username: record.username,
        name: record.name,
        roleIds: record.roles?.map((r: any) => r.id) || [],
      });
      accountGuard.snapshot();
      setModalOpen(true);
    },
    [accountGuard, form],
  );

  const handleSubmit = async () => {
    const values = await form.validateFields();
    setSaving(true);
    try {
      await saveMutation.mutateAsync({
        username: values.username,
        password: values.password,
        name: values.name,
        roleIds: values.roleIds || [],
      });
      message.success(editing ? '更新成功' : '创建成功');
      setModalOpen(false);
    } catch {
      // 错误提示由 useApiMutation 统一处理
    } finally {
      setSaving(false);
    }
  };
  const handleArchive = useCallback(
    async (id: number, archive: boolean) => {
      try {
        await archiveMutation.mutateAsync({ id, archive });
        message.success(archive ? '已归档' : '已恢复');
      } catch {
        // 错误提示由 useApiMutation 统一处理
      }
    },
    [archiveMutation],
  );

  const handlePurge = useCallback(
    (record: any) => {
      modal.confirm({
        title: `永久删除账号「${record.name || record.username}」？`,
        content:
          '删除后不可恢复，关联学生、任教、排课或考勤操作时将无法删除；角色绑定、通知和 AI 会话将被清除，操作日志保留。确定继续？',
        okText: '永久删除',
        okButtonProps: { danger: true },
        cancelText: '取消',
        onOk: async () => {
          try {
            await purgeMutation.mutateAsync(record.id);
            message.success('已永久删除（不可恢复）');
          } catch {
            // 错误提示由 useApiMutation 统一处理
          }
        },
      });
    },
    [modal, purgeMutation],
  );

  const handleResetPwd = useCallback(
    (record: any) => {
      setResetTarget(record);
      pwdForm.resetFields();
      pwdGuard.snapshot();
      setPwdModalOpen(true);
    },
    [pwdForm, pwdGuard],
  );

  const handlePwdSubmit = async () => {
    const values = await pwdForm.validateFields();
    setSaving(true);
    try {
      await pwdMutation.mutateAsync({ id: resetTarget.id, password: values.password });
      message.success('密码已重置');
      setPwdModalOpen(false);
    } catch {
      // 错误提示由 useApiMutation 统一处理
    } finally {
      setSaving(false);
    }
  };

  const saveCell = useCallback(
    async (record: any, field: string, value: unknown) => {
      try {
        await saveCellMutation.mutateAsync({ record, field, value });
        message.success('已保存');
      } catch {
        // 错误提示由 useApiMutation 统一处理
      }
    },
    [saveCellMutation],
  );

  const columns = useMemo(
    () => [
      { title: 'ID', dataIndex: 'id', width: 60 },
      {
        title: '用户名',
        dataIndex: USER_FIELDS.username,
        width: 120,
        render: (v: string, r: any) => (
          <EditableCell
            value={v}
            required
            permission="user:edit"
            disabled={r.isArchived}
            onSave={(next) => saveCell(r, USER_FIELDS.username, next)}
          >
            <span
              title={v}
              style={{
                display: 'block',
                maxWidth: '100%',
                overflow: 'hidden',
                textOverflow: 'ellipsis',
                whiteSpace: 'nowrap',
              }}
            >
              {v}
            </span>
          </EditableCell>
        ),
      },
      {
        title: '姓名',
        dataIndex: USER_FIELDS.name,
        width: 120,
        render: (v: string, r: any) => (
          <EditableCell
            value={v}
            required
            permission="user:edit"
            disabled={r.isArchived}
            onSave={(next) => saveCell(r, USER_FIELDS.name, next)}
          >
            {v}
          </EditableCell>
        ),
      },
      {
        title: '角色',
        dataIndex: 'roles',
        width: 200,
        render: (v: any[], record: any) => (
          <EditableCell
            value={v?.map((item) => item.id) || []}
            editor="multi-select"
            options={roles.map((item) => ({ value: item.id, label: item.name }))}
            permission="user:edit"
            disabled={record.isArchived}
            onSave={(next) => saveCell(record, 'roleIds', next)}
          >
            {v && v.length > 0 ? (
              v.map((r: any) => (
                <Tag key={r.id} color="blue">
                  {r.name}
                </Tag>
              ))
            ) : (
              <Tag color="default">无角色</Tag>
            )}
          </EditableCell>
        ),
      },
      {
        title: '最后登录',
        dataIndex: 'lastLoginAt',
        width: 170,
        render: (v: string) => (v ? dayjs(v).format('YYYY-MM-DD HH:mm:ss') : '-'),
      },
      {
        title: '创建时间',
        dataIndex: 'createdAt',
        width: 170,
        render: (v: string) => dayjs(v).format('YYYY-MM-DD HH:mm:ss'),
      },
      {
        title: '操作',
        width: 240,
        fixed: 'right' as const,
        render: (_: unknown, record: any) => (
          <Space>
            <PermissionButton
              permission="user:edit"
              type="link"
              size="small"
              icon={<IdcardOutlined />}
              onClick={() => handleOpenProfile(record)}
            >
              档案
            </PermissionButton>
            <PermissionButton
              permission="user:edit"
              type="link"
              size="small"
              icon={<EditOutlined />}
              onClick={() => handleEdit(record)}
            >
              编辑
            </PermissionButton>
            <PermissionButton
              permission="user:reset-password"
              type="link"
              size="small"
              icon={<KeyOutlined />}
              onClick={() => handleResetPwd(record)}
            >
              重置密码
            </PermissionButton>
            {record.isArchived ? (
              <>
                <Popconfirm title="确认恢复？" onConfirm={() => handleArchive(record.id, false)}>
                  <PermissionButton permission="user:edit" type="link" size="small">
                    恢复
                  </PermissionButton>
                </Popconfirm>
                {canPurgeUser ? (
                  <Button size="small" danger type="link" onClick={() => handlePurge(record)}>
                    删除
                  </Button>
                ) : null}
              </>
            ) : (
              <Popconfirm
                title="归档后可恢复，确认归档？"
                onConfirm={() => handleArchive(record.id, true)}
              >
                <PermissionButton permission="user:edit" type="link" size="small">
                  归档
                </PermissionButton>
              </Popconfirm>
            )}
          </Space>
        ),
      },
    ],
    [
      roles,
      saveCell,
      canPurgeUser,
      handlePurge,
      handleOpenProfile,
      handleEdit,
      handleArchive,
      handleResetPwd,
    ],
  );

  return (
    <div>
      <div
        style={{
          marginBottom: 16,
          display: 'flex',
          justifyContent: 'space-between',
          alignItems: 'center',
          flexWrap: 'wrap',
          gap: 8,
        }}
      >
        <h2 style={{ margin: 0 }}>账号管理</h2>
        <Space wrap>
          <PermissionButton
            permission="user:create"
            type="primary"
            icon={<PlusOutlined />}
            onClick={handleAdd}
          >
            新增账号
          </PermissionButton>
          <span style={{ marginLeft: 8 }}>
            <InboxOutlined style={{ marginRight: 4 }} />
            归档
            <Switch
              size="small"
              style={{ marginLeft: 4 }}
              checked={showArchived}
              onChange={setShowArchived}
            />
          </span>
        </Space>
      </div>
      <Table
        columns={columns}
        dataSource={data}
        rowKey="id"
        loading={loading}
        scroll={{ x: 1150 }}
        pagination={false}
      />

      <Modal
        title={editing ? '编辑账号' : '新增账号'}
        open={modalOpen}
        onOk={handleSubmit}
        onCancel={() => accountGuard.confirmClose(() => setModalOpen(false))}
        destroyOnHidden
        confirmLoading={saving}
      >
        <Form form={form} layout="vertical">
          <Form.Item
            name="username"
            label="用户名"
            rules={[{ required: true, message: '请输入用户名' }]}
          >
            <Input />
          </Form.Item>
          {!editing && (
            <Form.Item
              name="password"
              label="密码"
              rules={[{ required: true, min: 4, message: '密码至少4位' }]}
            >
              <Input.Password />
            </Form.Item>
          )}
          <Form.Item name="name" label="姓名" rules={[{ required: true, message: '请输入姓名' }]}>
            <Input />
          </Form.Item>
          <Form.Item
            name="roleIds"
            label="角色分配"
            rules={[{ required: !editing, message: '请至少选择一个角色' }]}
          >
            <Select
              mode="multiple"
              placeholder="选择角色"
              options={roles
                .filter((r: any) => r.status !== 0)
                .map((r: any) => ({
                  value: r.id,
                  label: `${r.name}${r.isSystem ? ' (系统)' : ''}`,
                }))}
            />
          </Form.Item>
        </Form>
      </Modal>

      <Modal
        title={`重置密码 - ${resetTarget?.username}`}
        open={pwdModalOpen}
        onOk={handlePwdSubmit}
        onCancel={() => pwdGuard.confirmClose(() => setPwdModalOpen(false))}
        destroyOnHidden
        confirmLoading={saving}
      >
        <Form form={pwdForm} layout="vertical">
          <Form.Item
            name="password"
            label="新密码"
            rules={[{ required: true, min: 4, message: '密码至少4位' }]}
          >
            <Input.Password />
          </Form.Item>
        </Form>
      </Modal>

      <Modal
        title={`教师档案 - ${profileUser?.name || profileUser?.username}`}
        open={profileModalOpen}
        onOk={handleProfileSubmit}
        onCancel={() => profileGuard.confirmClose(() => setProfileModalOpen(false))}
        destroyOnHidden
        confirmLoading={saving}
      >
        <Form form={profileForm} layout="vertical">
          <Form.Item name="joinedAt" label="入职日期">
            <Input placeholder="YYYY-MM-DD" />
          </Form.Item>
          <Form.Item name="qualifications" label="资质">
            <Input.TextArea placeholder="教师资格证号、学历等" rows={2} />
          </Form.Item>
          <Form.Item name="subjects" label="任教学科">
            <Select
              mode="tags"
              placeholder="输入学科后回车添加"
              options={[
                { value: '语文', label: '语文' },
                { value: '数学', label: '数学' },
                { value: '英语', label: '英语' },
                { value: '政治', label: '政治' },
                { value: '历史', label: '历史' },
                { value: '地理', label: '地理' },
                { value: '物理', label: '物理' },
                { value: '化学', label: '化学' },
                { value: '生物', label: '生物' },
              ]}
            />
          </Form.Item>
        </Form>
      </Modal>
    </div>
  );
};

export default UsersPage;
