"use server"

import { requirePermission } from "@/shared/lib/auth-guard"
import { Permissions } from "@/shared/types/permissions"
import { CreateQuestionSchema } from "./schema"
import type { CreateQuestionInput } from "./schema"
import type { ActionState } from "@/shared/types/action-state"
import { revalidatePath } from "next/cache"
import { z } from "zod"
import {
  createQuestionWithRelations,
  deleteQuestionByIdRecursive,
  deleteQuestionsBatch,
  exportQuestions,
  getChapterOptions,
  getKnowledgePointOptions,
  getKnowledgePointOptionsByChapter,
  getQuestions,
  getTextbookOptions,
  importQuestions,
  updateQuestionById,
  type GetQuestionsParams,
  type QuestionExportItem,
  type QuestionImportItem,
} from "./data-access"
import type { ChapterOption, KnowledgePointOption, TextbookOption } from "./types"
import { QuestionTypeEnum } from "./schema"
import { handleActionError, safeJsonParse } from "@/shared/lib/action-utils"
import { trackQuestionCreated, trackQuestionUpdated, trackQuestionDeleted } from "./utils/track-event"

/** Result type of getQuestions (data + meta) */
type QuestionsListResult = Awaited<ReturnType<typeof getQuestions>>

/** Result type of getKnowledgePointOptions */
type KnowledgePointOptionsResult = KnowledgePointOption[]

export async function createQuestionAction(
  prevState: ActionState<string> | undefined,
  formData: FormData | CreateQuestionInput,
): Promise<ActionState<string>> {
  try {
    const ctx = await requirePermission(Permissions.QUESTION_CREATE)

    let rawInput: unknown = formData

    if (formData instanceof FormData) {
      const jsonString = formData.get("json")
      if (typeof jsonString === "string") {
        rawInput = safeJsonParse<unknown>(jsonString, "题目内容格式无效")
      } else {
        return { success: false, message: "Invalid submission format. Expected JSON." }
      }
    }

    const validatedFields = CreateQuestionSchema.safeParse(rawInput)

    if (!validatedFields.success) {
      return {
        success: false,
        message: "Validation failed",
        errors: validatedFields.error.flatten().fieldErrors,
      }
    }

    const input = validatedFields.data

    const questionId = await createQuestionWithRelations(input, ctx.userId)

    trackQuestionCreated(questionId, input.type, input.difficulty)

    revalidatePath("/teacher/questions")
    revalidatePath("/admin/questions")

    return {
      success: true,
      message: "Question created successfully",
      data: questionId,
    }
  } catch (e) {
    return handleActionError(e)
  }
}

const UpdateQuestionSchema = z.object({
  id: z.string().min(1),
  type: z.enum(["single_choice", "multiple_choice", "text", "judgment", "composite"]),
  difficulty: z.number().min(1).max(5),
  content: z.record(z.string(), z.unknown()),
  knowledgePointIds: z.array(z.string()).optional(),
})

export async function updateQuestionAction(
  prevState: ActionState<string> | undefined,
  formData: FormData,
): Promise<ActionState<string>> {
  try {
    const ctx = await requirePermission(Permissions.QUESTION_UPDATE)
    const canEditAll = ctx.dataScope.type === "all"

    const jsonString = formData.get("json")
    if (typeof jsonString !== "string") {
      return { success: false, message: "Invalid submission format. Expected JSON." }
    }

    const parsed = UpdateQuestionSchema.safeParse(safeJsonParse<unknown>(jsonString, "题目内容格式无效"))
    if (!parsed.success) {
      return {
        success: false,
        message: "Validation failed",
        errors: parsed.error.flatten().fieldErrors,
      }
    }

    const { id, ...updateData } = parsed.data

    await updateQuestionById(id, updateData, canEditAll, ctx.userId)

    trackQuestionUpdated(id, updateData.type, updateData.difficulty)

    revalidatePath("/teacher/questions")
    revalidatePath("/admin/questions")

    return { success: true, message: "Question updated successfully", data: id }
  } catch (e) {
    return handleActionError(e)
  }
}

