import { CameraOutlined, PictureOutlined, ReloadOutlined, UploadOutlined } from '@ant-design/icons'
import { Button, Input, Select, Space, Typography, Upload, message } from 'antd'
import { useEffect, useMemo, useRef, useState } from 'react'
import { wrongQuestionApi } from '../api/client'
import type { Subject, WrongQuestionCategory } from '../types'
import ImageCropModal from './ImageCropModal'

interface Props {
  studentId: string
  subjects: Subject[]
  category: WrongQuestionCategory
  onUploaded: () => void
}

export default function WrongQuestionUpload({ studentId, subjects, category, onUploaded }: Props) {
  const isOlympiad = category === 'olympiad'
  const availableSubjects = useMemo(
    () => (isOlympiad ? subjects.filter((s) => s.name === '数学') : subjects),
    [subjects, isOlympiad],
  )
  const [subjectId, setSubjectId] = useState<number | undefined>()
  const [uploading, setUploading] = useState(false)
  const [cropOpen, setCropOpen] = useState(false)
  const [cropSrc, setCropSrc] = useState<string | null>(null)
  const [pendingFile, setPendingFile] = useState<File | null>(null)
  const cameraRef = useRef<HTMLInputElement>(null)

  useEffect(() => {
    if (availableSubjects.length) {
      setSubjectId(availableSubjects[0].id)
    }
  }, [availableSubjects])

  const closeCrop = () => {
    if (cropSrc) URL.revokeObjectURL(cropSrc)
    setCropOpen(false)
    setCropSrc(null)
    setPendingFile(null)
  }

  const openCrop = (file: File) => {
    if (!subjectId) {
      message.warning(isOlympiad ? '未找到数学科目' : '请选择科目')
      return
    }
    setCropSrc(URL.createObjectURL(file))
    setPendingFile(file)
    setCropOpen(true)
  }

  const doUpload = async (file: File) => {
    if (!subjectId) {
      message.warning(isOlympiad ? '未找到数学科目' : '请选择科目')
      return
    }
    setUploading(true)
    try {
      await wrongQuestionApi.upload(studentId, subjectId, file, category)
      message.success('上传成功，正在识别并生成解法…')
      onUploaded()
    } catch {
      message.error('上传失败')
    } finally {
      setUploading(false)
    }
  }

  const handlePickFile = (file: File) => {
    openCrop(file)
    return false
  }

  const handleCamera = (e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0]
    e.target.value = ''
    if (file) openCrop(file)
  }

  const handleCropConfirm = async (file: File) => {
    closeCrop()
    await doUpload(file)
  }

  const handleSkipCrop = async (file: File) => {
    closeCrop()
    await doUpload(file)
  }

  return (
    <Space direction="vertical" size="middle" style={{ width: '100%', marginBottom: 16 }}>
      {isOlympiad ? (
        <Typography.Text>科目：数学（奥数区仅支持数学）</Typography.Text>
      ) : (
        <Select
          style={{ width: '100%', maxWidth: 200 }}
          placeholder="选择科目"
          value={subjectId}
          onChange={setSubjectId}
          options={availableSubjects.map((s) => ({ value: s.id, label: s.name }))}
        />
      )}
      <Space wrap className="upload-actions">
        <span className="upload-mobile-only">
          <Upload beforeUpload={handlePickFile} showUploadList={false} accept="image/*">
            <Button icon={<PictureOutlined />} loading={uploading} type="primary" size="large">
              相册选图
            </Button>
          </Upload>
          <Button
            icon={<CameraOutlined />}
            loading={uploading}
            size="large"
            onClick={() => cameraRef.current?.click()}
          >
            拍照上传
          </Button>
          <input
            ref={cameraRef}
            type="file"
            accept="image/*"
            capture="environment"
            style={{ display: 'none' }}
            onChange={handleCamera}
          />
        </span>
        <span className="upload-desktop-only">
          <Upload beforeUpload={handlePickFile} showUploadList={false} accept="image/*">
            <Button icon={<UploadOutlined />} loading={uploading} type="primary" size="large">
              上传图片
            </Button>
          </Upload>
        </span>
        {!isOlympiad && (
          <span className="upload-mobile-only">
            <Upload beforeUpload={handlePickFile} showUploadList={false} accept="image/*">
              <Button icon={<UploadOutlined />} loading={uploading} size="large">
                上传图片
              </Button>
            </Upload>
          </span>
        )}
      </Space>
      {isOlympiad && (
        <span style={{ color: '#666', fontSize: 13 }}>
          奥数区仅数学，按学生学段（初中/高中）生成解题思路，严禁超纲
        </span>
      )}
      <ImageCropModal
        open={cropOpen}
        imageSrc={cropSrc}
        filename={pendingFile?.name || 'question.jpg'}
        originalFile={pendingFile}
        onCancel={closeCrop}
        onConfirm={handleCropConfirm}
        onSkip={handleSkipCrop}
      />
    </Space>
  )
}

interface SearchProps {
  subjectId?: number
  onSubjectChange?: (id?: number) => void
  search: string
  onSearchChange: (q: string) => void
  onRefresh: () => void
  subjects: Subject[]
  hideSubjectFilter?: boolean
}

export function WrongQuestionFilters({
  subjectId,
  onSubjectChange,
  search,
  onSearchChange,
  onRefresh,
  subjects,
  hideSubjectFilter,
}: SearchProps) {
  return (
    <Space wrap style={{ marginBottom: 16, width: '100%' }}>
      {!hideSubjectFilter && (
        <Select
          allowClear
          style={{ width: '100%', maxWidth: 140 }}
          placeholder="全部科目"
          value={subjectId}
          onChange={onSubjectChange}
          options={subjects.map((s) => ({ value: s.id, label: s.name }))}
        />
      )}
      <Input.Search
        placeholder="搜索题目/解法"
        value={search}
        onChange={(e) => onSearchChange(e.target.value)}
        onSearch={() => onRefresh()}
        style={{ width: '100%', maxWidth: 260 }}
        allowClear
      />
      <Button icon={<ReloadOutlined />} onClick={onRefresh}>
        刷新
      </Button>
    </Space>
  )
}
