import { useCallback, useEffect, useLayoutEffect, useReducer, useRef } from 'react'
import {
  intelligentEvalReadAdapter,
  intelligentEvalReadReducer,
  initialIntelligentEvalReadState,
  type IntelligentEvalReadAdapter,
  type IntelligentEvalReadState,
} from './intelligentEval'
import { usePolling } from '../hooks/usePolling'

const ACTIVE_STATUSES = new Set(['planning', 'pending_approval', 'executing'])

function errorMessage(error: unknown): string {
  return error instanceof Error ? error.message : '读取智能评估失败'
}

function isActive(status: string | undefined): boolean {
  return status != null && ACTIVE_STATUSES.has(status)
}

export function useIntelligentEvalRead(
  selectedId: string | null,
  adapter: IntelligentEvalReadAdapter = intelligentEvalReadAdapter,
): IntelligentEvalReadState & { reloadList: () => Promise<void>; reloadDetail: () => Promise<void> } {
  const [state, dispatch] = useReducer(intelligentEvalReadReducer, initialIntelligentEvalReadState)
  const detailRequestId = useRef(0)

  const loadList = useCallback(async (silent = false) => {
    dispatch({ type: 'list_requested', silent })
    try {
      const value = await adapter.list()
      dispatch({ type: 'list_succeeded', value })
    } catch (error) {
      dispatch({ type: 'list_failed', error: errorMessage(error) })
    }
  }, [adapter])

  const loadDetail = useCallback(async (id: string, silent = false) => {
    const requestId = ++detailRequestId.current
    dispatch({ type: 'detail_requested', id, requestId, silent })
    try {
      const value = await adapter.get(id)
      dispatch({ type: 'detail_succeeded', id, requestId, value })
    } catch (error) {
      dispatch({ type: 'detail_failed', id, requestId, error: errorMessage(error) })
    }
  }, [adapter])

  useEffect(() => {
    void loadList()
  }, [loadList])

  useLayoutEffect(() => {
    if (selectedId == null) {
      dispatch({ type: 'detail_cleared', requestId: ++detailRequestId.current })
      return
    }
    void loadDetail(selectedId)
  }, [loadDetail, selectedId])

  const listActive = state.list.value.some((item) => isActive(item.status))
  const detailActive = isActive(state.detail.value?.status)

  usePolling(() => { void loadList(true) }, 5000, listActive)
  usePolling(
    () => {
      if (selectedId != null) void loadDetail(selectedId, true)
    },
    5000,
    selectedId != null && detailActive,
  )

  const reloadList = useCallback(() => loadList(true), [loadList])
  const reloadDetail = useCallback(
    () => (selectedId == null ? Promise.resolve() : loadDetail(selectedId, true)),
    [loadDetail, selectedId],
  )

  return { ...state, reloadList, reloadDetail }
}
