import { z } from "zod"

/**
 * 注册输入 Zod 校验。
 *
 * 与 `register-form.tsx` 客户端校验保持一致，但服务端独立校验以防绕过。
 * 包含未成年人监护人字段的条件校验。
 */

const ADULT_AGE = 18

const guardianRelationEnum = z.enum([
  "父亲",
  "母亲",
  "其他法定监护人",
])

export const RegisterSchema = z
  .object({
    name: z
      .string()
      .trim()
      .min(1, "register.nameRequired")
      .max(50, "register.nameMax"),
    email: z
      .string()
      .trim()
      .min(1, "register.emailRequired")
      .email("register.emailInvalid"),
    password: z
      .string()
      .min(8, "register.passwordMin")
      .max(128, "register.passwordMax"),
    birthDate: z
      .string()
      .trim()
      .optional()
      .or(z.literal("")),
    guardianName: z
      .string()
      .trim()
      .max(255, "register.guardianNameMax")
      .optional()
      .or(z.literal("")),
    guardianPhone: z
      .string()
      .trim()
      .max(20, "register.guardianPhoneMax")
      .optional()
      .or(z.literal("")),
    guardianRelation: guardianRelationEnum.optional().or(z.literal("")),
    agreedTerms: z.boolean().refine((v) => v === true, {
      message: "register.consentRequired",
    }),
    agreedGuardian: z.boolean().optional(),
    // audit-P2-3: 邀请码（可选）。提供时使用邀请码中的 role 覆盖默认 student。
    invitationCode: z
      .string()
      .trim()
      .toUpperCase()
      .max(64, "register.invitationCodeMax")
      .optional()
      .or(z.literal("")),
  })
  .superRefine((data, ctx) => {
    if (!data.birthDate) return
    const birthDate = new Date(data.birthDate)
    if (Number.isNaN(birthDate.getTime())) {
      ctx.addIssue({
        code: z.ZodIssueCode.custom,
        path: ["birthDate"],
        message: "register.birthDateInvalid",
      })
      return
    }
    const age = calcAge(data.birthDate)
    if (age === null) return
    if (age < ADULT_AGE) {
      if (!data.guardianName || data.guardianName.length === 0) {
        ctx.addIssue({
          code: z.ZodIssueCode.custom,
          path: ["guardianName"],
          message: "register.guardianNameRequired",
        })
      }
      if (!data.guardianPhone || data.guardianPhone.length === 0) {
        ctx.addIssue({
          code: z.ZodIssueCode.custom,
          path: ["guardianPhone"],
          message: "register.guardianPhoneRequired",
        })
      }
      if (!data.guardianRelation || data.guardianRelation.length === 0) {
        ctx.addIssue({
          code: z.ZodIssueCode.custom,
          path: ["guardianRelation"],
          message: "register.guardianRelationRequired",
        })
      }
      if (!data.agreedGuardian) {
        ctx.addIssue({
          code: z.ZodIssueCode.custom,
          path: ["agreedGuardian"],
          message: "register.guardianConsentRequired",
        })
      }
    }
  })

export type RegisterFormData = z.infer<typeof RegisterSchema>

/** 计算年龄（纯函数，与 register-form.tsx 同步） */
export function calcAge(birth: string): number | null {
  if (!birth) return null
  const birthDate = new Date(birth)
  if (Number.isNaN(birthDate.getTime())) return null
  const now = new Date()
  let age = now.getFullYear() - birthDate.getFullYear()
  const monthDiff = now.getMonth() - birthDate.getMonth()
  if (monthDiff < 0 || (monthDiff === 0 && now.getDate() < birthDate.getDate())) {
    age -= 1
  }
  return age >= 0 ? age : null
}

/** 未成年人判定（与 register-form.tsx 同步） */
export function isMinorByBirthDate(birth: string): boolean {
  const age = calcAge(birth)
  return age !== null && age < ADULT_AGE
}