export async function deleteQuestionAction(
  prevState: ActionState<string> | undefined,
  formData: FormData,
): Promise<ActionState<string>> {
  try {
    const ctx = await requirePermission(Permissions.QUESTION_DELETE)
    const canDeleteAll = ctx.dataScope.type === "all"

    const questionId = formData.get("questionId")
    if (typeof questionId !== "string") {
      return { success: false, message: "Invalid question ID" }
    }

    await deleteQuestionByIdRecursive(questionId, canDeleteAll, ctx.userId)

    trackQuestionDeleted(questionId)

    revalidatePath("/teacher/questions")
    revalidatePath("/admin/questions")

    return { success: true, message: "Question deleted successfully", data: questionId }
  } catch (e) {
    return handleActionError(e)
  }
}

const BatchDeleteSchema = z.object({
  ids: z.array(z.string().min(1)).min(1, "At least one question ID is required"),
})

/**
 * 批量删除题目。
 *
 * 输入 JSON：{ ids: string[] }
 * 权限：QUESTION_DELETE，遵循数据范围过滤。
 */
export async function deleteQuestionsBatchAction(
  prevState: ActionState<{ deleted: number }> | undefined,
  formData: FormData,
): Promise<ActionState<{ deleted: number }>> {
  try {
    const ctx = await requirePermission(Permissions.QUESTION_DELETE)
    const canDeleteAll = ctx.dataScope.type === "all"

    const jsonString = formData.get("json")
    if (typeof jsonString !== "string") {
      return { success: false, message: "Invalid submission format. Expected JSON." }
    }

    const parsed = BatchDeleteSchema.safeParse(safeJsonParse<unknown>(jsonString, "批量删除参数无效"))
    if (!parsed.success) {
      return {
        success: false,
        message: "Validation failed",
        errors: parsed.error.flatten().fieldErrors,
      }
    }

    const deletedCount = await deleteQuestionsBatch(parsed.data.ids, canDeleteAll, ctx.userId)

    for (const id of parsed.data.ids) {
      trackQuestionDeleted(id)
    }

    revalidatePath("/teacher/questions")
    revalidatePath("/admin/questions")

    return { success: true, message: "Batch delete completed", data: { deleted: deletedCount } }
  } catch (e) {
    return handleActionError(e)
  }
}

export async function getQuestionsAction(
  params: GetQuestionsParams,
): Promise<ActionState<QuestionsListResult>> {
  try {
    await requirePermission(Permissions.QUESTION_READ)
    const data = await getQuestions(params)
    return { success: true, data }
  } catch (e) {
    return handleActionError(e)
  }
}

export async function getKnowledgePointOptionsAction(): Promise<
  ActionState<KnowledgePointOptionsResult>
> {
  try {
    await requirePermission(Permissions.QUESTION_READ)
    const data = await getKnowledgePointOptions()
    return { success: true, data }
  } catch (e) {
    return handleActionError(e)
  }
}

/** Result type of getTextbookOptions */
type TextbookOptionsResult = TextbookOption[]

/** Result type of getChapterOptions */
type ChapterOptionsResult = ChapterOption[]

/** Result type of getKnowledgePointOptionsByChapter */
type KnowledgePointOptionsByChapterResult = { id: string; name: string }[]

/**
 * 获取教材选项列表（级联筛选第一级）。
 */
export async function getTextbookOptionsAction(): Promise<
  ActionState<TextbookOptionsResult>
> {
  try {
    await requirePermission(Permissions.QUESTION_READ)
    const data = await getTextbookOptions()
    return { success: true, data }
  } catch (e) {
    return handleActionError(e)
  }
}

/**
 * 获取指定教材下的章节选项列表（级联筛选第二级）。
 */
