"use server"

import { revalidatePath } from "next/cache"
import { requirePermission, PermissionDeniedError } from "@/shared/lib/auth-guard"
import { Permissions } from "@/shared/types/permissions"

import type { ActionState } from "@/shared/types/action-state"
import {
  createAdminClass,
  deleteAdminClass,
  setClassSubjectTeachers,
  updateAdminClass,
} from "./data-access"
import {
  CreateAdminClassSchema,
  UpdateAdminClassSchema,
  DeleteAdminClassSchema,
} from "./schema"
import { parseSubjectTeachers } from "./actions-shared"

export async function createAdminClassAction(
  prevState: ActionState<string> | undefined,
  formData: FormData
): Promise<ActionState<string>> {
  try {
    await requirePermission(Permissions.CLASS_CREATE)

    const parsed = CreateAdminClassSchema.safeParse({
      name: formData.get("name"),
      grade: formData.get("grade"),
      teacherId: formData.get("teacherId"),
      schoolName: formData.get("schoolName"),
      schoolId: formData.get("schoolId"),
      gradeId: formData.get("gradeId"),
      homeroom: formData.get("homeroom"),
      room: formData.get("room"),
    })
    if (!parsed.success) {
      return { success: false, message: "Class name, grade and teacher are required" }
    }

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

    try {
      const id = await createAdminClass({
        schoolName: schoolName ?? null,
        schoolId: schoolId ?? null,
        name,
        grade,
        gradeId: gradeId ?? null,
        teacherId,
        homeroom: homeroom ?? null,
        room: room ?? null,
      })
      revalidatePath("/admin/school/classes")
      revalidatePath("/teacher/classes/my")
      revalidatePath("/teacher/classes/students")
      revalidatePath("/teacher/classes/schedule")
      return { success: true, message: "Class created successfully", data: id }
    } catch (error) {
      return { success: false, message: error instanceof Error ? error.message : "Failed to create class" }
    }
  } catch (e) {
    if (e instanceof PermissionDeniedError) return { success: false, message: e.message }
    throw e
  }
}

export async function updateAdminClassAction(
  classId: string,
  prevState: ActionState | undefined,
  formData: FormData
): Promise<ActionState> {
  try {
    await requirePermission(Permissions.CLASS_UPDATE)

    const parsed = UpdateAdminClassSchema.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: "Missing class id" }
    }

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

    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("/admin/school/classes")
      revalidatePath("/teacher/classes/my")
      revalidatePath("/teacher/classes/students")
      revalidatePath("/teacher/classes/schedule")
      return { success: true, message: "Class updated successfully" }
    } catch (error) {
      return { success: false, message: error instanceof Error ? error.message : "Failed to update class" }
    }
  } catch (e) {
    if (e instanceof PermissionDeniedError) return { success: false, message: e.message }
    throw e
  }
}

export async function deleteAdminClassAction(classId: string): Promise<ActionState> {
  try {
    await requirePermission(Permissions.CLASS_DELETE)

    const parsed = DeleteAdminClassSchema.safeParse({ classId })
    if (!parsed.success) {
      return { success: false, message: "Missing class id" }
    }

    try {
      await deleteAdminClass(parsed.data.classId)
      revalidatePath("/admin/school/classes")
      revalidatePath("/teacher/classes/my")
      revalidatePath("/teacher/classes/students")
      revalidatePath("/teacher/classes/schedule")
      return { success: true, message: "Class deleted successfully" }
    } catch (error) {
      return { success: false, message: error instanceof Error ? error.message : "Failed to delete class" }
    }
  } catch (e) {
    if (e instanceof PermissionDeniedError) return { success: false, message: e.message }
    throw e
  }
}
