import { describe, expect, it } from "vitest";
import { findDrops, monthsSinceLast } from "@/lib/alerts";

const series = (entries: [string, number][]) => new Map(entries);

describe("findDrops — ba mốc tháng/quý/năm trước, ngưỡng %", () => {
  it("giảm đúng ngưỡng (30%) vẫn được báo (>=, không phải >)", () => {
    const drops = findDrops(series([["2026-08", 70], ["2026-07", 100]]), "2026-08", 30);
    expect(drops).toHaveLength(1);
    expect(drops[0]).toMatchObject({ label: "tháng trước", before: 100, now: 70, dropPct: 30 });
  });

  it("giảm dưới ngưỡng thì không báo", () => {
    expect(findDrops(series([["2026-08", 80], ["2026-07", 100]]), "2026-08", 30)).toHaveLength(0);
  });

  it("kỳ trước bằng 0 thì bỏ qua (không có gì để so)", () => {
    expect(findDrops(series([["2026-08", 0]]), "2026-08", 30)).toHaveLength(0);
  });

  it("tăng thì không báo", () => {
    expect(findDrops(series([["2026-08", 150], ["2026-07", 100]]), "2026-08", 30)).toHaveLength(0);
  });

  it("nhiều mốc cùng giảm: xếp mốc giảm mạnh nhất lên đầu", () => {
    // tháng trước (2026-07→08): 100→20 (-80%, mạnh nhất).
    // quý trước (Mar–May tổng 300 → Jun–Aug tổng 150): -50%.
    // năm trước: kỳ trước (Sep 2024–Aug 2025) không có dữ liệu → before=0 → bị loại, không phải mốc thứ ba.
    const s = series([
      ["2026-08", 20],
      ["2026-07", 100],
      ["2026-06", 30],
      ["2026-05", 100],
      ["2026-04", 100],
      ["2026-03", 100],
    ]);
    const drops = findDrops(s, "2026-08", 30);
    expect(drops.map((d) => d.label)).toEqual(["tháng trước", "quý trước"]);
    expect(drops[0].dropPct).toBeCloseTo(80);
    expect(drops[1].dropPct).toBeCloseTo(50);
  });

  it("chỉ một mốc có dữ liệu quá khứ thì chỉ báo mốc đó", () => {
    // Không đủ 12 tháng lịch sử cho mốc năm trước — mốc đó bị bỏ qua, không báo giảm giả.
    const drops = findDrops(series([["2026-08", 10], ["2026-07", 100]]), "2026-08", 30);
    expect(drops.map((d) => d.label)).toEqual(["tháng trước"]);
  });
});

describe("monthsSinceLast — số tháng liên tiếp gần nhất không có giá trị", () => {
  it("tháng quét có giá trị → 0", () => {
    expect(monthsSinceLast(series([["2026-08", 5]]), "2026-08")).toBe(0);
  });

  it("tháng quét và 2 tháng liền trước đều không có, giá trị gần nhất là 3 tháng trước → 3", () => {
    expect(monthsSinceLast(series([["2026-05", 5]]), "2026-08")).toBe(3);
  });

  it("chưa từng có giá trị trong phạm vi tra cứu → null (không phải 'đã mất bao lâu')", () => {
    expect(monthsSinceLast(series([]), "2026-08", 12)).toBeNull();
  });

  it("có giá trị nhưng ngoài phạm vi lookback → null, không đếm quá xa", () => {
    expect(monthsSinceLast(series([["2026-01", 5]]), "2026-08", 3)).toBeNull();
  });
});
