import { useEffect, useState } from "react";
import { Alert, Button, Card, Form, Input, Table, Typography, Upload, message, Modal, Tag } from "antd";
import { UploadOutlined } from "@ant-design/icons";
import { api } from "../api";

type Batch = {
  id: number;
  subject_name: string;
  exam_id: number;
  exam_ids: number[];
  zip_filename: string;
  imported_at: string;
  status: string;
  attempt_count: number;
  paper_name?: string;
};

export default function AdminImportPage() {
  const [batches, setBatches] = useState<Batch[]>([]);
  const [file, setFile] = useState<File | null>(null);
  const [loading, setLoading] = useState(false);

  const load = () => api.get<{ items: Batch[] }>("/api/admin/import/batches").then((r) => setBatches(r.data.items));

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

  return (
    <div>
      <Card title="导入数据" style={{ marginBottom: 16 }}>
        <Alert
          type="info"
          showIcon
          style={{ marginBottom: 16 }}
          message="导入要求说明"
          description={
            <Typography.Paragraph style={{ marginBottom: 0 }}>
              <ul style={{ margin: "8px 0 0", paddingLeft: 20 }}>
                <li>请上传 <strong>ZIP 压缩包</strong>，内含导出 SQL（仅 <code>.sql</code> 文件，UTF-8 编码）。</li>
                <li>
                  必须包含 5 类数据（文件名需能识别，推荐与样例一致）：
                  <ul>
                    <li>考生：<code>examination_examinee</code>（勿与答案表混淆）</li>
                    <li>考试考生 / 成绩：<code>examination_exam_examinee</code></li>
                    <li>试卷：<code>examination_paper_source</code></li>
                    <li>试题明细：<code>examination_paper_item</code></li>
                    <li>考生答案：<code>examination_examinee_exam_answer</code></li>
                  </ul>
                </li>
                <li>
                  一个 ZIP 可包含<strong>多个 exam_id</strong>（同卷多场次）：ZIP 内须为<strong>同一份试卷</strong>（相同{" "}
                  <code>external_paper_id + revision</code>），系统将共用一套试题判分。
                </li>
                <li>
                  若 ZIP 内含<strong>多份不同试卷</strong>，须额外提供 <code>examination_exam</code> SQL，用{" "}
                  <code>paper_source_id</code> 标明每场考试使用的试卷；否则无法导入。
                </li>
                <li>
                  每个 <code>exam_id</code> 在全库仅能导入一次；已存在的试卷（相同{" "}
                  <code>external_paper_id + revision</code>）会复用题库，仅新增场次与成绩。
                </li>
                <li>
                  <strong>科目名称</strong>由管理员填写，用于成绩列表筛选；清除请用下方「导入历史」按批次操作（会删除该 ZIP 对应的全部场次数据）。
                </li>
                <li>导入后将按试题明细与答案自动判分，并以明细汇总结果更新总分（可与原 SQL 中 score 对照）。</li>
              </ul>
            </Typography.Paragraph>
          }
        />
        <Form
          layout="vertical"
          onFinish={async (v) => {
            if (!file) {
              message.warning("请选择 ZIP 文件");
              return;
            }
            const fd = new FormData();
            fd.append("subject_name", v.subject_name);
            fd.append("file", file);
            setLoading(true);
            try {
              const { data } = await api.post("/api/admin/import", fd);
              message.success("导入成功");
              Modal.info({ title: "导入报告", content: JSON.stringify(data.report, null, 2), width: 600 });
              setFile(null);
              load();
            } catch (e: unknown) {
              const msg = (e as { response?: { data?: { detail?: string } } })?.response?.data?.detail || "导入失败";
              message.error(msg);
            } finally {
              setLoading(false);
            }
          }}
        >
          <Form.Item name="subject_name" label="科目名称" rules={[{ required: true }]}>
            <Input placeholder="导入后用于成绩列表科目筛选" />
          </Form.Item>
          <Form.Item label="ZIP 文件" required>
            <Upload
              beforeUpload={(f) => {
                setFile(f);
                return false;
              }}
              maxCount={1}
              onRemove={() => setFile(null)}
            >
              <Button icon={<UploadOutlined />}>选择文件</Button>
            </Upload>
          </Form.Item>
          <Button type="primary" htmlType="submit" loading={loading}>开始导入</Button>
        </Form>
      </Card>
      <Card title="导入历史">
        <Table
          rowKey="id"
          scroll={{ x: 960 }}
          dataSource={batches}
          columns={[
            { title: "科目", dataIndex: "subject_name" },
            {
              title: "exam_id",
              dataIndex: "exam_ids",
              render: (ids: number[] | undefined, row) => {
                const list = ids?.length ? ids : row.exam_id != null ? [row.exam_id] : [];
                return list.map((id) => <Tag key={id}>{id}</Tag>);
              },
            },
            { title: "试卷", dataIndex: "paper_name", ellipsis: true },
            { title: "文件", dataIndex: "zip_filename", ellipsis: true },
            { title: "导入时间", dataIndex: "imported_at" },
            { title: "考生数", dataIndex: "attempt_count" },
            {
              title: "操作",
              render: (_, row) => {
                const ids = row.exam_ids?.length ? row.exam_ids : row.exam_id != null ? [row.exam_id] : [];
                return (
                  <Button
                    danger
                    type="link"
                    onClick={() => {
                      Modal.confirm({
                        title: "清除本次导入的全部数据？",
                        content: `科目：${row.subject_name}，exam_id：${ids.join("、") || "—"}。将删除该批次下全部场次与成绩，不可恢复。`,
                        onOk: async () => {
                          await api.delete(`/api/admin/import/batches/${row.id}`);
                          message.success("已清除");
                          load();
                        },
                      });
                    }}
                  >
                    清除
                  </Button>
                );
              },
            },
          ]}
        />
      </Card>
    </div>
  );
}
