"use client"

import { useState, useTransition } from "react"
import { useTranslations } from "next-intl"
import { Target, BookOpen, AlertCircle, Sparkles } from "lucide-react"
import { toast } from "sonner"

import { Button } from "@/shared/components/ui/button"
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/shared/components/ui/card"
import { Checkbox } from "@/shared/components/ui/checkbox"
import { Label } from "@/shared/components/ui/label"
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/shared/components/ui/select"

import { isPracticeType } from "../lib/type-guards"
import { usePracticeService, usePracticeAnalytics } from "../services/practice-service"
import type { AiRecommendedReason, PracticeType } from "../types"

export interface PracticeStarterProps {
  /** 知识点选项列表 */
  knowledgePoints: Array<{ id: string; name: string }>
  /** 预设模式（从错题本发起时传入） */
  presetMode?: {
    type: PracticeType
    sourceMeta: Record<string, unknown>
    subjectId?: string
  }
  /** 是否禁用类型选择（预设模式时） */
  lockType?: boolean
  /**
   * 会话创建成功后的回调（由页面层注入路由跳转逻辑）。
   *
   * 解耦设计：组件本身不感知路由，由调用方决定跳转目标
   * （学生跳 `/student/practice/[id]`，家长可能跳 `/parent/practice/[id]`）。
   * 不传则不跳转（仅 toast 提示）。
   */
  onSessionCreated?: (sessionId: string) => void
  /**
   * AI 推荐练习的发起角色（决定 sourceMeta.reason 枚举值）。
   *
   * - 学生自主发起（默认）：`"student_initiated"`
   * - 家长建议子女：`"parent_suggested"`
   * - 教师布置：`"teacher_assigned"`
   */
  aiRecommendReason?: AiRecommendedReason
}

const QUESTION_COUNT_OPTIONS = [5, 10, 15, 20, 30] as const

/**
 * 专项练习发起器。
 *
 * 通过 `usePracticeService()` 获取数据服务，不直接 import actions，
 * 实现完全解耦：测试时可注入 mock 服务，不同角色可注入不同实现。
 *
 * 路由跳转通过 `onSessionCreated` 回调注入，组件本身不感知路由结构。
 *
 * 支持四种练习模式：
 * 1. 错题重做：从错题本发起（通过 presetMode）
 * 2. 知识点专项：选择知识点后抽题
 * 3. 薄弱章节：自动识别薄弱知识点（不传 chapterId 时跨章节识别）
 * 4. AI 推荐：根据学情推荐
 */
