"use client"

import { createContext, useContext, useMemo, type ReactNode } from "react"

import type { DiagnosticService } from "./diagnostic-service"
import { defaultDiagnosticService } from "./default-diagnostic-service"
import { createMonitoredDiagnosticService } from "./monitored-diagnostic-service"
import { noopDiagnosticMonitor } from "./diagnostic-monitor"
import { useDiagnosticMonitor } from "./diagnostic-monitor-context"

/**
 * v2-P1-4: 诊断模块服务 Context。
 *
 * 组件通过 useDiagnosticService() 获取服务实现，
 * 而非直接 import actions，实现依赖反转。
 *
 * 默认由 DiagnosticServiceProvider 在客户端组装默认实现（调用 Server Actions）；
 * 测试时可注入 mock 实现以隔离组件测试。
 */
const DiagnosticServiceContext = createContext<DiagnosticService | null>(null)

interface DiagnosticServiceProviderProps {
  /** 可选自定义服务实现，未传则使用 defaultDiagnosticService + 监控包装 */
  service?: DiagnosticService
  children: ReactNode
}

export function DiagnosticServiceProvider({
  service,
  children,
}: DiagnosticServiceProviderProps): ReactNode {
  const monitor = useDiagnosticMonitor()
  const value = useMemo<DiagnosticService>(() => {
    if (service) return service
    // 客户端组装：默认 service + 监控埋点包装
    return createMonitoredDiagnosticService(
      defaultDiagnosticService,
      monitor ?? noopDiagnosticMonitor,
    )
  }, [service, monitor])

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

/**
 * 获取诊断模块服务。
 * 必须在 DiagnosticServiceProvider 内部使用。
 */
export function useDiagnosticService(): DiagnosticService {
  const service = useContext(DiagnosticServiceContext)
  if (!service) {
    throw new Error(
      "useDiagnosticService must be used within a DiagnosticServiceProvider",
    )
  }
  return service
}
