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

import {
  assetInputSchema,
  categoryInputSchema,
  projectInputSchema,
  sectionInputSchema,
} from "@/lib/portfolio-validation";

function category(overrides: Record<string, unknown> = {}) {
  return {
    slug: "branding",
    nameAr: "الهوية", nameEn: "Branding", nameDe: "Branding",
    descriptionAr: "وصف", descriptionEn: "Description", descriptionDe: "Beschreibung",
    sortOrder: 1,
    isActive: true,
    ...overrides,
  };
}

function baseMedia(overrides: Record<string, unknown> = {}) {
  return { mode: "external", assetId: "", url: "https://x/y.png", label: "L", kind: "IMAGE", ...overrides };
}

function section(overrides: Record<string, unknown> = {}) {
  return {
    type: "RICH_TEXT",
    titleAr: "ع", titleEn: "t", titleDe: "t",
    bodyAr: "ب", bodyEn: "b", bodyDe: "b",
    imagePath: "",
    linkUrl: "",
    sortOrder: 0,
    ...overrides,
  };
}

function project(overrides: Record<string, unknown> = {}) {
  return {
    categoryId: "cat_1",
    slug: "case-study",
    viewMode: "GRID",
    titleAr: "ع", titleEn: "T", titleDe: "T",
    summaryAr: "م", summaryEn: "S", summaryDe: "S",
    clientName: "Client",
    projectYear: 2025,
    serviceLabelAr: "خ", serviceLabelEn: "Svc", serviceLabelDe: "Svc",
    previewUrl: "https://example.com",
    currentCoverImagePath: "",
    sortOrder: 1,
    isFeatured: false,
    isPublished: true,
    sections: [],
    assets: [],
    ...overrides,
  };
}

describe("categoryInputSchema", () => {
  it("accepts a valid payload", () => {
    expect(categoryInputSchema.parse(category()).slug).toBe("branding");
  });

  it("requires lowercase hyphenated slugs", () => {
    expect(() => categoryInputSchema.parse(category({ slug: "Not Valid" }))).toThrow(/slug/i);
    expect(() => categoryInputSchema.parse(category({ slug: "-leading" }))).toThrow(/slug/i);
    expect(categoryInputSchema.parse(category({ slug: "multi-word-slug" })).slug).toBe("multi-word-slug");
  });

  it("requires all name and description locales", () => {
    expect(() => categoryInputSchema.parse(category({ nameEn: "" }))).toThrow(/nameEn/i);
    expect(() => categoryInputSchema.parse(category({ descriptionDe: "  " }))).toThrow(/descriptionDe/i);
  });

  it("coerces sortOrder and enforces its range", () => {
    expect(categoryInputSchema.parse(category({ sortOrder: "5" })).sortOrder).toBe(5);
    expect(() => categoryInputSchema.parse(category({ sortOrder: 10000 }))).toThrow();
    expect(() => categoryInputSchema.parse(category({ sortOrder: -1 }))).toThrow();
  });
});

describe("sectionInputSchema", () => {
  it("accepts a RICH_TEXT section with body", () => {
    expect(sectionInputSchema.parse(section()).type).toBe("RICH_TEXT");
  });

  it("requires body for RICH_TEXT, STATS and DELIVERABLES", () => {
    for (const type of ["RICH_TEXT", "STATS", "DELIVERABLES"]) {
      expect(() => sectionInputSchema.parse(section({ type, bodyEn: "" }))).toThrow(/body/i);
    }
  });

  it("requires an image for GALLERY sections", () => {
    expect(() =>
      sectionInputSchema.parse(section({ type: "GALLERY", bodyAr: "", bodyEn: "", bodyDe: "", imagePath: "" })),
    ).toThrow(/image/i);
    expect(
      sectionInputSchema.parse(
        section({ type: "GALLERY", bodyAr: "", bodyEn: "", bodyDe: "", imagePath: "/uploads/media/x.svg" }),
      ).type,
    ).toBe("GALLERY");
    expect(
      sectionInputSchema.parse(
        section({ type: "GALLERY", bodyAr: "", bodyEn: "", bodyDe: "", media: baseMedia({ mode: "library", assetId: "a" }) }),
      ).type,
    ).toBe("GALLERY");
  });

  it("requires a link url for LINK sections", () => {
    expect(() =>
      sectionInputSchema.parse(section({ type: "LINK", bodyAr: "", bodyEn: "", bodyDe: "", linkUrl: "" })),
    ).toThrow(/link/i);
    expect(
      sectionInputSchema.parse(section({ type: "LINK", bodyAr: "", bodyEn: "", bodyDe: "", linkUrl: "https://x" })).linkUrl,
    ).toBe("https://x");
  });

  it("rejects malformed link urls", () => {
    expect(() => sectionInputSchema.parse(section({ type: "LINK", linkUrl: "javascript:alert(1)" }))).toThrow(/absolute URL/i);
  });

  it("requires titles in all languages", () => {
    expect(() => sectionInputSchema.parse(section({ titleAr: "" }))).toThrow(/titleAr/i);
  });
});

