"use client"

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

import type { ActionState } from "@/shared/types/action-state"

import {
  abandonPracticeSessionAction,
  completePracticeSessionAction,
  createPracticeSessionAction,
  getPracticeSessionDetailAction,
  getPracticeSessionsAction,
  getPracticeStatsAction,
  submitPracticeAnswerAction,
} from "../actions"
import type {
  PracticeSessionDetail,
  PracticeSessionSummary,
  PracticeStats,
} from "../types"

// ─── 数据服务接口 ──────────────────────────────────────────

/**
 * 专项练习数据服务接口（抽象数据依赖）。
 *
 * 组件层通过 `usePracticeService()` 消费此接口，而非直接 import actions，
 * 实现完全解耦：
 * - 默认实现调用真实 Server Actions（见下方 `defaultPracticeService`）
 * - 测试时可注入 mock 实现以隔离数据层
 * - 不同角色（student / parent / teacher）可注入不同实现，
 *   例如 ParentPracticeService 在调用时自动附加子女 studentId
 *
 * 所有写入方法签名与 Server Action 保持一致（prevState + formData），
 * 便于无缝替换；读取方法直接返回数据，由 Server Action 内部处理权限校验。
 */
export interface PracticeService {
  /** 创建练习会话 */
  createSession(
    prevState: ActionState<{ sessionId: string; selectedCount: number }> | undefined,
    formData: FormData,
  ): Promise<ActionState<{ sessionId: string; selectedCount: number }>>
  /** 提交单题答案 */
  submitAnswer(
    prevState: ActionState<{ isCorrect: boolean | null; score: number | null }> | undefined,
    formData: FormData,
  ): Promise<ActionState<{ isCorrect: boolean | null; score: number | null }>>
  /** 完成练习会话 */
  completeSession(
    prevState: ActionState<void> | undefined,
    formData: FormData,
  ): Promise<ActionState<void>>
  /** 放弃练习会话 */
  abandonSession(
    prevState: ActionState<void> | undefined,
    formData: FormData,
  ): Promise<ActionState<void>>
  /** 获取练习会话列表 */
  getSessions(
    studentId?: string,
  ): Promise<ActionState<{ data: PracticeSessionSummary[]; total: number }>>
  /** 获取练习会话详情（含答题记录） */
  getSessionDetail(
    sessionId: string,
    studentId?: string,
  ): Promise<ActionState<PracticeSessionDetail>>
  /** 获取练习统计 */
  getStats(studentId?: string): Promise<ActionState<PracticeStats>>
}

// ─── 监控埋点接口 ──────────────────────────────────────────

/**
 * 专项练习监控埋点接口。
 *
 * 预留关键操作埋点，供后续接入实际监控 SDK（如 PostHog / Mixpanel）。
 * 默认实现为空操作（见 `noopPracticeAnalytics`），生产环境通过
 * Provider 注入实际实现。
 */
export interface PracticeAnalytics {
  /** 练习会话创建 */
  trackSessionStart(practiceType: string, questionCount: number): void
  /** 单题答案提交 */
  trackAnswerSubmit(sessionId: string, answerId: string, isCorrect: boolean | null): void
  /** 练习会话完成 */
  trackSessionComplete(sessionId: string, accuracy: number): void
  /** 练习会话放弃 */
  trackSessionAbandon(sessionId: string): void
  /** 提交失败重试 */
  trackErrorRetry(answerId: string): void
}

const noopPracticeAnalytics: PracticeAnalytics = {
  trackSessionStart: () => {},
  trackAnswerSubmit: () => {},
  trackSessionComplete: () => {},
  trackSessionAbandon: () => {},
  trackErrorRetry: () => {},
}

// ─── 默认实现（代理到真实 Server Actions） ──────────────────

/**
 * 默认 PracticeService 实现：直接代理到真实 Server Actions。
 *
 * 测试或角色定制时可在 Provider 中注入其他实现以覆盖此默认行为。
 */
export const defaultPracticeService: PracticeService = {
  createSession: (prevState, formData) => createPracticeSessionAction(prevState, formData),
  submitAnswer: (prevState, formData) => submitPracticeAnswerAction(prevState, formData),
  completeSession: (prevState, formData) => completePracticeSessionAction(prevState, formData),
  abandonSession: (prevState, formData) => abandonPracticeSessionAction(prevState, formData),
  getSessions: (studentId) => getPracticeSessionsAction(studentId),
  getSessionDetail: (sessionId, studentId) =>
    getPracticeSessionDetailAction(sessionId, studentId),
  getStats: (studentId) => getPracticeStatsAction(studentId),
}

// ─── React Context 依赖注入 ────────────────────────────────

const PracticeServiceContext = createContext<PracticeService | null>(null)
const PracticeAnalyticsContext = createContext<PracticeAnalytics>(noopPracticeAnalytics)

interface PracticeServiceProviderProps {
  /** 注入的服务实现；不传则使用默认实现（调用真实 Server Actions） */
  service?: PracticeService
  /** 注入的监控埋点实现；不传则使用空操作 */
  analytics?: PracticeAnalytics
  children: ReactNode
}

/**
 * 专项练习服务 Provider（在页面层注入角色特定的实现）。
 *
 * 未包裹 Provider 时 `usePracticeService()` 回退到默认实现，保证向后兼容。
 */
export function PracticeServiceProvider({
  service,
  analytics,
  children,
}: PracticeServiceProviderProps): ReactNode {
  return (
    <PracticeServiceContext.Provider value={service ?? defaultPracticeService}>
      <PracticeAnalyticsContext.Provider value={analytics ?? noopPracticeAnalytics}>
        {children}
      </PracticeAnalyticsContext.Provider>
    </PracticeServiceContext.Provider>
  )
}

/** 获取当前注入的专项练习数据服务 */
export function usePracticeService(): PracticeService {
  const ctx = useContext(PracticeServiceContext)
  return ctx ?? defaultPracticeService
}

/** 获取当前注入的监控埋点接口 */
export function usePracticeAnalytics(): PracticeAnalytics {
  return useContext(PracticeAnalyticsContext)
}
