import { createJob } from "@shared/testing/factories";
import type { Job } from "@shared/types";
import { renderHook } from "@testing-library/react";
import { describe, expect, it } from "vitest";
import { useFilteredJobs } from "./useFilteredJobs";

const baseJob = createJob({
  id: "job-1",
  source: "linkedin",
  title: "Engineer",
  employer: "Acme",
  location: "London",
  jobDescription: "Desc",
  status: "ready",
});

describe("useFilteredJobs", () => {
  it("keeps processing jobs visible in the all jobs tab", () => {
    const jobs: Job[] = [
      { ...baseJob, id: "in-progress", status: "in_progress" },
      { ...baseJob, id: "processing", status: "processing" },
      {
        ...baseJob,
        id: "closed",
        status: "in_progress",
        closedAt: 1741996800,
      },
    ];

    const { result } = renderHook(() =>
      useFilteredJobs(
        jobs,
        "all",
        "all",
        "all",
        { mode: "at_least", min: null, max: null },
        {
          key: "score",
          direction: "desc",
        },
      ),
    );

    expect(result.current.map((job) => job.id)).toEqual([
      "in-progress",
      "processing",
    ]);
  });

  it("keeps processing jobs visible in the ready tab", () => {
    const jobs: Job[] = [
      { ...baseJob, id: "ready", status: "ready" },
      { ...baseJob, id: "processing", status: "processing" },
      { ...baseJob, id: "discovered", status: "discovered" },
    ];

    const { result } = renderHook(() =>
      useFilteredJobs(
        jobs,
        "ready",
        "all",
        "all",
        { mode: "at_least", min: null, max: null },
        {
          key: "score",
          direction: "desc",
        },
      ),
    );

    expect(result.current.map((job) => job.id)).toEqual(
      expect.arrayContaining(["ready", "processing"]),
    );
    expect(result.current).toHaveLength(2);
  });

  it("filters by sponsor status categories", () => {
    const jobs: Job[] = [
      { ...baseJob, id: "confirmed", sponsorMatchScore: 99 },
      { ...baseJob, id: "potential", sponsorMatchScore: 82 },
      { ...baseJob, id: "not-found", sponsorMatchScore: 45 },
      { ...baseJob, id: "unknown", sponsorMatchScore: null },
    ];

    const { result } = renderHook(() =>
      useFilteredJobs(
        jobs,
        "all",
        "all",
        "confirmed",
        { mode: "at_least", min: null, max: null },
        {
          key: "score",
          direction: "desc",
        },
      ),
    );

    expect(result.current.map((job) => job.id)).toEqual(["confirmed"]);
  });

  it("filters by salary range using structured and text salary fields", () => {
    const jobs: Job[] = [
      { ...baseJob, id: "structured", salaryMinAmount: 70000 },
      { ...baseJob, id: "k-format", salary: "GBP 65k" },
      { ...baseJob, id: "below", salary: "GBP 55k" },
      { ...baseJob, id: "none", salary: null },
    ];

    const { result } = renderHook(() =>
      useFilteredJobs(
        jobs,
        "all",
        "all",
        "all",
        { mode: "between", min: 60000, max: 80000 },
        {
          key: "score",
          direction: "desc",
        },
      ),
    );

    expect(result.current.map((job) => job.id)).toEqual(
      expect.arrayContaining(["structured", "k-format"]),
    );
    expect(result.current).toHaveLength(2);
  });

  it("sorts by salary with highest first and missing salaries last", () => {
    const jobs: Job[] = [
      { ...baseJob, id: "max", salaryMinAmount: 120000 },
      { ...baseJob, id: "mid", salary: "GBP 65k" },
      { ...baseJob, id: "low", salaryMinAmount: 50000 },
      { ...baseJob, id: "none", salary: null, salaryMinAmount: null },
    ];

    const { result } = renderHook(() =>
      useFilteredJobs(
        jobs,
        "all",
        "all",
        "all",
        { mode: "at_least", min: null, max: null },
        {
          key: "salary",
          direction: "desc",
        },
      ),
    );

    expect(result.current.map((job) => job.id)).toEqual([
      "max",
      "mid",
      "low",
      "none",
    ]);
  });
});
