"use server"

import { requirePermission, PermissionDeniedError } 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,
  getKnowledgePointOptions,
  getQuestions,
  updateQuestionById,
  type GetQuestionsParams,
} from "./data-access"
import type { KnowledgePointOption } from "./types"

/** 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 = JSON.parse(jsonString) as unknown
      } 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

    await createQuestionWithRelations(input, ctx.userId)

    revalidatePath("/teacher/questions")

    return {
      success: true,
      message: "Question created successfully",
    }
  } catch (e) {
    if (e instanceof PermissionDeniedError) {
      return { success: false, message: e.message }
    }
    if (e instanceof Error) {
      return {
        success: false,
        message: e.message || "Database error occurred",
      }
    }

    return {
      success: false,
      message: "An unexpected error occurred",
    }
  }
}

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.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(JSON.parse(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)

    revalidatePath("/teacher/questions")

    return { success: true, message: "Question updated successfully" }
  } catch (e) {
    if (e instanceof PermissionDeniedError) {
      return { success: false, message: e.message }
    }
    if (e instanceof Error) {
      return { success: false, message: e.message }
    }
    return { success: false, message: "An unexpected error occurred" }
  }
}

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)

    revalidatePath("/teacher/questions")

    return { success: true, message: "Question deleted successfully" }
  } catch (e) {
    if (e instanceof PermissionDeniedError) {
      return { success: false, message: e.message }
    }
    if (e instanceof Error) {
      return { success: false, message: e.message }
    }
    return { success: false, message: "Failed to delete question" }
  }
}

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) {
    if (e instanceof PermissionDeniedError) {
      return { success: false, message: e.message }
    }
    const message = e instanceof Error ? e.message : "Failed to fetch questions"
    return { success: false, message }
  }
}

export async function getKnowledgePointOptionsAction(): Promise<
  ActionState<KnowledgePointOptionsResult>
> {
  try {
    await requirePermission(Permissions.QUESTION_READ)
    const data = await getKnowledgePointOptions()
    return { success: true, data }
  } catch (e) {
    if (e instanceof PermissionDeniedError) {
      return { success: false, message: e.message }
    }
    const message = e instanceof Error ? e.message : "Failed to fetch knowledge point options"
    return { success: false, message }
  }
}
