import React, { useEffect, useState, useMemo, useCallback } from 'react';
import {
  Table,
  Button,
  Input,
  Select,
  Space,
  Tag,
  Modal,
  Form,
  InputNumber,
  DatePicker,
  Popconfirm,
  Card,
  Switch,
  Empty,
} from 'antd';
import type { ColumnsType } from 'antd/es/table';
import { PlusOutlined, SearchOutlined, TeamOutlined, InboxOutlined } from '@ant-design/icons';
import { useNavigate } from 'react-router-dom';
import dayjs from 'dayjs';
import api from '../../api';
import PermissionButton from '../../components/PermissionButton';
import EditableCell from '../../components/EditableCell';
import { message } from '../../ui/app-message';

// ---- Types ----

interface ClassItem {
  id: number;
  name: string;
  code: string;
  classType: string;
  startDate: string | null;
  endDate: string | null;
  status: string;
  headTeacherId: number | null;
  lifeTeacherId: number | null;
  academicTeacherId: number | null;
  maxStudents: number;
  notes: string | null;
  studentCount: number;
  isArchived: boolean;
  createdAt: string;
  updatedAt: string;
}

interface ClassFormValues {
  name: string;
  code: string;
  classType: string;
  startDate?: dayjs.Dayjs;
  endDate?: dayjs.Dayjs;
  maxStudents?: number;
  status?: string;
  notes?: string;
}

// ---- Constants ----

const STATUS_MAP: Record<string, { color: string; text: string }> = {
  enrolling: { color: 'blue', text: '招生中' },
  active: { color: 'green', text: '在读' },
  ended: { color: 'default', text: '结课' },
  suspended: { color: 'orange', text: '停课' },
};

const TYPE_MAP: Record<string, string> = {
  culture: '文化课',
  professional: '专业课',
  bootcamp: '集训营',
  sprint: '冲刺营',
};

// ---- Component ----