describe("assetInputSchema", () => {
  it("accepts a valid image asset", () => {
    const parsed = assetInputSchema.parse({
      kind: "IMAGE",
      filePath: "/uploads/media/assets/x.svg",
      fileFieldName: "",
      media: baseMedia(),
      altAr: "ع", altEn: "a", altDe: "a",
      sortOrder: 0,
    });
    expect(parsed.kind).toBe("IMAGE");
  });

  it("only allows the IMAGE kind", () => {
    expect(() =>
      assetInputSchema.parse({ kind: "DOCUMENT", altAr: "ع", altEn: "a", altDe: "a", sortOrder: 0 }),
    ).toThrow();
  });

  it("requires alt text in all languages", () => {
    expect(() =>
      assetInputSchema.parse({ kind: "IMAGE", altAr: "ع", altEn: "", altDe: "a", sortOrder: 0 }),
    ).toThrow(/altEn/i);
  });

  it("rejects invalid embedded media urls", () => {
    expect(() =>
      assetInputSchema.parse({
        kind: "IMAGE",
        media: baseMedia({ url: "not-a-url" }),
        altAr: "ع", altEn: "a", altDe: "a",
        sortOrder: 0,
      }),
    ).toThrow(/url/i);
  });
});

describe("projectInputSchema", () => {
  it("accepts a fully valid project", () => {
    expect(projectInputSchema.parse(project()).slug).toBe("case-study");
  });

  it("defaults viewMode to GRID and accepts known modes", () => {
    expect(projectInputSchema.parse(project({ viewMode: undefined })).viewMode).toBe("GRID");
    expect(projectInputSchema.parse(project({ viewMode: "CASE_STUDY" })).viewMode).toBe("CASE_STUDY");
    expect(() => projectInputSchema.parse(project({ viewMode: "WILD" }))).toThrow();
  });

  it("rejects invalid slugs", () => {
    expect(() => projectInputSchema.parse(project({ slug: "Bad Slug" }))).toThrow(/slug/i);
  });

  it("coerces and bounds projectYear", () => {
    expect(projectInputSchema.parse(project({ projectYear: "2025" })).projectYear).toBe(2025);
    expect(() => projectInputSchema.parse(project({ projectYear: 1999 }))).toThrow();
    expect(() => projectInputSchema.parse(project({ projectYear: 2101 }))).toThrow();
  });

  it("requires all localized content fields", () => {
    expect(() => projectInputSchema.parse(project({ summaryDe: "" }))).toThrow(/summaryDe/i);
    expect(() => projectInputSchema.parse(project({ serviceLabelAr: "" }))).toThrow(/serviceLabelAr/i);
    expect(() => projectInputSchema.parse(project({ clientName: "" }))).toThrow(/clientName/i);
  });

  it("allows an empty preview url but rejects a relative one", () => {
    expect(projectInputSchema.parse(project({ previewUrl: "" })).previewUrl).toBe("");
    expect(() => projectInputSchema.parse(project({ previewUrl: "/relative" }))).toThrow(/absolute URL/i);
  });

  it("validates nested sections and assets", () => {
    expect(() =>
      projectInputSchema.parse(project({ sections: [section({ titleEn: "" })] })),
    ).toThrow(/titleEn/i);
    expect(
      projectInputSchema.parse(
        project({ assets: [{ kind: "IMAGE", altAr: "ع", altEn: "a", altDe: "a", sortOrder: 0, media: baseMedia() }] }),
      ).assets.length,
    ).toBe(1);
  });
});
