import { expect, test } from "bun:test";
import {
  coverageOf,
  seedTargets,
  setCell,
  setForSelected,
  TARGET_COUNTRIES,
  type TargetsState,
} from "./targets";
import type { Keyword } from "./types";

function kw(id: string): Keyword {
  return {
    id,
    siteId: "s1",
    term: id,
    locale: { lang: "en", country: "US" },
    theme: "lab-diamonds",
    status: "idea",
    intent: ["informational"],
    stages: [],
    primarySource: "mangools",
    sources: ["mangools"],
    metrics: {},
    trend: [],
    briefs: {},
    gsc: null,
    gscByCountry: {},
    enrichmentExports: {},
  };
}

test("TARGET_COUNTRIES are US, GB, CA, AU", () => {
  expect(TARGET_COUNTRIES.map((c) => c.code)).toEqual(["US", "GB", "CA", "AU"]);
});

test("seedTargets is deterministic for the same input", () => {
  const ks = ["a", "b", "c", "d", "e"].map(kw);
  expect(seedTargets(ks)).toEqual(seedTargets(ks));
});

test("seedTargets covers at least one keyword", () => {
  const ks = ["a", "b", "c", "d", "e"].map(kw);
  const state = seedTargets(ks);
  expect(Object.keys(state).length).toBeGreaterThan(0);
});

test("setCell adds, updates, and removes a target", () => {
  let s: TargetsState = {};
  s = setCell(s, "a", "US", "candidate");
  expect(s.a.US).toBe("candidate");
  s = setCell(s, "a", "US", "planned");
  expect(s.a.US).toBe("planned");
  s = setCell(s, "a", "US", null);
  expect(s.a).toBeUndefined(); // last country removed -> keyword entry dropped
});

test("setForSelected creates candidates for each keyword x country", () => {
  const s = setForSelected({}, ["a", "b"], ["US", "CA"]);
  expect(s.a).toEqual({ US: "candidate", CA: "candidate" });
  expect(s.b).toEqual({ US: "candidate", CA: "candidate" });
});

test("setForSelected does not downgrade a more-advanced status", () => {
  let s = setCell({}, "a", "US", "live");
  s = setForSelected(s, ["a"], ["US", "CA"]); // candidate
  expect(s.a.US).toBe("live"); // preserved
  expect(s.a.CA).toBe("candidate"); // new
});

test("coverageOf returns covered countries in the given country order", () => {
  const s = setForSelected({}, ["a"], ["CA", "US"]);
  expect(coverageOf(s, "a", ["US", "CA"])).toEqual([
    { country: "US", status: "candidate" },
    { country: "CA", status: "candidate" },
  ]);
  expect(coverageOf(s, "missing", ["US", "CA"])).toEqual([]);
});

test("coverageOf hides targets outside the given countries (legacy proto)", () => {
  const s = setForSelected({}, ["a"], ["US", "FR"]);
  // FR-only site: the legacy US target must not appear.
  expect(coverageOf(s, "a", ["FR"])).toEqual([
    { country: "FR", status: "candidate" },
  ]);
});
