import { describe, expect, it } from "vitest";
import {
  buildJobContentFingerprint,
  buildJobDescriptionFingerprint,
  collectJobDedupKeys,
  employersMatchForDismiss,
  jobsMatchEmployerAndTitleDismiss,
  normalizeEmployerForFingerprint,
  normalizeTitleForFingerprint,
  titlesMatchForDismiss,
} from "./job-fingerprint";

describe("buildJobContentFingerprint", () => {
  it("collapses the same role across sources", () => {
    const a = buildJobContentFingerprint({
      employer: "Stripe, Inc.",
      title: "Senior Software Engineer (Backend) - Toronto, ON",
    });
    const b = buildJobContentFingerprint({
      employer: "stripe inc",
      title: "Senior Software Engineer  (Backend)",
    });
    expect(a).toBe(b);
    expect(a).not.toBeNull();
  });

  it("ignores trailing location decorations on titles", () => {
    const a = buildJobContentFingerprint({
      employer: "Acme",
      title: "Software Engineer — Remote",
    });
    const b = buildJobContentFingerprint({
      employer: "Acme",
      title: "Software Engineer",
    });
    expect(a).toBe(b);
  });

  it("strips diacritics and punctuation", () => {
    const a = buildJobContentFingerprint({
      employer: "Café Münchën",
      title: "Étudiant – Stage",
    });
    const b = buildJobContentFingerprint({
      employer: "cafe munchen",
      title: "Etudiant Stage",
    });
    expect(a).toBe(b);
  });

  it("returns null when employer or title is empty", () => {
    expect(
      buildJobContentFingerprint({ employer: "", title: "Engineer" }),
    ).toBeNull();
    expect(
      buildJobContentFingerprint({ employer: "Acme", title: "" }),
    ).toBeNull();
  });

  it("does not collapse different roles at the same employer", () => {
    const a = buildJobContentFingerprint({
      employer: "Acme",
      title: "Software Engineer",
    });
    const b = buildJobContentFingerprint({
      employer: "Acme",
      title: "Product Designer",
    });
    expect(a).not.toBe(b);
  });

  it("matches reposts with the same employer and description body", () => {
    const description =
      "We are hiring an Automation Test Engineer to build scalable test frameworks. ".repeat(
        4,
      );
    const a = buildJobDescriptionFingerprint({
      employer: "Joveo",
      jobDescription: description,
    });
    const b = buildJobDescriptionFingerprint({
      employer: "Joveo",
      jobDescription: description,
    });
    expect(a).toBe(b);
    expect(
      collectJobDedupKeys({
        employer: "Joveo",
        title: "SDET",
        jobDescription: description,
      }),
    ).toContain(a);
  });

  describe("normalizers", () => {
    it("normalizeEmployerForFingerprint strips legal suffixes", () => {
      expect(normalizeEmployerForFingerprint("Acme Corporation")).toBe("acme");
      expect(normalizeEmployerForFingerprint("Acme, LLC")).toBe("acme");
      expect(normalizeEmployerForFingerprint("Acme GmbH")).toBe("acme");
    });

    it("normalizeEmployerForFingerprint strips leading punctuation", () => {
      expect(normalizeEmployerForFingerprint(". CGI IT UK Limited")).toBe(
        "cgiituklimited",
      );
    });

    it("normalizeTitleForFingerprint drops leading repost markers", () => {
      expect(normalizeTitleForFingerprint("[Reposted] Software Engineer")).toBe(
        "softwareengineer",
      );
    });
  });

  describe("prior skip dismiss matching", () => {
    it("employersMatchForDismiss allows prefix matches", () => {
      expect(
        employersMatchForDismiss("cgi", normalizeEmployerForFingerprint("CGI")),
      ).toBe(true);
      expect(
        employersMatchForDismiss(
          normalizeEmployerForFingerprint("CGI IT UK Limited"),
          normalizeEmployerForFingerprint("CGI"),
        ),
      ).toBe(true);
    });

    it("titlesMatchForDismiss allows plural variants", () => {
      expect(
        titlesMatchForDismiss(
          normalizeTitleForFingerprint("Automation Test Engineer"),
          normalizeTitleForFingerprint("Automation Test Engineers"),
        ),
      ).toBe(true);
    });

    it("jobsMatchEmployerAndTitleDismiss requires same title family", () => {
      expect(
        jobsMatchEmployerAndTitleDismiss({
          employerA: "CGI IT UK Limited",
          titleA: "Automation Test Engineers",
          employerB: "CGI",
          titleB: "Automation Test Engineer",
        }),
      ).toBe(true);
      expect(
        jobsMatchEmployerAndTitleDismiss({
          employerA: "Cognizant",
          titleA: "AI Automation Test Engineer",
          employerB: "Cognizant",
          titleB: "Automation Test Engineer",
        }),
      ).toBe(false);
    });
  });
});
