import { useEffect, useRef, useState } from 'react'
import { api, type TaskLog } from '@/api'
import { TASK_STATUS } from '@/constants'

/**
 * 拉取日志详情；运行中任务走 SSE `/logs/sse?log_id=`
 */
export function useLogStream(log: TaskLog | null | undefined) {
  const [content, setContent] = useState('')
  const [loading, setLoading] = useState(false)
  const [liveLog, setLiveLog] = useState<TaskLog | null>(null)
  const sourceRef = useRef<EventSource | null>(null)
  const bufferRef = useRef<string[]>([])
  const flushRef = useRef<ReturnType<typeof setInterval> | null>(null)
  const durationRef = useRef<ReturnType<typeof setInterval> | null>(null)

  function cleanup() {
    sourceRef.current?.close()
    sourceRef.current = null
    if (flushRef.current) {
      clearInterval(flushRef.current)
      flushRef.current = null
    }
    if (durationRef.current) {
      clearInterval(durationRef.current)
      durationRef.current = null
    }
    bufferRef.current = []
  }

  useEffect(() => {
    cleanup()
    setContent('')
    setLiveLog(log || null)
    if (!log?.id) return

    let cancelled = false

    async function start() {
      setLoading(true)
      if (log!.status !== TASK_STATUS.RUNNING) {
        try {
          const detail = await api.logs.get(log!.id)
          if (!cancelled) {
            setContent(detail.output || detail.error || '')
            setLiveLog({ ...log!, ...detail, task_name: log!.task_name })
          }
        } catch {
          if (!cancelled) setContent('加载日志失败')
        } finally {
          if (!cancelled) setLoading(false)
        }
        return
      }

      // running: SSE
      setContent('')
      setLoading(false)
      const protocol = window.location.protocol
      const host = window.location.host
      const baseUrl = (window as any).__BASE_URL__ || ''
      const apiVersion = (window as any).__API_VERSION__ || '/api/v1'
      const sseUrl = `${protocol}//${host}${baseUrl}${apiVersion}/logs/sse?log_id=${log!.id}`
      const es = new EventSource(sseUrl, { withCredentials: true } as EventSourceInit)
      sourceRef.current = es

      es.onmessage = (event) => {
        let text = ''
        try {
          const data = JSON.parse(event.data)
          text = data.text || ''
        } catch {
          text = event.data
        }
        bufferRef.current.push(text)
        if (!flushRef.current) {
          flushRef.current = setInterval(() => {
            if (bufferRef.current.length) {
              const chunk = bufferRef.current.join('')
              bufferRef.current = []
              setContent((prev) => prev + chunk)
            }
          }, 150)
        }
      }
      es.onerror = () => {
        cleanup()
        // 结束后再拉一次完整日志
        api.logs
          .get(log!.id)
          .then((detail) => {
            if (!cancelled) {
              setContent(detail.output || detail.error || '')
              setLiveLog((prev) => (prev ? { ...prev, ...detail, status: detail.status } : prev))
            }
          })
          .catch(() => {})
      }

      durationRef.current = setInterval(() => {
        setLiveLog((prev) => {
          if (!prev || prev.status !== TASK_STATUS.RUNNING) return prev
          if (prev.start_time && prev.start_time !== '-') {
            const startMs = new Date(prev.start_time).getTime()
            if (!Number.isNaN(startMs)) {
              return { ...prev, duration: Date.now() - startMs }
            }
          }
          return { ...prev, duration: (prev.duration || 0) + 1000 }
        })
      }, 1000)
    }

    start()
    return () => {
      cancelled = true
      cleanup()
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [log?.id, log?.status])

  return { content, loading, liveLog, setLiveLog }
}
