import { UploadOutlined } from '@ant-design/icons'
import { Button, Input, List, Space, Tag, Typography, Upload, message } from 'antd'
import { useCallback, useEffect, useState } from 'react'
import { compositionApi } from '../api/client'
import type { Composition, CompositionInputMode, Student } from '../types'
import { COMPOSITION_STATUS_LABELS } from '../types'
import { SCHOOL_LEVEL_LABELS } from '../constants/school'
import CompositionDetailModal from './CompositionDetailModal'

interface Props {
  studentId: string
  student: Student
}

export default function CompositionPanel({ studentId, student }: Props) {
  const [topic, setTopic] = useState('')
  const [inputMode, setInputMode] = useState<CompositionInputMode>('manual')
  const [items, setItems] = useState<Composition[]>([])
  const [loading, setLoading] = useState(false)
  const [ocrLoading, setOcrLoading] = useState(false)
  const [creating, setCreating] = useState(false)
  const [selected, setSelected] = useState<Composition | null>(null)
  const [detailOpen, setDetailOpen] = useState(false)
  const [regenerating, setRegenerating] = useState(false)

  const load = useCallback(async () => {
    setLoading(true)
    try {
      const { data } = await compositionApi.list(studentId)
      setItems(data)
      setSelected((prev) => {
        if (!prev) return prev
        return data.find((item) => item.id === prev.id) ?? prev
      })
    } finally {
      setLoading(false)
    }
  }, [studentId])

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

  useEffect(() => {
    const hasProcessing = items.some(
      (item) => item.status === 'pending' || item.status === 'generating',
    )
    if (!hasProcessing) return
    const timer = window.setInterval(load, 4000)
    return () => window.clearInterval(timer)
  }, [items, load])

  const handleOcr = async (file: File) => {
    setOcrLoading(true)
    try {
      const { data } = await compositionApi.ocr(studentId, file)
      setTopic(data.text)
      setInputMode('ocr')
      message.success('题目识别完成')
    } catch {
      message.error('题目识别失败')
    } finally {
      setOcrLoading(false)
    }
    return false
  }

  const handleGenerate = async () => {
    if (!topic.trim()) {
      message.warning('请输入或识别作文题目')
      return
    }
    setCreating(true)
    try {
      const { data } = await compositionApi.create(studentId, {
        topic: topic.trim(),
        input_mode: inputMode,
      })
      message.success('已开始生成，请稍后在历史记录中查看')
      setTopic('')
      setInputMode('manual')
      await load()
      setSelected(data)
      setDetailOpen(true)
    } catch {
      message.error('创建失败')
    } finally {
      setCreating(false)
    }
  }

  const openDetail = (item: Composition) => {
    setSelected(item)
    setDetailOpen(true)
  }

  const handleRegenerate = async (id: string) => {
    setRegenerating(true)
    try {
      const { data } = await compositionApi.regenerate(id)
      message.info('正在重新生成…')
      setSelected(data)
      await load()
    } catch {
      message.error('重新生成失败')
    } finally {
      setRegenerating(false)
    }
  }

  const handleDelete = async (id: string) => {
    await compositionApi.remove(id)
    message.success('已删除')
    setDetailOpen(false)
    setSelected(null)
    load()
  }

  const handleDownload = async (item: Composition) => {
    try {
      const { data } = await compositionApi.download(item.id)
      const url = URL.createObjectURL(data)
      const a = document.createElement('a')
      a.href = url
      a.download = `${item.topic.slice(0, 20).replace(/[\\/:*?"<>|]/g, '_') || 'composition'}.md`
      a.click()
      URL.revokeObjectURL(url)
    } catch {
      message.error('下载失败')
    }
  }

  const stage = SCHOOL_LEVEL_LABELS[student.school_level]
  const gradeText = [stage, student.grade, student.class_name].filter(Boolean).join(' · ')

  return (
    <Space direction="vertical" size="large" style={{ width: '100%' }}>
      <Typography.Paragraph type="secondary" style={{ marginBottom: 0 }}>
        按 {gradeText || stage} 课内要求生成写作方案与范文，严禁超纲。题目可手动输入或拍照 OCR 识别。
      </Typography.Paragraph>

      <div>
        <Typography.Text strong>作文题目</Typography.Text>
        <Input.TextArea
          rows={4}
          value={topic}
          onChange={(e) => {
            setTopic(e.target.value)
            setInputMode('manual')
          }}
          placeholder="输入作文题目，或通过下方上传题目图片 OCR 识别"
          style={{ marginTop: 8 }}
        />
        <Space wrap style={{ marginTop: 12 }}>
          <Upload beforeUpload={handleOcr} showUploadList={false} accept="image/*">
            <Button icon={<UploadOutlined />} loading={ocrLoading}>
              上传题目 OCR
            </Button>
          </Upload>
          <Button type="primary" loading={creating} onClick={handleGenerate}>
            生成写作方案与范文
          </Button>
        </Space>
      </div>

      <div>
        <Typography.Title level={5} style={{ marginTop: 0 }}>
          历史记录
        </Typography.Title>
        <List
          loading={loading}
          dataSource={items}
          locale={{ emptyText: '暂无记录，请在上方输入题目并生成' }}
          renderItem={(item) => (
            <List.Item
              actions={[
                <Button type="link" onClick={() => openDetail(item)}>
                  查看
                </Button>,
              ]}
            >
              <List.Item.Meta
                title={
                  <Space wrap>
                    <Typography.Text ellipsis style={{ maxWidth: 420 }}>
                      {item.topic}
                    </Typography.Text>
                    <Tag color={item.status === 'done' ? 'green' : item.status === 'failed' ? 'red' : 'blue'}>
                      {COMPOSITION_STATUS_LABELS[item.status]}
                    </Tag>
                  </Space>
                }
                description={new Date(item.created_at).toLocaleString()}
              />
            </List.Item>
          )}
        />
      </div>

      <CompositionDetailModal
        item={selected}
        open={detailOpen}
        onClose={() => setDetailOpen(false)}
        onRegenerate={handleRegenerate}
        onDelete={handleDelete}
        onDownload={handleDownload}
        regenerating={regenerating}
      />
    </Space>
  )
}
