"use server"

import { revalidatePath } from "next/cache"
import type { ActionState } from "@/shared/types/action-state"
import { requirePermission } from "@/shared/lib/auth-guard"
import { handleActionError } from "@/shared/lib/action-utils"
import { Permissions } from "@/shared/types/permissions"
import { z } from "zod"

import {
  recordProctoringEvent,
  getExamSubmissionForProctoring,
  getExamProctoringSummary,
  getStudentProctoringStatuses,
  getRecentProctoringEvents,
  getExamForProctoring,
} from "./data-access"
import type { ProctoringDashboardData } from "./types"

const ProctoringEventSchema = z.object({
  submissionId: z.string().min(1),
  examId: z.string().min(1),
  eventType: z.enum([
    "tab_switch",
    "window_blur",
    "copy_attempt",
    "paste_attempt",
    "right_click",
    "devtools_open",
    "fullscreen_exit",
    "idle_timeout",
  ]),
  eventDetail: z.string().optional(),
})

const failState = <T>(message: string): ActionState<T> => ({
  success: false,
  message,
})

const successState = <T>(data: T, message?: string): ActionState<T> => ({
  success: true,
  message,
  data,
})

/**
 * 学生端上报监考事件
 * 需要 EXAM_SUBMIT 权限（学生上报自己的事件）
 */
export async function recordProctoringEventAction(
  prevState: ActionState<{ id: string }> | null,
  formData: FormData,
): Promise<ActionState<{ id: string }>> {
  try {
    const ctx = await requirePermission(Permissions.EXAM_SUBMIT)

    const parsed = ProctoringEventSchema.safeParse({
      submissionId: formData.get("submissionId"),
      examId: formData.get("examId"),
      eventType: formData.get("eventType"),
      eventDetail: formData.get("eventDetail") ?? undefined,
    })

    if (!parsed.success) {
      return failState<{ id: string }>(
        parsed.error.issues[0]?.message ?? "Invalid event payload",
      )
    }

    // 安全校验：submission 必须属于当前学生
    const submission = await getExamSubmissionForProctoring(
      parsed.data.submissionId,
      ctx.userId,
    )
    if (!submission) {
      return failState<{ id: string }>("Submission not found for current user")
    }

    const event = await recordProctoringEvent({
      submissionId: parsed.data.submissionId,
      studentId: ctx.userId,
      examId: parsed.data.examId,
      eventType: parsed.data.eventType,
      eventDetail: parsed.data.eventDetail,
    })

    revalidatePath(`/teacher/exams/${parsed.data.examId}/proctoring`)

    return successState({ id: event.id }, "Event recorded")
  } catch (error) {
    return handleActionError(error)
  }
}

/**
 * 获取监考面板数据（教师/管理员使用）
 * 需要 EXAM_PROCTOR 权限
 */
export async function getProctoringDashboardAction(
  examId: string,
): Promise<ActionState<ProctoringDashboardData>> {
  try {
    await requirePermission(Permissions.EXAM_PROCTOR)

    if (!examId) {
      return failState<ProctoringDashboardData>("Exam ID is required")
    }

    const exam = await getExamForProctoring(examId)
    if (!exam) {
      return failState<ProctoringDashboardData>("Exam not found")
    }

    const [summary, students, recentEvents] = await Promise.all([
      getExamProctoringSummary(examId),
      getStudentProctoringStatuses(examId),
      getRecentProctoringEvents(examId, 20),
    ])

    return successState<ProctoringDashboardData>({
      summary,
      students,
      recentEvents,
    })
  } catch (error) {
    return handleActionError(error)
  }
}
