import { expect, test } from "bun:test";
import {
  countryForLang,
  countryToConfiguredLang,
  localeSegmentLang,
  resolveGscCountry,
  resolveQueryLanguages,
} from "./language";
import type { GscQueryRow } from "./types";

const row = (query: string): GscQueryRow => ({
  query,
  clicks: 0,
  impressions: 1,
  ctr: 0,
  position: 1,
});

test("localeSegmentLang matches a configured locale path segment", () => {
  expect(localeSegmentLang("https://x.com/en/guide", ["fr", "en"])).toBe("en");
  expect(localeSegmentLang("https://x.com/fr/blog/a", ["fr", "en"])).toBe("fr");
  // root-served (no locale segment) → no URL signal
  expect(localeSegmentLang("https://x.com/blog/a", ["fr", "en"])).toBeNull();
  // segment present but not configured → no match
  expect(localeSegmentLang("https://x.com/de/seite", ["fr", "en"])).toBeNull();
});

test("countryToConfiguredLang: configured hit / known-but-not / unknown", () => {
  expect(countryToConfiguredLang("FR", ["fr"])).toBe("fr");
  // multilingual country, config picks the one it has
  expect(countryToConfiguredLang("BE", ["fr"])).toBe("fr");
  // known country, none of its languages configured → null (drop signal)
  expect(countryToConfiguredLang("VN", ["fr"])).toBeNull();
  // unknown country → undefined (no signal)
  expect(countryToConfiguredLang("ZZ", ["fr"])).toBeUndefined();
});

test("countryForLang picks a target country matching the language", () => {
  expect(countryForLang("fr", ["FR", "US"])).toBe("FR");
  expect(countryForLang("en", ["FR", "US"])).toBe("US");
  expect(countryForLang("es", ["FR", "US"])).toBeNull();
});

test("URL locale segment wins over country", () => {
  const langs = resolveQueryLanguages({
    rows: [row("ssl certificate")],
    configured: ["fr", "en"],
    primary: "fr",
    topPageByQuery: new Map([["ssl certificate", "https://x.com/en/ssl"]]),
    queryCountries: new Map([
      ["ssl certificate", [{ country: "FR", impressions: 50 }]],
    ]),
  });
  expect(langs.get("ssl certificate")).toBe("en");
});

test("elevaseo: francophone-country queries → fr, Vietnam-only → dropped", () => {
  const langs = resolveQueryLanguages({
    rows: [row("certificat ssl tls"), row("ssl en attente"), row("foreign")],
    configured: ["fr"],
    primary: "fr",
    queryCountries: new Map([
      // French queries ranking in francophone markets → kept as fr
      ["certificat ssl tls", [{ country: "FR", impressions: 18 }]],
      [
        "ssl en attente",
        [
          { country: "SN", impressions: 3 },
          { country: "CI", impressions: 2 },
        ],
      ],
      // ranks only in Vietnam (known, non-configured) → dropped
      ["foreign", [{ country: "VN", impressions: 9 }]],
    ]),
  });
  expect(langs.get("certificat ssl tls")).toBe("fr");
  expect(langs.get("ssl en attente")).toBe("fr");
  expect(langs.get("foreign")).toBeNull();
});

test("a query ranking in both a configured and a foreign market is kept", () => {
  const langs = resolveQueryLanguages({
    rows: [row("ssl")],
    configured: ["fr"],
    primary: "fr",
    queryCountries: new Map([
      [
        "ssl",
        [
          { country: "VN", impressions: 100 }, // dominant but foreign
          { country: "FR", impressions: 5 }, // configured → keeps it
        ],
      ],
    ]),
  });
  expect(langs.get("ssl")).toBe("fr");
});

test("no URL/country signal → primary language (never dropped)", () => {
  const langs = resolveQueryLanguages({
    rows: [row("new ranking term")],
    configured: ["fr"],
    primary: "fr",
  });
  expect(langs.get("new ranking term")).toBe("fr");
});

test("unknown-country-only query falls back to primary (not dropped)", () => {
  const langs = resolveQueryLanguages({
    rows: [row("q")],
    configured: ["fr"],
    primary: "fr",
    queryCountries: new Map([["q", [{ country: "ZZ", impressions: 5 }]]]),
  });
  expect(langs.get("q")).toBe("fr");
});

test("resolveGscCountry: prefers the dominant TARGET country", () => {
  // Ranks in US (100) and CA (30); both targets → US wins (more impressions).
  const b = [
    { country: "US", impressions: 100 },
    { country: "CA", impressions: 30 },
  ];
  expect(resolveGscCountry(b, ["CA", "FR", "US", "GB"], "CA")).toBe("US");
});

test("resolveGscCountry: a target with data beats a non-target with more", () => {
  // TH not a target, GB is → GB even though TH has more impressions.
  const b = [
    { country: "TH", impressions: 500 },
    { country: "GB", impressions: 40 },
  ];
  expect(resolveGscCountry(b, ["CA", "FR", "US", "GB"], "CA")).toBe("GB");
});

test("resolveGscCountry: no target country → truthful dominant (not fallback)", () => {
  // Pure off-target market (Thailand) → TH, NOT the CA fallback.
  const b = [{ country: "TH", impressions: 90 }];
  expect(resolveGscCountry(b, ["CA", "FR", "US", "GB"], "CA")).toBe("TH");
});

test("resolveGscCountry: no breakdown → fallback", () => {
  expect(resolveGscCountry(undefined, ["CA"], "CA")).toBe("CA");
  expect(resolveGscCountry([], ["CA"], "CA")).toBe("CA");
});
