"use server"

import { revalidatePath } from "next/cache"
import { z } from "zod"

import { requirePermission, PermissionDeniedError } from "@/shared/lib/auth-guard"
import { Permissions } from "@/shared/types/permissions"
import type { ActionState } from "@/shared/types/action-state"

import {
  CreateErrorBookItemSchema,
  ReviewErrorBookItemSchema,
  UpdateErrorBookNoteSchema,
  CollectFromSubmissionSchema,
} from "./schema"
import {
  archiveErrorBookItem,
  collectFromExamSubmission,
  collectFromHomeworkSubmission,
  createErrorBookItem,
  deleteErrorBookItem,
  getErrorBookItemById,
  getErrorBookItems,
  getErrorBookStats,
  recordReview,
  updateErrorBookNote,
} from "./data-access"
import type { ErrorBookListResult, ErrorBookStats as ErrorBookStatsType, ErrorBookItemDetail } from "./types"

// ---------------------------------------------------------------------------
// 学生端 Actions
// ---------------------------------------------------------------------------

export async function getErrorBookItemsAction(
  params: {
    studentId?: string
    q?: string
    page?: number
    pageSize?: number
    status?: string
    sourceType?: string
    subjectId?: string
    dueOnly?: boolean
  }
): Promise<ActionState<ErrorBookListResult>> {
  try {
    const ctx = await requirePermission(Permissions.ERROR_BOOK_READ)

    // 学生只能看自己的错题本；家长查看子女的错题本（通过 dataScope.childrenIds 校验）
    const studentId = ctx.dataScope.type === "children"
      ? params.studentId ?? ctx.dataScope.childrenIds[0] ?? ctx.userId
      : ctx.userId

    // 如果传入 studentId 且不是自己，需要校验权限（家长查看子女）
    if (params.studentId && params.studentId !== ctx.userId) {
      if (ctx.dataScope.type !== "children" || !ctx.dataScope.childrenIds.includes(params.studentId)) {
        throw new PermissionDeniedError(Permissions.ERROR_BOOK_READ)
      }
    }

    const statusParse = z.enum(["new", "learning", "mastered", "archived"]).safeParse(params.status)
    const status = params.status && params.status !== "all" && statusParse.success
      ? statusParse.data
      : undefined

    const sourceTypeParse = z.enum(["exam", "homework", "manual"]).safeParse(params.sourceType)
    const sourceType = params.sourceType && params.sourceType !== "all" && sourceTypeParse.success
      ? sourceTypeParse.data
      : undefined

    const data = await getErrorBookItems({
      studentId,
      q: params.q,
      page: params.page,
      pageSize: params.pageSize,
      status,
      sourceType,
      subjectId: params.subjectId && params.subjectId !== "all" ? params.subjectId : undefined,
      dueOnly: params.dueOnly,
    })

    return { success: true, data }
  } catch (e) {
    if (e instanceof PermissionDeniedError) {
      return { success: false, message: e.message }
    }
    const message = e instanceof Error ? e.message : "获取错题列表失败"
    return { success: false, message }
  }
}

export async function getErrorBookItemDetailAction(
  itemId: string
): Promise<ActionState<ErrorBookItemDetail>> {
  try {
    const ctx = await requirePermission(Permissions.ERROR_BOOK_READ)

    const studentId = ctx.dataScope.type === "children"
      ? ctx.dataScope.childrenIds[0] ?? ctx.userId
      : ctx.userId

    const data = await getErrorBookItemById(itemId, studentId)
    if (!data) {
      return { success: false, message: "错题不存在或无权访问" }
    }
    return { success: true, data }
  } catch (e) {
    if (e instanceof PermissionDeniedError) {
      return { success: false, message: e.message }
    }
    const message = e instanceof Error ? e.message : "获取错题详情失败"
    return { success: false, message }
  }
}

export async function getErrorBookStatsAction(
  studentId?: string
): Promise<ActionState<ErrorBookStatsType>> {
  try {
    const ctx = await requirePermission(Permissions.ERROR_BOOK_READ)

    let targetStudentId = ctx.userId
    if (studentId && studentId !== ctx.userId) {
      if (ctx.dataScope.type !== "children" || !ctx.dataScope.childrenIds.includes(studentId)) {
        throw new PermissionDeniedError(Permissions.ERROR_BOOK_READ)
      }
      targetStudentId = studentId
    } else if (ctx.dataScope.type === "children") {
      targetStudentId = ctx.dataScope.childrenIds[0] ?? ctx.userId
    }

    const data = await getErrorBookStats(targetStudentId)
    return { success: true, data }
  } catch (e) {
    if (e instanceof PermissionDeniedError) {
      return { success: false, message: e.message }
    }
    const message = e instanceof Error ? e.message : "获取错题统计失败"
    return { success: false, message }
  }
}

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

    const jsonString = formData.get("json")
    if (typeof jsonString !== "string") {
      return { success: false, message: "提交格式错误，需要 JSON 字段" }
    }

    const parsed = CreateErrorBookItemSchema.safeParse(JSON.parse(jsonString))
    if (!parsed.success) {
      return {
        success: false,
        message: "输入验证失败",
        errors: parsed.error.flatten().fieldErrors,
      }
    }

    const id = await createErrorBookItem(ctx.userId, parsed.data)
    revalidatePath("/student/error-book")

    return { success: true, message: "错题已添加", data: id }
  } catch (e) {
    if (e instanceof PermissionDeniedError) {
      return { success: false, message: e.message }
    }
    const message = e instanceof Error ? e.message : "添加错题失败"
    return { success: false, message }
  }
}

