"use client"

import { useState, useEffect, useCallback } from "react"
import { getKnowledgeGraphDataAction } from "../actions"
import type { GraphViewMode, KnowledgeGraphData } from "../types"

interface UseGraphDataResult {
  data: KnowledgeGraphData | null
  /** 首次加载（无任何数据时） */
  isLoading: boolean
  /** 切换模式时的刷新（保留旧数据，显示轻量指示器） */
  isRefreshing: boolean
  error: string | null
  reload: () => void
}

/**
 * 图谱数据加载 Hook。
 *
 * 按 textbookId + viewMode 加载，切换 viewMode 时重新加载。
 * 区分 isLoading（首次加载）和 isRefreshing（切换模式刷新），
 * 切换模式时保留旧数据避免 UI 闪烁。
 *
 * 注意：不使用 lastRequestKey 防重复机制。该机制在 React StrictMode
 * （Next.js 默认启用）下会导致 action 结果被丢弃：
 * 第一次 mount 发起 action → cleanup 设置 cancelled=true →
 * 第二次 mount 因 requestKey 相同跳过 → action 结果被忽略 → 永久 loading。
 * useEffect 依赖数组已足够控制 effect 执行频率，无需额外防重复。
 */
export function useGraphData(
  textbookId: string,
  viewMode: GraphViewMode,
): UseGraphDataResult {
  const [data, setData] = useState<KnowledgeGraphData | null>(null)
  const [error, setError] = useState<string | null>(null)
  const [reloadTrigger, setReloadTrigger] = useState(0)

  const reload = useCallback(() => {
    setReloadTrigger((n) => n + 1)
  }, [])

  // 首次加载：完全无数据
  const isLoading = data === null && error === null
  // 切换模式刷新：有旧数据但 viewMode 不匹配
  const isRefreshing = data !== null && data.viewMode !== viewMode

  useEffect(() => {
    if (!textbookId) return

    let cancelled = false

    getKnowledgeGraphDataAction(textbookId, viewMode)
      .then((result) => {
        if (cancelled) return
        if (result.success && result.data) {
          setData(result.data)
          setError(null)
        } else {
          setData(null)
          // 错误消息使用通用 key，由组件层翻译
          setError(result.message ?? "graph.error.loadFailed")
        }
      })
      .catch((e: unknown) => {
        if (!cancelled) {
          setData(null)
          setError(e instanceof Error ? e.message : "graph.error.loadFailed")
        }
      })

    return () => {
      cancelled = true
    }
  }, [textbookId, viewMode, reloadTrigger])

  return { data, isLoading, error, reload, isRefreshing }
}
