import { DeleteOutlined, EditOutlined } from '@ant-design/icons'
import { Button, Checkbox, DatePicker, Form, Input, InputNumber, Modal, Select, Space, Table, message } from 'antd'
import dayjs from 'dayjs'
import { useEffect, useState } from 'react'
import { examApi } from '../api/client'
import type { Exam, ExamType, ReviewStatus, ScoreInput, Subject } from '../types'
import { EXAM_TYPE_LABELS, REVIEW_STATUS_OPTIONS } from '../types'

interface Props {
  studentId: string
  subjects: Subject[]
  exams: Exam[]
  onRefresh: () => void
}

export default function ScoreForm({ studentId, subjects, exams, onRefresh }: Props) {
  const [modalOpen, setModalOpen] = useState(false)
  const [editing, setEditing] = useState<Exam | null>(null)
  const [form] = Form.useForm()
  const [loading, setLoading] = useState(false)

  useEffect(() => {
    if (modalOpen && editing) {
      form.setFieldsValue({
        exam_type: editing.exam_type,
        exam_date: dayjs(editing.exam_date),
        title: editing.title,
        scores: subjects.map((s) => {
          const found = editing.scores.find((sc) => sc.subject_id === s.id)
          return found
            ? {
                subject_id: s.id,
                total_score: found.total_score,
                obtained_score: found.obtained_score,
                review_statuses: found.review_statuses || [],
              }
            : { subject_id: s.id, total_score: undefined, obtained_score: undefined, review_statuses: [] }
        }),
      })
    } else if (modalOpen) {
      form.setFieldsValue({
        exam_type: 'weekly',
        exam_date: dayjs(),
        scores: subjects.map((s) => ({ subject_id: s.id, review_statuses: [] })),
      })
    }
  }, [modalOpen, editing, subjects, form])

  const openCreate = () => {
    setEditing(null)
    setModalOpen(true)
  }

  const openEdit = (exam: Exam) => {
    setEditing(exam)
    setModalOpen(true)
  }

  const handleSubmit = async () => {
    try {
      const values = await form.validateFields()
      const scores: ScoreInput[] = (values.scores || [])
        .map((s: ScoreInput & { review_statuses?: ReviewStatus[] }, idx: number) => ({
          subject_id: subjects[idx]?.id ?? s.subject_id,
          total_score: s.total_score,
          obtained_score: s.obtained_score,
          review_statuses: s.review_statuses || [],
        }))
        .filter(
          (s: ScoreInput) =>
            s.subject_id != null &&
            s.total_score != null &&
            s.obtained_score != null &&
            s.total_score > 0,
        )
        .map((s: ScoreInput) => ({
          subject_id: s.subject_id,
          total_score: Number(s.total_score),
          obtained_score: Number(s.obtained_score),
          review_statuses: s.review_statuses || [],
        }))

      if (scores.length === 0) {
        message.warning('请至少录入一科成绩')
        return
      }

      setLoading(true)
      const payload = {
        exam_type: values.exam_type as ExamType,
        exam_date: values.exam_date.format('YYYY-MM-DD'),
        title: values.title || undefined,
        scores,
      }

      if (editing) {
        await examApi.update(editing.id, payload)
        message.success('已更新')
      } else {
        await examApi.create(studentId, payload)
        message.success('已添加')
      }
      setModalOpen(false)
      onRefresh()
    } catch {
      /* validation */
    } finally {
      setLoading(false)
    }
  }

  const handleDelete = async (exam: Exam) => {
    Modal.confirm({
      title: '确认删除该考试记录？',
      onOk: async () => {
        await examApi.remove(exam.id)
        message.success('已删除')
        onRefresh()
      },
    })
  }

  const columns = [
    { title: '日期', dataIndex: 'exam_date', key: 'exam_date', width: 110 },
    {
      title: '类型',
      dataIndex: 'exam_type',
      key: 'exam_type',
      width: 80,
      render: (t: ExamType) => EXAM_TYPE_LABELS[t],
    },
    { title: '标题', dataIndex: 'title', key: 'title', ellipsis: true },
    {
      title: '科目数',
      key: 'count',
      width: 80,
      render: (_: unknown, r: Exam) => r.scores.length,
    },
    {
      title: '平均占比',
      key: 'avg',
      width: 100,
      render: (_: unknown, r: Exam) => {
        if (!r.scores.length) return '-'
        const avg = r.scores.reduce((a, s) => a + s.ratio, 0) / r.scores.length
        return `${(avg * 100).toFixed(1)}%`
      },
    },
    {
      title: '操作',
      key: 'action',
      width: 120,
      render: (_: unknown, r: Exam) => (
        <Space>
          <Button type="link" icon={<EditOutlined />} onClick={() => openEdit(r)} />
          <Button type="link" danger icon={<DeleteOutlined />} onClick={() => handleDelete(r)} />
        </Space>
      ),
    },
  ]

  return (
    <div>
      <Button type="primary" onClick={openCreate} style={{ marginBottom: 16 }}>
        录入成绩
      </Button>
      <Table rowKey="id" columns={columns} dataSource={exams} pagination={{ pageSize: 10 }} scroll={{ x: 600 }} />

      <Modal
        title={editing ? '编辑考试' : '录入成绩'}
        open={modalOpen}
        onCancel={() => setModalOpen(false)}
        onOk={handleSubmit}
        confirmLoading={loading}
        width={900}
        destroyOnHidden
      >
        <Form form={form} layout="vertical">
          <Space style={{ width: '100%' }} size="large" wrap>
            <Form.Item name="exam_type" label="考试类型" rules={[{ required: true }]}>
              <Select
                style={{ width: 120 }}
                options={Object.entries(EXAM_TYPE_LABELS).map(([k, v]) => ({ value: k, label: v }))}
              />
            </Form.Item>
            <Form.Item name="exam_date" label="考试日期" rules={[{ required: true }]}>
              <DatePicker />
            </Form.Item>
            <Form.Item name="title" label="备注标题">
              <Input placeholder="可选" style={{ width: 200 }} />
            </Form.Item>
          </Space>

          <Form.List name="scores">
            {(fields) => (
              <Table
                size="small"
                pagination={false}
                dataSource={fields.map((f, i) => ({ ...f, subject: subjects[i] }))}
                rowKey="key"
                scroll={{ x: 720 }}
                columns={[
                  {
                    title: '科目',
                    width: 70,
                    render: (_, row) => (
                      <>
                        <Form.Item name={[row.name, 'subject_id']} hidden initialValue={row.subject?.id}>
                          <InputNumber />
                        </Form.Item>
                        {row.subject?.name}
                      </>
                    ),
                  },
                  {
                    title: '总分',
                    width: 100,
                    render: (_, row) => (
                      <Form.Item name={[row.name, 'total_score']} noStyle>
                        <InputNumber min={0} placeholder="总分" style={{ width: 90 }} />
                      </Form.Item>
                    ),
                  },
                  {
                    title: '得分',
                    width: 100,
                    render: (_, row) => (
                      <Form.Item name={[row.name, 'obtained_score']} noStyle>
                        <InputNumber min={0} placeholder="得分" style={{ width: 90 }} />
                      </Form.Item>
                    ),
                  },
                  {
                    title: '占比',
                    width: 70,
                    render: (_, row) => {
                      const total = form.getFieldValue(['scores', row.name, 'total_score'])
                      const obtained = form.getFieldValue(['scores', row.name, 'obtained_score'])
                      if (total > 0 && obtained != null) {
                        return `${((obtained / total) * 100).toFixed(1)}%`
                      }
                      return '-'
                    },
                  },
                  {
                    title: '考试状态',
                    render: (_, row) => (
                      <Form.Item name={[row.name, 'review_statuses']} noStyle initialValue={[]}>
                        <Checkbox.Group options={REVIEW_STATUS_OPTIONS} />
                      </Form.Item>
                    ),
                  },
                ]}
              />
            )}
          </Form.List>
        </Form>
      </Modal>
    </div>
  )
}
