import "server-only"

import { trackEvent, type EventName } from "@/shared/lib/track-event"
import { recordAiEvent } from "../data-access"

export type AiUsageEvent = {
  userId: string
  capability: "chat" | "similar_question" | "grading_assist" | "lesson_content" | "question_variant" | "weakness_analysis" | "child_summary" | "study_path" | "explain_error"
  providerId?: string
  model?: string
  success: boolean
  durationMs: number
  tokenUsage?: number
  errorMessage?: string
}

const AI_EVENT_MAP: Record<AiUsageEvent["capability"], EventName> = {
  chat: "ai.chat",
  similar_question: "ai.similar_question",
  grading_assist: "ai.grading_assist",
  lesson_content: "ai.lesson_content",
  question_variant: "ai.question_variant",
  weakness_analysis: "ai.weakness_analysis",
  child_summary: "ai.child_summary",
  study_path: "ai.study_path",
  explain_error: "ai.explain_error",
}

/**
 * AI 使用埋点
 *
 * 记录每次 AI 调用的元数据，用于监控、成本分析与异常排查。
 * 同时写入 data-access 层的内存事件存储（供管理员仪表盘聚合查询）。
 * 非阻塞，失败不影响主流程。
 */
export const trackAiUsage = (event: AiUsageEvent): void => {
  const eventName = AI_EVENT_MAP[event.capability]

  // 写入 data-access 层（供 getAiUsageStats 聚合）
  recordAiEvent({
    userId: event.userId,
    capability: event.capability,
    success: event.success,
    durationMs: event.durationMs,
    timestamp: Date.now(),
    errorMessage: event.errorMessage,
  })

  // 写入全局 trackEvent（供外部监控系统）
  void trackEvent({
    event: eventName,
    userId: event.userId,
    targetType: event.capability,
    properties: {
      providerId: event.providerId,
      model: event.model,
      success: event.success,
      durationMs: event.durationMs,
      tokenUsage: event.tokenUsage,
      errorMessage: event.errorMessage,
    },
  }).catch(() => {
    // 静默失败：埋点不应影响业务流程
  })
}

/**
 * 测量 AI 调用耗时并自动埋点
 */
export const withAiTracking = async <T>(
  userId: string,
  capability: AiUsageEvent["capability"],
  providerId: string | undefined,
  fn: () => Promise<{ result: T; model?: string; tokenUsage?: number }>
): Promise<T> => {
  const start = Date.now()
  try {
    const { result, model, tokenUsage } = await fn()
    trackAiUsage({
      userId,
      capability,
      providerId,
      model,
      success: true,
      durationMs: Date.now() - start,
      tokenUsage,
    })
    return result
  } catch (error) {
    trackAiUsage({
      userId,
      capability,
      providerId,
      success: false,
      durationMs: Date.now() - start,
      errorMessage: error instanceof Error ? error.message : String(error),
    })
    throw error
  }
}
