import { describe, expect, test } from "bun:test";
import {
  densifySeries,
  detectDrop,
  normalizeUrl,
  weightedPosition,
} from "./stats-logic";

describe("weightedPosition", () => {
  test("weights by impressions", () => {
    expect(
      weightedPosition([
        { position: 10, impressions: 90 },
        { position: 100, impressions: 10 },
      ]),
    ).toBe(19);
  });
  test("null when no impressions", () => {
    expect(weightedPosition([{ position: 5, impressions: 0 }])).toBeNull();
    expect(weightedPosition([])).toBeNull();
  });
});

describe("normalizeUrl", () => {
  test("lowercases scheme+host, strips trailing slash, keeps path case", () => {
    expect(normalizeUrl("HTTPS://Example.COM/Path/")).toBe(
      "https://example.com/Path",
    );
    expect(normalizeUrl("https://example.com/")).toBe("https://example.com");
    expect(normalizeUrl("https://example.com/a?b=1")).toBe(
      "https://example.com/a?b=1",
    );
  });
  test("returns input trimmed when not a URL", () => {
    expect(normalizeUrl("  not a url ")).toBe("not a url");
  });
});

describe("detectDrop", () => {
  const ok = { clicks: 100, impressions: 1000, position: 5 };
  test("position degrades by >= 3", () => {
    expect(detectDrop({ ...ok, position: 9 }, { ...ok, position: 5 })).toBe(
      true,
    );
    expect(detectDrop({ ...ok, position: 7 }, { ...ok, position: 5 })).toBe(
      false,
    );
  });
  test("clicks fall >= 50% with prev floor of 5", () => {
    expect(detectDrop({ ...ok, clicks: 40 }, { ...ok, clicks: 100 })).toBe(
      true,
    );
    expect(detectDrop({ ...ok, clicks: 60 }, { ...ok, clicks: 100 })).toBe(
      false,
    );
    expect(detectDrop({ ...ok, clicks: 1 }, { ...ok, clicks: 4 })).toBe(false); // floor
  });
  test("never fires without impressions on both sides", () => {
    expect(detectDrop({ ...ok, impressions: 0 }, ok)).toBe(false);
    expect(detectDrop(ok, { ...ok, impressions: 0 })).toBe(false);
    expect(detectDrop(ok, { clicks: 0, impressions: 0, position: null })).toBe(
      false,
    );
  });
});

describe("densifySeries", () => {
  test("fills missing days with 0, chronological", () => {
    expect(
      densifySeries(
        [
          { date: "2026-06-07", clicks: 3 },
          { date: "2026-06-05", clicks: 1 },
        ],
        "2026-06-05",
        "2026-06-08",
      ),
    ).toEqual([1, 0, 3, 0]);
  });
});
