import { describe, expect, it } from "vitest";
import {
  filterExpiredJobListings,
  isGoogleJobsHost,
  listingLooksExpired,
  probeJobListingUrl,
  resolveJobListingProbeUrl,
} from "./job-listing-probe.js";

describe("resolveJobListingProbeUrl", () => {
  it("prefers non-Google application links", () => {
    expect(
      resolveJobListingProbeUrl({
        jobUrl: "https://www.google.com/search?q=jobs",
        applicationLink: "https://bebee.com/ca/jobs/example",
      }),
    ).toBe("https://bebee.com/ca/jobs/example");
  });

  it("falls back to jobUrl when apply link is Google", () => {
    expect(
      resolveJobListingProbeUrl({
        jobUrl: "https://boards.greenhouse.io/acme/jobs/1",
        applicationLink: "https://www.google.com/search?q=jobs",
      }),
    ).toBe("https://boards.greenhouse.io/acme/jobs/1");
  });
});

describe("isGoogleJobsHost", () => {
  it("detects google hosts", () => {
    expect(isGoogleJobsHost("https://www.google.com/search?q=x")).toBe(true);
    expect(isGoogleJobsHost("https://www.google.ca/search?q=x")).toBe(true);
    expect(isGoogleJobsHost("https://bebee.com/jobs/1")).toBe(false);
  });
});

describe("listingLooksExpired", () => {
  it("treats 410 and expired body text as expired", () => {
    expect(
      listingLooksExpired({
        status: 410,
        finalUrl: "https://bebee.com/jobs/1",
        body: "Job expired\nThis job listing is no longer available.",
      }),
    ).toBe(true);
  });

  it("keeps healthy 200 pages", () => {
    expect(
      listingLooksExpired({
        status: 200,
        finalUrl: "https://example.com/jobs/1",
        body: "<html><body>Apply now for Software Engineer</body></html>",
      }),
    ).toBe(false);
  });
});

describe("probeJobListingUrl", () => {
  it("marks 410 responses expired", async () => {
    const fetchImpl = async () =>
      ({
        url: "https://bebee.com/jobs/1",
        status: 410,
        text: async () => "Job expired",
      }) as Response;

    const result = await probeJobListingUrl("https://bebee.com/jobs/1", {
      fetchImpl,
    });
    expect(result?.expired).toBe(true);
    expect(result?.status).toBe(410);
  });

  it("returns null on network failure (fail-open)", async () => {
    const fetchImpl = async () => {
      throw new Error("network down");
    };
    const result = await probeJobListingUrl("https://example.com/jobs/1", {
      fetchImpl,
    });
    expect(result).toBeNull();
  });
});

describe("filterExpiredJobListings", () => {
  it("drops expired listings and keeps the rest", async () => {
    const fetchImpl = async (input: RequestInfo | URL) => {
      const url = String(input);
      if (url.includes("dead")) {
        return {
          url,
          status: 410,
          text: async () => "Job expired",
        } as Response;
      }
      return {
        url,
        status: 200,
        text: async () => "Apply now",
      } as Response;
    };

    const { kept, dropped } = await filterExpiredJobListings(
      [
        {
          jobUrl: "https://example.com/alive",
          applicationLink: "https://example.com/alive",
        },
        {
          jobUrl: "https://example.com/dead",
          applicationLink: "https://example.com/dead",
        },
      ],
      { fetchImpl, concurrency: 2 },
    );

    expect(dropped).toBe(1);
    expect(kept).toHaveLength(1);
    expect(kept[0]?.jobUrl).toContain("alive");
  });
});
