import { getTranslations } from "next-intl/server"

import type { AuthContext } from "@/shared/types/permissions"
import type { ClassSubject } from "./types"
import { DEFAULT_CLASS_SUBJECTS } from "./types"
import { ValidationError } from "@/shared/lib/action-utils"

const CLASS_SUBJECT_STRINGS: readonly string[] = DEFAULT_CLASS_SUBJECTS

export const isClassSubject = (v: string): v is ClassSubject => CLASS_SUBJECT_STRINGS.includes(v)

export const isWeekday = (n: number): n is 1 | 2 | 3 | 4 | 5 | 6 | 7 =>
  n >= 1 && n <= 7 && Number.isInteger(n)

export const toWeekday = async (n: number): Promise<1 | 2 | 3 | 4 | 5 | 6 | 7> => {
  if (!isWeekday(n)) {
    const t = await getTranslations("classes")
    throw new ValidationError(t("actions.invalidWeekday"))
  }
  return n
}

/**
 * P1-1: 替代 `ctx.roles.includes("admin")` 硬编码。
 * 通过 dataScope.type === "all" 判断是否拥有 admin 级别的数据访问范围。
 */
export const hasAdminScope = (ctx: AuthContext): boolean => ctx.dataScope.type === "all"

/**
 * P1-1: 替代 `ctx.roles.includes("teacher")` 硬编码。
 * 通过 dataScope.type === "class_taught" 判断是否为教师（有授课班级）。
 */
export const hasTeacherScope = (ctx: AuthContext): boolean => ctx.dataScope.type === "class_taught"

/**
 * P1-1: 替代 `ctx.roles.includes("student")` 硬编码。
 * 通过 dataScope.type === "class_members" 判断是否为学生。
 */
export const hasStudentScope = (ctx: AuthContext): boolean => ctx.dataScope.type === "class_members"

/**
 * 解析表单中的 subjectTeachers JSON 字符串为标准赋值数组。
 * 提取自原 actions.ts，供 admin/grade class 更新逻辑复用。
 *
 * 入参类型直接接受 FormDataEntryValue（string | File），避免在调用方
 * 使用 `as string | null` 强断言（P2-A 修复）。
 */
export const parseSubjectTeachers = async (raw: FormDataEntryValue | null) => {
  if (typeof raw !== "string" || raw.trim().length === 0) return null
  // JSON.parse 返回 any，此处显式拓宽到 unknown 以迫使后续使用类型守卫（合法的 any → unknown 转换）
  const parsed: unknown = JSON.parse(raw)
  if (!Array.isArray(parsed)) {
    const t = await getTranslations("classes")
    throw new ValidationError(t("actions.invalidSubjectTeachers"))
  }

  return parsed.flatMap((item): Array<{ subject: ClassSubject; teacherId: string | null }> => {
    if (!item || typeof item !== "object") return []

    // 使用 `in` 操作符收窄类型，避免 `(item as { x?: unknown }).x` 反模式（P2-A 修复）
    const subject = "subject" in item ? item.subject : undefined
    const teacherId = "teacherId" in item ? item.teacherId : undefined

    if (typeof subject !== "string" || !isClassSubject(subject)) return []

    if (teacherId === null || typeof teacherId === "undefined") {
      return [{ subject, teacherId: null }]
    }

    if (typeof teacherId !== "string") return []
    const trimmed = teacherId.trim()
    return [{ subject, teacherId: trimmed.length > 0 ? trimmed : null }]
  })
}
