import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
import { getLatestBoard, getLatestQueryDetail, getQueryPreview } from '../../api/workbench.js'
import { isLiveRun, singletonMaps } from './model.js'

const BOARD_POLL_MS = 5 * 60 * 1000

export function useQueryBoard() {
  const [preview, setPreview] = useState(null)
  const [board, setBoard] = useState(null)
  const [loading, setLoading] = useState(true)
  const [error, setError] = useState('')
  const [lastUpdatedAt, setLastUpdatedAt] = useState(null)

  const refreshBoard = useCallback(({ signal } = {}) => {
    return getLatestBoard({ signal }).then((payload) => {
      setBoard(payload)
      setLastUpdatedAt(new Date())
      return payload
    })
  }, [])

  useEffect(() => {
    const controller = new AbortController()
    setLoading(true)
    setError('')
    Promise.all([
      getQueryPreview({ signal: controller.signal }),
      getLatestBoard({ signal: controller.signal }).catch(() => null),
    ])
      .then(([previewPayload, boardPayload]) => {
        setPreview(previewPayload)
        setBoard(boardPayload)
        setLastUpdatedAt(new Date())
      })
      .catch((e) => {
        if (e.name !== 'AbortError') setError(e.message || '读取失败')
      })
      .finally(() => setLoading(false))
    return () => controller.abort()
  }, [])

  useEffect(() => {
    if (!isLiveRun(board?.run)) return undefined
    let stopped = false
    let timer = 0
    let controller = null
    const tick = () => {
      controller = new AbortController()
      refreshBoard({ signal: controller.signal })
        .catch(() => {})
        .finally(() => {
          if (!stopped) timer = window.setTimeout(tick, BOARD_POLL_MS)
        })
    }
    timer = window.setTimeout(tick, BOARD_POLL_MS)
    return () => {
      stopped = true
      window.clearTimeout(timer)
      controller?.abort()
    }
  }, [board?.run?.status, refreshBoard])

  const latestByQuery = useMemo(() => singletonMaps(board), [board])

  return {
    preview,
    board,
    latestByQuery,
    loading,
    error,
    lastUpdatedAt,
    refreshBoard,
    isPolling: isLiveRun(board?.run),
  }
}

export function useLatestQueryDetail(selectedQuery) {
  const [detail, setDetail] = useState(null)
  const [loading, setLoading] = useState(false)
  const [error, setError] = useState('')
  const cacheRef = useRef(new Map())

  const load = useCallback(({ signal, background = false } = {}) => {
    if (!selectedQuery?.query_id) return Promise.resolve(null)
    const cacheKey = `${selectedQuery.query_id}:${selectedQuery.detail_version || ''}`
    const cached = cacheRef.current.get(cacheKey)
    if (cached && !background) {
      setDetail(cached)
      setLoading(false)
      setError('')
      return Promise.resolve(cached)
    }
    if (!background) setLoading(true)
    setError('')
    return getLatestQueryDetail(selectedQuery.query_id, { signal })
      .then((payload) => {
        cacheRef.current.set(cacheKey, payload)
        setDetail(payload)
        return payload
      })
      .catch((e) => {
        if (e.name !== 'AbortError') setError(e.message || '搜索结果读取失败')
        return null
      })
      .finally(() => {
        if (!background) setLoading(false)
      })
  }, [selectedQuery?.query_id, selectedQuery?.detail_version])

  useEffect(() => {
    setDetail(null)
    if (!selectedQuery?.query_id) return undefined
    const controller = new AbortController()
    load({ signal: controller.signal })
    return () => controller.abort()
  }, [selectedQuery?.query_id, load])

  return { detail, loading, error, reload: load }
}