export function PracticeStarter({
  knowledgePoints,
  presetMode,
  lockType,
  onSessionCreated,
  aiRecommendReason = "student_initiated",
}: PracticeStarterProps): React.ReactNode {
  const t = useTranslations("practice")
  const service = usePracticeService()
  const analytics = usePracticeAnalytics()
  const [isPending, startTransition] = useTransition()

  const [practiceType, setPracticeType] = useState<PracticeType>(
    presetMode?.type ?? "knowledge_point",
  )
  const [selectedKpIds, setSelectedKpIds] = useState<string[]>([])
  const [questionCount, setQuestionCount] = useState<number>(10)
  const [difficulty, setDifficulty] = useState<number>(0)

  function toggleKp(kpId: string): void {
    setSelectedKpIds((prev) =>
      prev.includes(kpId) ? prev.filter((id) => id !== kpId) : [...prev, kpId],
    )
  }

  function handleTypeChange(value: string): void {
    // 严格类型守卫替代 `value as PracticeType` 断言
    if (isPracticeType(value)) {
      setPracticeType(value)
    }
  }

  function handleDifficultyChange(value: string): void {
    const num = Number(value)
    if (Number.isInteger(num)) {
      setDifficulty(num)
    }
  }

  function handleQuestionCountChange(value: string): void {
    const num = Number(value)
    if (Number.isInteger(num)) {
      setQuestionCount(num)
    }
  }

  function resolveErrorMessage(
    errorCode: string | undefined,
    message: string | undefined,
    fallbackKey: string,
  ): string {
    if (errorCode) {
      return t(`errors.${errorCode}`)
    }
    return message ?? t(fallbackKey)
  }

  function handleStart(): void {
    if (presetMode) {
      // 预设模式：直接使用传入的 sourceMeta
      startTransition(async () => {
        const formData = new FormData()
        formData.append(
          "json",
          JSON.stringify({
            practiceType: presetMode.type,
            subjectId: presetMode.subjectId,
            sourceMeta: presetMode.sourceMeta,
            questionCount,
          }),
        )
        const res = await service.createSession(undefined, formData)
        if (res.success && res.data) {
          analytics.trackSessionStart(presetMode.type, questionCount)
          toast.success(res.message ?? t("toasts.created"))
          onSessionCreated?.(res.data.sessionId)
        } else {
          toast.error(resolveErrorMessage(res.errorCode, res.message, "toasts.createFailed"))
        }
      })
      return
    }

    // 自定义模式：根据类型构建 sourceMeta
    let sourceMeta: Record<string, unknown> = {}

    if (practiceType === "knowledge_point") {
      if (selectedKpIds.length === 0) {
        toast.error(t("toasts.selectKnowledgePoint"))
        return
      }
      sourceMeta = {
        knowledgePointIds: selectedKpIds,
        difficulty: difficulty > 0 ? difficulty : undefined,
      }
    } else if (practiceType === "weak_chapter") {
      // 薄弱章节模式：传入选中的知识点作为薄弱知识点
      // 不传 chapterId 时，后端跨所有章节自动识别薄弱知识点
      if (selectedKpIds.length === 0) {
        toast.error(t("toasts.selectWeakKnowledgePoint"))
        return
      }
      sourceMeta = {
        weakKnowledgePointIds: selectedKpIds,
      }
    } else if (practiceType === "ai_recommended") {
      sourceMeta = {
        recommendedKnowledgePointIds: selectedKpIds,
        // 枚举值（业务数据），UI 层通过 t(`reasons.${reason}`) 查 i18n
        reason: aiRecommendReason,
      }
    }

    startTransition(async () => {
      const formData = new FormData()
      formData.append(
        "json",
        JSON.stringify({
          practiceType,
          sourceMeta,
          questionCount,
        }),
      )
      const res = await service.createSession(undefined, formData)
      if (res.success && res.data) {
        analytics.trackSessionStart(practiceType, questionCount)
        toast.success(res.message ?? t("toasts.created"))
        onSessionCreated?.(res.data.sessionId)
      } else {
        toast.error(resolveErrorMessage(res.errorCode, res.message, "toasts.createFailed"))
      }
    })
  }

  const showKpSelector =
    !presetMode ||
    practiceType === "knowledge_point" ||
    practiceType === "weak_chapter" ||
    practiceType === "ai_recommended"

  return (
    <Card>
      <CardHeader>
        <CardTitle className="flex items-center gap-2">
          <Target className="h-5 w-5 text-primary" aria-hidden="true" />
          {t("starter.title")}
        </CardTitle>
        <CardDescription>{t("starter.description")}</CardDescription>
      </CardHeader>
      <CardContent className="space-y-4">
        {/* 练习类型选择 */}
        {!lockType ? (
          <div className="space-y-2">
            <Label htmlFor="practice-type-select">{t("starter.type")}</Label>
            <Select value={practiceType} onValueChange={handleTypeChange}>
              <SelectTrigger id="practice-type-select" aria-label={t("starter.type")}>
                <SelectValue />
              </SelectTrigger>
              <SelectContent>
                <SelectItem value="knowledge_point">
                  <span className="flex items-center gap-2">
                    <BookOpen className="h-4 w-4" aria-hidden="true" />
                    {t("types.knowledge_point")}
                  </span>
                </SelectItem>
                <SelectItem value="weak_chapter">
                  <span className="flex items-center gap-2">
                    <AlertCircle className="h-4 w-4" aria-hidden="true" />
                    {t("types.weak_chapter")}
                  </span>
                </SelectItem>
                <SelectItem value="ai_recommended">
                  <span className="flex items-center gap-2">
                    <Sparkles className="h-4 w-4" aria-hidden="true" />
                    {t("types.ai_recommended")}
                  </span>
                </SelectItem>
              </SelectContent>
            </Select>
          </div>
        ) : null}

        {/* 知识点选择 */}
        {showKpSelector && knowledgePoints.length > 0 ? (
          <div className="space-y-2">
            <Label>{t("starter.knowledgePoints")}</Label>
            <div
              className="grid grid-cols-2 gap-2 max-h-48 overflow-y-auto rounded-md border p-2"
              role="group"
              aria-label={t("starter.knowledgePoints")}
            >
              {knowledgePoints.map((kp) => {
                const checked = selectedKpIds.includes(kp.id)
                return (
                  <label
                    key={kp.id}
                    className="flex items-center gap-2 rounded-md p-2 hover:bg-muted/50 cursor-pointer"
                  >
                    <Checkbox
                      checked={checked}
                      onCheckedChange={() => toggleKp(kp.id)}
                      aria-label={kp.name}
                    />
                    <span className="text-sm">{kp.name}</span>
                  </label>
                )
              })}
            </div>
          </div>
        ) : null}

        {/* 难度选择（仅知识点专项） */}
        {practiceType === "knowledge_point" && !presetMode ? (
          <div className="space-y-2">
            <Label htmlFor="difficulty-select">{t("starter.difficulty")}</Label>
            <Select value={String(difficulty)} onValueChange={handleDifficultyChange}>
              <SelectTrigger id="difficulty-select" aria-label={t("starter.difficulty")}>
                <SelectValue />
              </SelectTrigger>
              <SelectContent>
                <SelectItem value="0">{t("starter.anyDifficulty")}</SelectItem>
                <SelectItem value="1">1</SelectItem>
                <SelectItem value="2">2</SelectItem>
                <SelectItem value="3">3</SelectItem>
                <SelectItem value="4">4</SelectItem>
                <SelectItem value="5">5</SelectItem>
              </SelectContent>
            </Select>
          </div>
        ) : null}

        {/* 题目数量 */}
        <div className="space-y-2">
          <Label htmlFor="question-count-select">{t("starter.questionCount")}</Label>
          <Select value={String(questionCount)} onValueChange={handleQuestionCountChange}>
            <SelectTrigger id="question-count-select" aria-label={t("starter.questionCount")}>
              <SelectValue />
            </SelectTrigger>
            <SelectContent>
              {QUESTION_COUNT_OPTIONS.map((count) => (
                <SelectItem key={count} value={String(count)}>
                  {count}
                </SelectItem>
              ))}
            </SelectContent>
          </Select>
        </div>

        {/* 开始按钮 */}
        <Button
          onClick={handleStart}
          disabled={isPending}
          className="w-full"
          aria-label={isPending ? t("starter.creating") : t("starter.start")}
        >
          {isPending ? t("starter.creating") : t("starter.start")}
        </Button>
      </CardContent>
    </Card>
  )
}
