import { describe, expect, it } from "vitest"

import { CreateAnnouncementSchema, UpdateAnnouncementSchema } from "./schema"

/**
 * 公告 Schema 校验测试（P2-7）。
 *
 * 重点验证 `refineAudience` 条件校验矩阵：
 * - school 类型：targetGradeId / targetClassId 必须为空
 * - grade 类型：targetGradeId 必填
 * - class 类型：targetClassId 必填
 * - 默认 type="school"
 */
describe("CreateAnnouncementSchema", () => {
  const validSchoolAnnouncement = {
    title: "期末考试安排",
    content: "请各位同学注意考试时间。",
  }

  describe("基础字段校验", () => {
    it("接受最小有效输入（默认 type=school / status=draft）", () => {
      const result = CreateAnnouncementSchema.safeParse(validSchoolAnnouncement)
      expect(result.success).toBe(true)
      if (result.success) {
        expect(result.data.type).toBe("school")
        expect(result.data.status).toBe("draft")
        expect(result.data.targetGradeId).toBeNull()
        expect(result.data.targetClassId).toBeNull()
      }
    })

    it("拒绝空标题", () => {
      const result = CreateAnnouncementSchema.safeParse({
        ...validSchoolAnnouncement,
        title: "  ",
      })
      expect(result.success).toBe(false)
    })

    it("拒绝空内容", () => {
      const result = CreateAnnouncementSchema.safeParse({
        ...validSchoolAnnouncement,
        content: "",
      })
      expect(result.success).toBe(false)
    })

    it("拒绝超过 255 字符的标题", () => {
      const result = CreateAnnouncementSchema.safeParse({
        ...validSchoolAnnouncement,
        title: "a".repeat(256),
      })
      expect(result.success).toBe(false)
    })

    it("拒绝非法 type 枚举值", () => {
      const result = CreateAnnouncementSchema.safeParse({
        ...validSchoolAnnouncement,
        type: "department",
      })
      expect(result.success).toBe(false)
    })

    it("拒绝非法 status 枚举值", () => {
      const result = CreateAnnouncementSchema.safeParse({
        ...validSchoolAnnouncement,
        status: "deleted",
      })
      expect(result.success).toBe(false)
    })
  })

  describe("refineAudience 条件校验", () => {
    it("school 类型 + 无 target：通过", () => {
      const result = CreateAnnouncementSchema.safeParse({
        ...validSchoolAnnouncement,
        type: "school",
      })
      expect(result.success).toBe(true)
    })

    it("school 类型 + 有 targetGradeId：拒绝（path 指向 targetGradeId）", () => {
      const result = CreateAnnouncementSchema.safeParse({
        ...validSchoolAnnouncement,
        type: "school",
        targetGradeId: "grade-1",
      })
      expect(result.success).toBe(false)
      if (!result.success) {
        expect(result.error.issues[0].path).toContain("targetGradeId")
      }
    })

    it("school 类型 + 有 targetClassId：拒绝", () => {
      const result = CreateAnnouncementSchema.safeParse({
        ...validSchoolAnnouncement,
        type: "school",
        targetClassId: "class-1",
      })
      expect(result.success).toBe(false)
    })

    it("grade 类型 + targetGradeId 必填：缺失时拒绝", () => {
      const result = CreateAnnouncementSchema.safeParse({
        ...validSchoolAnnouncement,
        type: "grade",
      })
      expect(result.success).toBe(false)
      if (!result.success) {
        expect(result.error.issues[0].path).toContain("targetGradeId")
      }
    })

    it("grade 类型 + targetGradeId 提供：通过", () => {
      const result = CreateAnnouncementSchema.safeParse({
        ...validSchoolAnnouncement,
        type: "grade",
        targetGradeId: "grade-1",
      })
      expect(result.success).toBe(true)
    })

    it("grade 类型 + 仅空格 targetGradeId：拒绝", () => {
      const result = CreateAnnouncementSchema.safeParse({
        ...validSchoolAnnouncement,
        type: "grade",
        targetGradeId: "   ",
      })
      expect(result.success).toBe(false)
    })

    it("class 类型 + targetClassId 必填：缺失时拒绝", () => {
      const result = CreateAnnouncementSchema.safeParse({
        ...validSchoolAnnouncement,
        type: "class",
      })
      expect(result.success).toBe(false)
      if (!result.success) {
        expect(result.error.issues[0].path).toContain("targetClassId")
      }
    })

    it("class 类型 + targetClassId 提供：通过", () => {
      const result = CreateAnnouncementSchema.safeParse({
        ...validSchoolAnnouncement,
        type: "class",
        targetClassId: "class-1",
      })
      expect(result.success).toBe(true)
    })
  })

  describe("transform 输出归一化", () => {
    it("空字符串 targetGradeId 归一化为 null", () => {
      const result = CreateAnnouncementSchema.safeParse({
        ...validSchoolAnnouncement,
        targetGradeId: "",
      })
      expect(result.success).toBe(true)
      if (result.success) {
        expect(result.data.targetGradeId).toBeNull()
      }
    })

    it("空字符串 targetClassId 归一化为 null", () => {
      const result = CreateAnnouncementSchema.safeParse({
        ...validSchoolAnnouncement,
        targetClassId: "",
      })
      expect(result.success).toBe(true)
      if (result.success) {
        expect(result.data.targetClassId).toBeNull()
      }
    })

    it("空字符串 publishedAt 归一化为 null", () => {
      const result = CreateAnnouncementSchema.safeParse({
        ...validSchoolAnnouncement,
        publishedAt: "",
      })
      expect(result.success).toBe(true)
      if (result.success) {
        expect(result.data.publishedAt).toBeNull()
      }
    })
  })
})

/**
 * UpdateAnnouncementSchema 应复用 refineAudience，
 * 此处仅做最小回归测试，避免 update 路径 schema 漂移。
 */
describe("UpdateAnnouncementSchema", () => {
  it("复用与 Create 相同的 refineAudience 校验规则", () => {
    const gradeResult = UpdateAnnouncementSchema.safeParse({
      title: "更新标题",
      content: "更新内容",
      type: "grade",
    })
    expect(gradeResult.success).toBe(false)

    const validResult = UpdateAnnouncementSchema.safeParse({
      title: "更新标题",
      content: "更新内容",
      type: "class",
      targetClassId: "class-1",
    })
    expect(validResult.success).toBe(true)
  })
})