export async function updateErrorBookNoteAction(
  prevState: ActionState<void> | undefined,
  formData: FormData
): Promise<ActionState<void>> {
  try {
    const ctx = await requirePermission(Permissions.ERROR_BOOK_MANAGE)

    const jsonString = formData.get("json")
    if (typeof jsonString !== "string") {
      return { success: false, message: "提交格式错误" }
    }

    const parsed = UpdateErrorBookNoteSchema.safeParse(JSON.parse(jsonString))
    if (!parsed.success) {
      return {
        success: false,
        message: "输入验证失败",
        errors: parsed.error.flatten().fieldErrors,
      }
    }

    const { itemId, ...input } = parsed.data
    await updateErrorBookNote(itemId, ctx.userId, input)

    revalidatePath("/student/error-book")

    return { success: true, message: "笔记已更新" }
  } catch (e) {
    if (e instanceof PermissionDeniedError) {
      return { success: false, message: e.message }
    }
    const message = e instanceof Error ? e.message : "更新笔记失败"
    return { success: false, message }
  }
}

export async function reviewErrorBookItemAction(
  prevState: ActionState<void> | undefined,
  formData: FormData
): Promise<ActionState<void>> {
  try {
    const ctx = await requirePermission(Permissions.ERROR_BOOK_MANAGE)

    const jsonString = formData.get("json")
    if (typeof jsonString !== "string") {
      return { success: false, message: "提交格式错误" }
    }

    const parsed = ReviewErrorBookItemSchema.safeParse(JSON.parse(jsonString))
    if (!parsed.success) {
      return {
        success: false,
        message: "输入验证失败",
        errors: parsed.error.flatten().fieldErrors,
      }
    }

    await recordReview(parsed.data.itemId, ctx.userId, parsed.data.result)

    revalidatePath("/student/error-book")

    return { success: true, message: "复习结果已记录" }
  } catch (e) {
    if (e instanceof PermissionDeniedError) {
      return { success: false, message: e.message }
    }
    const message = e instanceof Error ? e.message : "记录复习结果失败"
    return { success: false, message }
  }
}

export async function deleteErrorBookItemAction(
  prevState: ActionState<void> | undefined,
  formData: FormData
): Promise<ActionState<void>> {
  try {
    const ctx = await requirePermission(Permissions.ERROR_BOOK_MANAGE)

    const itemId = formData.get("itemId")
    if (typeof itemId !== "string") {
      return { success: false, message: "无效的错题 ID" }
    }

    await deleteErrorBookItem(itemId, ctx.userId)

    revalidatePath("/student/error-book")

    return { success: true, message: "错题已删除" }
  } catch (e) {
    if (e instanceof PermissionDeniedError) {
      return { success: false, message: e.message }
    }
    const message = e instanceof Error ? e.message : "删除错题失败"
    return { success: false, message }
  }
}

export async function archiveErrorBookItemAction(
  prevState: ActionState<void> | undefined,
  formData: FormData
): Promise<ActionState<void>> {
  try {
    const ctx = await requirePermission(Permissions.ERROR_BOOK_MANAGE)

    const itemId = formData.get("itemId")
    if (typeof itemId !== "string") {
      return { success: false, message: "无效的错题 ID" }
    }

    await archiveErrorBookItem(itemId, ctx.userId)

    revalidatePath("/student/error-book")

    return { success: true, message: "错题已归档" }
  } catch (e) {
    if (e instanceof PermissionDeniedError) {
      return { success: false, message: e.message }
    }
    const message = e instanceof Error ? e.message : "归档错题失败"
    return { success: false, message }
  }
}

export async function collectFromSubmissionAction(
  prevState: ActionState<number> | undefined,
  formData: FormData
): Promise<ActionState<number>> {
  try {
    const ctx = await requirePermission(Permissions.ERROR_BOOK_MANAGE)

    const jsonString = formData.get("json")
    if (typeof jsonString !== "string") {
      return { success: false, message: "提交格式错误" }
    }

    const parsed = CollectFromSubmissionSchema.safeParse(JSON.parse(jsonString))
    if (!parsed.success) {
      return {
        success: false,
        message: "输入验证失败",
        errors: parsed.error.flatten().fieldErrors,
      }
    }

    const collected = parsed.data.sourceType === "exam"
      ? await collectFromExamSubmission(parsed.data.submissionId, ctx.userId)
      : await collectFromHomeworkSubmission(parsed.data.submissionId, ctx.userId)

    revalidatePath("/student/error-book")

    return {
      success: true,
      message: collected > 0 ? `已采集 ${collected} 道错题` : "没有新的错题需要采集",
      data: collected,
    }
  } catch (e) {
    if (e instanceof PermissionDeniedError) {
      return { success: false, message: e.message }
    }
    const message = e instanceof Error ? e.message : "采集错题失败"
    return { success: false, message }
  }
}