export async function getChapterOptionsAction(
  textbookId: string,
): Promise<ActionState<ChapterOptionsResult>> {
  try {
    await requirePermission(Permissions.QUESTION_READ)
    const data = await getChapterOptions(textbookId)
    return { success: true, data }
  } catch (e) {
    return handleActionError(e)
  }
}

/**
 * 获取指定章节下的知识点选项列表（级联筛选第三级）。
 */
export async function getKnowledgePointOptionsByChapterAction(
  chapterId: string,
): Promise<ActionState<KnowledgePointOptionsByChapterResult>> {
  try {
    await requirePermission(Permissions.QUESTION_READ)
    const data = await getKnowledgePointOptionsByChapter(chapterId)
    return { success: true, data }
  } catch (e) {
    return handleActionError(e)
  }
}

// ---------------------------------------------------------------------------
// 导入/导出 Server Actions
// ---------------------------------------------------------------------------

const ExportSchema = z.object({
  ids: z.array(z.string().min(1)).optional(),
})

/**
 * 导出题目为 JSON 格式。
 *
 * 输入 JSON：{ ids?: string[] }（不传 ids 则导出全部，受权限范围限制）
 * 权限：QUESTION_READ，遵循数据范围过滤。
 */
export async function exportQuestionsAction(
  formData: FormData,
): Promise<ActionState<QuestionExportItem[]>> {
  try {
    const ctx = await requirePermission(Permissions.QUESTION_READ)
    const canExportAll = ctx.dataScope.type === "all"

    const jsonString = formData.get("json")
    const inputJson = typeof jsonString === "string" ? jsonString : "{}"
    const parsed = ExportSchema.safeParse(safeJsonParse<unknown>(inputJson, "导出参数无效"))

    if (!parsed.success) {
      return {
        success: false,
        message: "Validation failed",
        errors: parsed.error.flatten().fieldErrors,
      }
    }

    const data = await exportQuestions(parsed.data.ids, canExportAll, ctx.userId)
    return { success: true, data }
  } catch (e) {
    return handleActionError(e)
  }
}

const ImportItemSchema = z.object({
  type: QuestionTypeEnum,
  difficulty: z.number().min(1).max(5),
  content: z.unknown(),
  knowledgePointIds: z.array(z.string()).optional(),
})

const ImportSchema = z.object({
  items: z.array(ImportItemSchema).min(1, "至少需要一条题目"),
})

/**
 * 批量导入题目。
 *
 * 输入 JSON：{ items: QuestionImportItem[] }
 * 权限：QUESTION_CREATE。
 */
export async function importQuestionsAction(
  prevState: ActionState<{ imported: number }> | undefined,
  formData: FormData,
): Promise<ActionState<{ imported: number }>> {
  try {
    const ctx = await requirePermission(Permissions.QUESTION_CREATE)

    const jsonString = formData.get("json")
    if (typeof jsonString !== "string") {
      return { success: false, message: "Invalid submission format. Expected JSON." }
    }

    const parsed = ImportSchema.safeParse(safeJsonParse<unknown>(jsonString, "导入参数无效"))
    if (!parsed.success) {
      return {
        success: false,
        message: "Validation failed",
        errors: parsed.error.flatten().fieldErrors,
      }
    }

    const items: QuestionImportItem[] = parsed.data.items.map((item) => ({
      type: item.type,
      difficulty: item.difficulty,
      content: item.content,
      knowledgePointIds: item.knowledgePointIds,
    }))

    const createdIds = await importQuestions(items, ctx.userId)

    for (let i = 0; i < createdIds.length; i++) {
      const item = items[i]
      trackQuestionCreated(createdIds[i], item.type, item.difficulty)
    }

    revalidatePath("/teacher/questions")
    revalidatePath("/admin/questions")

    return { success: true, message: "Import completed", data: { imported: createdIds.length } }
  } catch (e) {
    return handleActionError(e)
  }
}
