import { createContext, useContext, useState, useCallback, useMemo, useRef, useEffect, type ReactNode } from 'react'
import { toast } from 'sonner'
import { jobApi } from '@/lib/api'
import type { Job, JobStatus } from '@/types/job'
import { POLL_INTERVAL } from '@/lib/constants'
import { useHistoryContext } from '@/contexts/HistoryContext'

interface JobContextType {
  currentJob: Job | null
  status: JobStatus | null
  error: string | null
  elapsedTime: number
  startJob: (jobId: number) => void
  stopJob: () => void
  resetJob: () => void
  loadCompletedJob: (job: Job) => void
}

const JobContext = createContext<JobContextType | undefined>(undefined)

export function JobProvider({ children }: { children: ReactNode }) {
  const [currentJob, setCurrentJob] = useState<Job | null>(null)
  const [status, setStatus] = useState<JobStatus | null>(null)
  const [error, setError] = useState<string | null>(null)
  const [elapsedTime, setElapsedTime] = useState(0)

  const { refresh: historyRefresh } = useHistoryContext()
  const pollIntervalRef = useRef<ReturnType<typeof setInterval> | null>(null)
  const timeIntervalRef = useRef<ReturnType<typeof setInterval> | null>(null)

  const clearIntervals = useCallback(() => {
    if (pollIntervalRef.current) {
      clearInterval(pollIntervalRef.current)
      pollIntervalRef.current = null
    }
    if (timeIntervalRef.current) {
      clearInterval(timeIntervalRef.current)
      timeIntervalRef.current = null
    }
  }, [])

  const stopJob = useCallback(() => {
    clearIntervals()
    setCurrentJob(null)
    setStatus(null)
    setError(null)
    setElapsedTime(0)
  }, [clearIntervals])

  const resetJob = useCallback(() => {
    setError(null)
  }, [])

  const loadCompletedJob = useCallback((job: Job) => {
    setCurrentJob(job)
    setStatus(job.status)
    setError(job.error_message || null)
    setElapsedTime(0)
  }, [])

  const startJob = useCallback((jobId: number) => {
    clearIntervals()
    // Reset state for new job
    setCurrentJob(null)
    setStatus('pending')
    setError(null)
    setElapsedTime(0)

    const poll = async () => {
      try {
        const job = await jobApi.getJob(jobId)
        setCurrentJob(job)
        setStatus(job.status)

        if (job.status === 'completed') {
          clearIntervals()
          toast.success('任务完成！')
          try {
            historyRefresh()
          } catch {}
        } else if (job.status === 'failed') {
          clearIntervals()
          setError(job.error_message || '任务失败')
          toast.error(job.error_message || '任务失败')
          try {
            historyRefresh()
          } catch {}
        }
      } catch (error: any) {
        clearIntervals()
        const message = error.response?.data?.detail || '获取任务状态失败'
        setError(message)
        toast.error(message)
      }
    }

    poll()
    pollIntervalRef.current = setInterval(poll, POLL_INTERVAL)
    timeIntervalRef.current = setInterval(() => {
      setElapsedTime((prev) => prev + 1)
    }, 1000)
  }, [historyRefresh, clearIntervals])

  useEffect(() => {
    return () => {
      clearIntervals()
    }
  }, [clearIntervals])

  const value = useMemo(
    () => ({
      currentJob,
      status,
      error,
      elapsedTime,
      startJob,
      stopJob,
      resetJob,
      loadCompletedJob,
    }),
    [currentJob, status, error, elapsedTime, startJob, stopJob, resetJob, loadCompletedJob]
  )

  return (
    <JobContext.Provider value={value}>
      {children}
    </JobContext.Provider>
  )
}

export function useJob() {
  const context = useContext(JobContext)
  if (!context) {
    throw new Error('useJob must be used within JobProvider')
  }
  return context
}