const ClassesPage: React.FC = () => {
  const navigate = useNavigate();
  const [data, setData] = useState<ClassItem[]>([]);
  const [loading, setLoading] = useState(false);
  const [modalOpen, setModalOpen] = useState(false);
  const [editing, setEditing] = useState<ClassItem | null>(null);
  const [searchText, setSearchText] = useState('');
  const [filterStatus, setFilterStatus] = useState<string>();
  const [filterType, setFilterType] = useState<string>();
  const [form] = Form.useForm<ClassFormValues>();
  const [saving, setSaving] = useState(false);
  const [showArchived, setShowArchived] = useState(false);

  const handleArchive = async (id: number, archive: boolean) => {
    try {
      await api.put(`/classes/${id}/${archive ? 'archive' : 'restore'}`);
      message.success(archive ? '已归档' : '已恢复');
      fetchData();
    } catch (e: unknown) {
      const err = e as { message?: string };
      message.error(err?.message || '操作失败');
    }
  };

  const fetchData = useCallback(async () => {
    setLoading(true);
    try {
      const params: Record<string, string | boolean | undefined> = {};
      if (filterStatus) params.status = filterStatus;
      if (filterType) params.classType = filterType;
      params.isArchived = showArchived;
      const res = await api.get<ClassItem[]>('/classes', { params } as Record<string, unknown>);
      setData(res);
    } catch (e: any) {
      message.error(e?.message || '加载失败，请稍后重试');
    } finally {
      setLoading(false);
    }
  }, [filterStatus, filterType, showArchived]);

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

  const filtered = useMemo(() => {
    if (!searchText) return data;
    const q = searchText.toLowerCase();
    return data.filter(
      (c) => c.name?.toLowerCase().includes(q) || c.code?.toLowerCase().includes(q),
    );
  }, [data, searchText]);

  const handleCreate = () => {
    setEditing(null);
    form.resetFields();
    setModalOpen(true);
  };

  const handleEdit = (record: ClassItem) => {
    setEditing(record);
    form.setFieldsValue({
      ...record,
      notes: record.notes ?? undefined,
      startDate: record.startDate ? dayjs(record.startDate) : undefined,
      endDate: record.endDate ? dayjs(record.endDate) : undefined,
    });
    setModalOpen(true);
  };

  const handleSubmit = async () => {
    setSaving(true);
    try {
      const values = await form.validateFields();
      const payload = {
        ...values,
        startDate: values.startDate?.format('YYYY-MM-DD'),
        endDate: values.endDate?.format('YYYY-MM-DD'),
      };
      if (editing) {
        await api.put(`/classes/${editing.id}`, payload);
        message.success('更新成功');
      } else {
        await api.post('/classes', payload);
        message.success('创建成功');
      }
      setModalOpen(false);
      fetchData();
    } catch (e: any) {
      message.error(e?.message || '操作失败');
    } finally {
      setSaving(false);
    }
  };

  const saveCell = useCallback(
    async (record: ClassItem, field: string, value: unknown) => {
      await api.put(`/classes/${record.id}`, { [field]: value });
      message.success('已保存');
      await fetchData();
    },
    [fetchData],
  );

  const columns: ColumnsType<ClassItem> = useMemo(
    () => [
      {
        title: '班级名称',
        dataIndex: 'name',
        width: 120,
        sorter: (a, b) => a.name.localeCompare(b.name),
        render: (v: string, r: ClassItem) => (
          <EditableCell
            value={v}
            required
            permission="class:edit"
            disabled={r.isArchived}
            onSave={(next) => saveCell(r, 'name', next)}
          >
            {v}
          </EditableCell>
        ),
      },
      {
        title: '编码',
        dataIndex: 'code',
        width: 140,
        render: (v: string, r: ClassItem) => (
          <EditableCell
            value={v}
            required
            permission="class:edit"
            disabled={r.isArchived}
            onSave={(next) => saveCell(r, 'code', next)}
          >
            {v}
          </EditableCell>
        ),
      },
      {
        title: '班型',
        dataIndex: 'classType',
        width: 100,
        render: (v: string, r: ClassItem) => (
          <EditableCell
            value={v}
            editor="select"
            options={Object.entries(TYPE_MAP).map(([value, label]) => ({ value, label }))}
            permission="class:edit"
            disabled={r.isArchived}
            onSave={(next) => saveCell(r, 'classType', next)}
          >
            <Tag>{TYPE_MAP[v] || v}</Tag>
          </EditableCell>
        ),
      },
      {
        title: '开班日期',
        dataIndex: 'startDate',
        width: 110,
        render: (v: string | null, r: ClassItem) => (
          <EditableCell
            value={v}
            editor="date"
            permission="class:edit"
            disabled={r.isArchived}
            onSave={(next) => saveCell(r, 'startDate', next)}
          >
            {v || '-'}
          </EditableCell>
        ),
      },
      {
        title: '学员',
        width: 100,
        render: (_: unknown, r: ClassItem) => (
          <EditableCell
            value={r.maxStudents}
            editor="number"
            min={0}
            permission="class:edit"
            disabled={r.isArchived}
            onSave={(next) => saveCell(r, 'maxStudents', next)}
          >{`${r.studentCount || 0}/${r.maxStudents || '-'}`}</EditableCell>
        ),
      },
      {
        title: '状态',
        dataIndex: 'status',
        width: 100,
        render: (v: string, r: ClassItem) => (
          <EditableCell
            value={v}
            editor="select"
            options={Object.entries(STATUS_MAP).map(([value, item]) => ({
              value,
              label: item.text,
            }))}
            permission="class:edit"
            disabled={r.isArchived}
            onSave={(next) => saveCell(r, 'status', next)}
          >
            {(() => {
              const cfg = STATUS_MAP[v] || { color: 'default', text: v };
              return <Tag color={cfg.color}>{cfg.text}</Tag>;
            })()}
          </EditableCell>
        ),
      },
      {
        title: '操作',
        width: 280,
        render: (_: unknown, r: ClassItem) => (
          <Space>
            <Button
              size="small"
              icon={<TeamOutlined />}
              onClick={() => navigate(`/classes/${r.id}`)}
            >
              详情
            </Button>
            <PermissionButton permission="class:edit" size="small" onClick={() => handleEdit(r)}>
              编辑
            </PermissionButton>
            {r.isArchived ? (
              <Popconfirm title="确认恢复？" onConfirm={() => handleArchive(r.id, false)}>
                <PermissionButton permission="class:edit" size="small">
                  恢复
                </PermissionButton>
              </Popconfirm>
            ) : (
              <Popconfirm
                title="归档后可恢复，确认归档？"
                onConfirm={() => handleArchive(r.id, true)}
              >
                <PermissionButton permission="class:edit" size="small">
                  归档
                </PermissionButton>
              </Popconfirm>
            )}
          </Space>
        ),
      },
    ],
    [saveCell],
  );

  return (
    <Card>
      <Space
        style={{ marginBottom: 16 }}
        wrap
        className="responsive-toolbar responsive-toolbar--single"
      >
        <Input
          placeholder="搜索名称/编码"
          prefix={<SearchOutlined />}
          value={searchText}
          onChange={(e) => setSearchText(e.target.value)}
          style={{ width: 200 }}
        />
        <Select
          placeholder="班型"
          allowClear
          style={{ width: 120 }}
          value={filterType}
          onChange={setFilterType}
          options={Object.entries(TYPE_MAP).map(([k, v]) => ({ value: k, label: v }))}
        />
        <Select
          placeholder="状态"
          allowClear
          style={{ width: 120 }}
          value={filterStatus}
          onChange={setFilterStatus}
          options={Object.entries(STATUS_MAP).map(([k, v]) => ({ value: k, label: v.text }))}
        />
        <PermissionButton
          permission="class:create"
          type="primary"
          icon={<PlusOutlined />}
          onClick={handleCreate}
        >
          创建班级
        </PermissionButton>
        <span style={{ marginLeft: 8 }}>
          <InboxOutlined style={{ marginRight: 4 }} />
          归档
          <Switch
            size="small"
            style={{ marginLeft: 4 }}
            checked={showArchived}
            onChange={setShowArchived}
          />
        </span>
      </Space>
      <Table<ClassItem>
        columns={columns}
        dataSource={filtered}
        rowKey="id"
        loading={loading}
        locale={{ emptyText: <Empty description="暂无数据" /> }}
        pagination={{
          defaultPageSize: 20,
          showSizeChanger: true,
          pageSizeOptions: [20, 50, 100],
        }}
        scroll={{ x: 1100 }}
      />

      <Modal
        title={editing ? '编辑班级' : '创建班级'}
        open={modalOpen}
        onOk={handleSubmit}
        onCancel={() => setModalOpen(false)}
        confirmLoading={saving}
        width={600}
      >
        <Form form={form} layout="vertical">
          <Form.Item name="name" label="班级名称" rules={[{ required: true }]}>
            <Input />
          </Form.Item>
          <Form.Item name="code" label="班级编码" rules={[{ required: true }]}>
            <Input />
          </Form.Item>
          <Form.Item name="classType" label="班型" rules={[{ required: true }]}>
            <Select options={Object.entries(TYPE_MAP).map(([k, v]) => ({ value: k, label: v }))} />
          </Form.Item>
          <Space>
            <Form.Item name="startDate" label="开班日期">
              <DatePicker />
            </Form.Item>
            <Form.Item name="endDate" label="结课日期">
              <DatePicker />
            </Form.Item>
            <Form.Item name="maxStudents" label="人数上限">
              <InputNumber min={1} />
            </Form.Item>
          </Space>
          <Form.Item name="status" label="状态" initialValue="enrolling">
            <Select
              options={Object.entries(STATUS_MAP).map(([k, v]) => ({ value: k, label: v.text }))}
            />
          </Form.Item>
          <Form.Item name="notes" label="备注">
            <Input.TextArea rows={3} />
          </Form.Item>
        </Form>
      </Modal>
    </Card>
  );
};

export default ClassesPage;
