"use server"

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

import type { ActionState } from "@/shared/types/action-state"
import { handleActionError } from "@/shared/lib/action-utils"
import {
  createClassScheduleItem,
  updateClassScheduleItem,
  deleteClassScheduleItem,
} from "@/modules/scheduling/data-access-class-schedule"
import {
  CreateClassScheduleItemSchema,
  UpdateClassScheduleItemSchema,
  DeleteClassScheduleItemSchema,
} from "./schema"
import { hasAdminScope, toWeekday } from "./actions-shared"
import { verifyTeacherOwnsClass } from "./data-access"
import { getClassIdByScheduleId } from "./data-access-schedule"

/**
 * 校验当前用户对班级的归属权限（P0-3 审计修复）。
 * - admin scope：跳过校验（管理员可管理任意班级）
 * - 其他用户：必须为该班级的班主任
 * 返回 null 表示通过，返回 string 表示错误消息。
 */
async function assertClassOwnership(
  ctx: Parameters<typeof hasAdminScope>[0],
  classId: string,
  t: (key: string) => string
): Promise<string | null> {
  if (hasAdminScope(ctx)) return null
  const owns = await verifyTeacherOwnsClass(classId, ctx.userId)
  return owns ? null : t("actions.notPermissionManageClassSchedule")
}

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

    const parsed = CreateClassScheduleItemSchema.safeParse({
      classId: formData.get("classId"),
      weekday: formData.get("weekday"),
      course: formData.get("course"),
      startTime: formData.get("startTime"),
      endTime: formData.get("endTime"),
      location: formData.get("location"),
    })
    if (!parsed.success) {
      return { success: false, message: t("actions.invalidScheduleData") }
    }

    const { classId, weekday, course, startTime, endTime, location } = parsed.data

    // P0-3: 越权校验——防止教师为他班添加课表
    const ownErr = await assertClassOwnership(ctx, classId, t)
    if (ownErr) return { success: false, message: ownErr }

    try {
      const id = await createClassScheduleItem({
        classId,
        weekday: await toWeekday(weekday),
        startTime,
        endTime,
        course,
        location: location ?? null,
      })
      revalidatePath("/teacher/classes/schedule")
      return { success: true, message: t("actions.scheduleItemCreated"), data: id }
    } catch (error) {
      return handleActionError(error)
    }
  } catch (e) {
    return handleActionError(e)
  }
}

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

    const parsed = UpdateClassScheduleItemSchema.safeParse({
      scheduleId,
      classId: formData.get("classId"),
      weekday: formData.get("weekday") || undefined,
      course: formData.get("course"),
      startTime: formData.get("startTime"),
      endTime: formData.get("endTime"),
      location: formData.get("location"),
    })
    if (!parsed.success) {
      return { success: false, message: t("actions.missingScheduleId") }
    }

    const { scheduleId: validatedScheduleId, classId, weekday, course, startTime, endTime, location } = parsed.data

    // P0-3: 越权校验——更新时需校验目标班级归属
    // 优先用表单传入的 classId，否则从已有 schedule item 反查 classId
    const targetClassId = typeof classId === "string" && classId.trim()
      ? classId
      : await getClassIdByScheduleId(validatedScheduleId)
    if (!targetClassId) {
      return { success: false, message: t("actions.scheduleItemNotFound") }
    }
    const ownErr = await assertClassOwnership(ctx, targetClassId, t)
    if (ownErr) return { success: false, message: ownErr }

    try {
      await updateClassScheduleItem(validatedScheduleId, {
        classId: classId ?? undefined,
        weekday: typeof weekday === "number" ? await toWeekday(weekday) : undefined,
        startTime: startTime ?? undefined,
        endTime: endTime ?? undefined,
        course: course ?? undefined,
        location: location ?? undefined,
      })
      revalidatePath("/teacher/classes/schedule")
      return { success: true, message: t("actions.scheduleItemUpdated") }
    } catch (error) {
      return handleActionError(error)
    }
  } catch (e) {
    return handleActionError(e)
  }
}

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

    const parsed = DeleteClassScheduleItemSchema.safeParse({ scheduleId })
    if (!parsed.success) {
      return { success: false, message: t("actions.missingScheduleId") }
    }

    // P0-3: 越权校验——删除时需校验该 schedule item 所属班级归属
    const targetClassId = await getClassIdByScheduleId(parsed.data.scheduleId)
    if (!targetClassId) {
      return { success: false, message: t("actions.scheduleItemNotFound") }
    }
    const ownErr = await assertClassOwnership(ctx, targetClassId, t)
    if (ownErr) return { success: false, message: ownErr }

    try {
      await deleteClassScheduleItem(parsed.data.scheduleId)
      revalidatePath("/teacher/classes/schedule")
      return { success: true, message: t("actions.scheduleItemDeleted") }
    } catch (error) {
      return handleActionError(error)
    }
  } catch (e) {
    return handleActionError(e)
  }
}
