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

import {
  articleInputSchema,
  confirmedFactCardSchema,
  candidateFactCardSchema,
  qaReportSchema,
} from "../validation";

describe("domain validation", () => {
  it("accepts article input with title, body, images, platform, and instructions", () => {
    const parsed = articleInputSchema.parse({
      title: "How GEO Optimization Improves Brand Visibility",
      body: "A practical overview of GEO optimization for marketing teams.",
      images: [
        { type: "description", content: "Dashboard screenshot" },
        { type: "link", content: "https://example.com/image.png" },
      ],
      platform: "official_site",
      user_instructions: "Keep the article factual and concise.",
    });

    expect(parsed.images).toHaveLength(2);
    expect(parsed.platform).toBe("official_site");
  });

  it("marks a fact card with unresolved uncertain items as not ready for optimization", () => {
    const parsed = candidateFactCardSchema.parse({
      company_full_name: "Example Technology Co., Ltd.",
      company_short_names: ["Example Tech"],
      brand_names: ["Example"],
      product_names: ["Example GEO"],
      target_industry: "GEO optimization",
      target_audience: "Marketing teams",
      experience_years: 8,
      core_claims: ["Eight years of GEO optimization experience"],
      forbidden_claims: [],
      image_topics: ["Product dashboard"],
      uncertain_items: ["Conflicting product names found"],
    });

    expect(parsed.is_ready_for_optimization).toBe(false);
  });

  it("normalizes near-valid LLM fact card field types", () => {
    const emptyExperience = candidateFactCardSchema.parse({
      company_full_name: "Example Technology Co., Ltd.",
      company_short_names: ["Example Tech"],
      brand_names: ["Example"],
      product_names: ["Example GEO"],
      target_industry: "GEO optimization",
      target_audience: ["Marketing teams", "Brand teams"],
      experience_years: "",
      core_claims: ["GEO optimization experience"],
      forbidden_claims: [],
      image_topics: [],
      uncertain_items: [],
    });

    const numericExperience = candidateFactCardSchema.parse({
      company_full_name: "Example Technology Co., Ltd.",
      company_short_names: ["Example Tech"],
      brand_names: ["Example"],
      product_names: ["Example GEO"],
      target_industry: "GEO optimization",
      target_audience: "Marketing teams",
      experience_years: "8年",
      core_claims: ["GEO optimization experience"],
      forbidden_claims: [],
      image_topics: [],
      uncertain_items: [],
    });

    expect(emptyExperience.target_audience).toBe("Marketing teams、Brand teams");
    expect(emptyExperience.experience_years).toBeNull();
    expect(numericExperience.experience_years).toBe(8);
  });

  it("keeps incomplete candidate fact cards editable and ready", () => {
    const parsed = candidateFactCardSchema.parse({
      company_full_name: "",
      company_short_names: [],
      brand_names: [],
      product_names: [],
      target_industry: "",
      target_audience: "",
      experience_years: "",
      core_claims: [],
      forbidden_claims: [],
      image_topics: [],
      uncertain_items: [],
    });

    expect(parsed.target_industry).toBe("");
    expect(parsed.target_audience).toBe("");
    expect(parsed.experience_years).toBeNull();
    expect(parsed.uncertain_items).toEqual([]);
    expect(parsed.is_ready_for_optimization).toBe(true);
  });

  it("rejects a confirmed fact card with an empty company full name", () => {
    expect(() =>
      confirmedFactCardSchema.parse({
        company_full_name: "",
        company_short_names: ["Example"],
        brand_names: ["Example"],
        product_names: ["Example GEO"],
        target_industry: "GEO optimization",
        target_audience: "Marketing teams",
        experience_years: 8,
        core_claims: ["Eight years of GEO optimization experience"],
        forbidden_claims: [],
        image_topics: [],
        uncertain_items: [],
        confirmed_by_user: true,
      }),
    ).toThrow();
  });

  it("accepts QA reports only with pass, warn, or fail statuses", () => {
    const valid = qaReportSchema.parse({
      job_id: "job_123",
      revision: 1,
      overall_status: "warn",
      checks: [
        {
          rule_id: "title_quality",
          status: "pass",
          evidence: "Title reads naturally.",
          reason: "No grammar issue detected.",
          suggested_fix: "",
          target_agent: null,
        },
      ],
    });

    expect(valid.checks[0]?.status).toBe("pass");
    expect(() =>
      qaReportSchema.parse({
        job_id: "job_123",
        revision: 1,
        overall_status: "blocked",
        checks: [],
      }),
    ).toThrow();
  });
});
