import { expect, test } from "bun:test";
import { gscBand, opportunityScore, positionBucket } from "./gsc-positioning";
import type { GscTracking } from "./types";

const g = (position: number, impressions = 100): GscTracking => ({
  clicks: 0,
  impressions,
  ctr: 0,
  position,
  updatedAt: "2026-06-06",
});

test("gscBand classifies by position; null/undefined = none", () => {
  expect(gscBand(null)).toBe("none");
  expect(gscBand(undefined)).toBe("none");
  expect(gscBand(g(10))).toBe("top10");
  expect(gscBand(g(10.4))).toBe("quickwin");
  expect(gscBand(g(20))).toBe("quickwin");
  expect(gscBand(g(20.1))).toBe("beyond");
});

test("opportunityScore: 0 outside quick-win, impressions × proximity inside", () => {
  expect(opportunityScore(null)).toBe(0);
  expect(opportunityScore(g(5))).toBe(0); // top10
  expect(opportunityScore(g(28))).toBe(0); // beyond
  expect(opportunityScore(g(11, 900))).toBe(9000); // 900 × (21 − 11)
  expect(opportunityScore(g(20, 900))).toBe(900); // 900 × (21 − 20)
  expect(opportunityScore(g(18, 120))).toBe(360); // 120 × (21 − 18)
  expect(opportunityScore(g(11, 900))).toBeGreaterThan(
    opportunityScore(g(20, 900)),
  );
});

test("positionBucket: top3 ≤3, top10 4-10, quickwin 11-20, deep 21-50, far >50, none null", () => {
  expect(positionBucket(null)).toBe("none");
  expect(positionBucket(g(3))).toBe("top3");
  expect(positionBucket(g(3.4))).toBe("top10");
  expect(positionBucket(g(10))).toBe("top10");
  expect(positionBucket(g(10.4))).toBe("quickwin");
  expect(positionBucket(g(20))).toBe("quickwin");
  expect(positionBucket(g(20.4))).toBe("deep");
  expect(positionBucket(g(50))).toBe("deep");
  expect(positionBucket(g(50.4))).toBe("far");
});
