"use server"

import { revalidatePath } from "next/cache"
import { getTranslations } from "next-intl/server"
import { requirePermission } from "@/shared/lib/auth-guard"
import { handleActionError } from "@/shared/lib/action-utils"
import { Permissions } from "@/shared/types/permissions"

import type { ActionState } from "@/shared/types/action-state"
import {
  createAdminClass,
  deleteAdminClass,
  getClassGradeId,
  setClassSubjectTeachers,
  updateAdminClass,
} from "./data-access"
import { isGradeManager } from "@/modules/school/data-access"
import {
  CreateGradeClassSchema,
  UpdateGradeClassSchema,
  DeleteGradeClassSchema,
} from "./schema"
import { parseSubjectTeachers } from "./actions-shared"

export async function createGradeClassAction(
  prevState: ActionState<string> | undefined,
  formData: FormData
): Promise<ActionState<string>> {
  try {
    const ctx = await requirePermission(Permissions.CLASS_CREATE)
    const t = await getTranslations("classes")

    const parsed = CreateGradeClassSchema.safeParse({
      name: formData.get("name"),
      gradeId: formData.get("gradeId"),
      teacherId: formData.get("teacherId"),
      schoolName: formData.get("schoolName"),
      schoolId: formData.get("schoolId"),
      grade: formData.get("grade"),
      homeroom: formData.get("homeroom"),
      room: formData.get("room"),
    })
    if (!parsed.success) {
      return { success: false, message: t("actions.classNameGradeTeacherRequired") }
    }

    const { name, gradeId, teacherId, schoolName, schoolId, grade, homeroom, room } = parsed.data

    // Verify access
    const isManager = await isGradeManager(gradeId, ctx.userId)
    if (!isManager) {
      return { success: false, message: t("actions.notPermissionCreateGrade") }
    }

    try {
      const id = await createAdminClass({
        schoolName: schoolName ?? null,
        schoolId: schoolId ?? null,
        name,
        grade: grade ?? "", // Should be passed from UI based on selected grade
        gradeId,
        teacherId,
        homeroom: homeroom ?? null,
        room: room ?? null,
      })
      revalidatePath("/management/grade/classes")
      return { success: true, message: t("actions.classCreated"), data: id }
    } catch (error) {
      return handleActionError(error)
    }
  } catch (e) {
    return handleActionError(e)
  }
}

export async function updateGradeClassAction(
  classId: string,
  prevState: ActionState | undefined,
  formData: FormData
): Promise<ActionState> {
  try {
    const ctx = await requirePermission(Permissions.CLASS_UPDATE)
    const t = await getTranslations("classes")

    const parsed = UpdateGradeClassSchema.safeParse({
      classId,
      schoolName: formData.get("schoolName"),
      schoolId: formData.get("schoolId"),
      name: formData.get("name"),
      grade: formData.get("grade"),
      gradeId: formData.get("gradeId"),
      teacherId: formData.get("teacherId"),
      homeroom: formData.get("homeroom"),
      room: formData.get("room"),
    })
    if (!parsed.success) {
      return { success: false, message: t("actions.missingClassId") }
    }

    const { classId: validatedClassId, schoolName, schoolId, name, grade, gradeId, teacherId, homeroom, room } = parsed.data
    const subjectTeachers = await parseSubjectTeachers(formData.get("subjectTeachers"))

    // Verify access: Check if the class belongs to a managed grade
    const classGradeId = await getClassGradeId(validatedClassId)
    if (!classGradeId) {
      return { success: false, message: t("actions.classNotFoundOrNotLinked") }
    }

    const isManager = await isGradeManager(classGradeId, ctx.userId)
    if (!isManager) {
      return { success: false, message: t("actions.notPermissionUpdateClass") }
    }

    // If changing gradeId, verify target grade too
    if (typeof gradeId === "string" && gradeId !== classGradeId) {
      const isTargetManager = await isGradeManager(gradeId, ctx.userId)
      if (!isTargetManager) {
        return { success: false, message: t("actions.notPermissionMoveClass") }
      }
    }

    try {
      await updateAdminClass(validatedClassId, {
        schoolName: schoolName ?? undefined,
        schoolId: schoolId ?? undefined,
        name: name ?? undefined,
        grade: grade ?? undefined,
        gradeId: gradeId ?? undefined,
        teacherId: teacherId ?? undefined,
        homeroom: homeroom ?? undefined,
        room: room ?? undefined,
      })

      if (subjectTeachers) {
        await setClassSubjectTeachers({
          classId: validatedClassId,
          assignments: subjectTeachers,
        })
      }

      revalidatePath("/management/grade/classes")
      return { success: true, message: t("actions.classUpdated") }
    } catch (error) {
      return handleActionError(error)
    }
  } catch (e) {
    return handleActionError(e)
  }
}

export async function deleteGradeClassAction(classId: string): Promise<ActionState> {
  try {
    const ctx = await requirePermission(Permissions.CLASS_DELETE)
    const t = await getTranslations("classes")

    const parsed = DeleteGradeClassSchema.safeParse({ classId })
    if (!parsed.success) {
      return { success: false, message: t("actions.missingClassId") }
    }

    const { classId: validatedClassId } = parsed.data

    // Verify access
    const classGradeId = await getClassGradeId(validatedClassId)
    if (!classGradeId) {
      return { success: false, message: t("actions.classNotFoundOrNotLinked") }
    }

    const isManager = await isGradeManager(classGradeId, ctx.userId)
    if (!isManager) {
      return { success: false, message: t("actions.notPermissionDeleteClass") }
    }

    try {
      await deleteAdminClass(validatedClassId)
      revalidatePath("/management/grade/classes")
      return { success: true, message: t("actions.classDeleted") }
    } catch (error) {
      return handleActionError(error)
    }
  } catch (e) {
    return handleActionError(e)
  }
}
