import test from "node:test";
import assert from "node:assert/strict";
import { buildDailyTokenGrid, buildTokenMonthLabels, buildTokenPeriodGrid, tokenLevel } from "./token-grid.js";

test("daily token grid fills the latest 30 calendar days and keeps missing days empty", () => {
  const days = buildDailyTokenGrid([
    { startDate: "2026-07-13", tokens: 500 },
    { startDate: "2026-07-14", tokens: 1000 }
  ], 30, new Date("2026-07-14T12:00:00.000Z"));

  assert.equal(days.length, 30);
  assert.deepEqual(days.at(-2), { date: "2026-07-13", tokens: 500, level: 2 });
  assert.deepEqual(days.at(-1), { date: "2026-07-14", tokens: 1000, level: 4 });
  assert.deepEqual(days[0], { date: "2026-06-15", tokens: null, level: 0 });
});

test("token levels use the account's peak daily value", () => {
  assert.equal(tokenLevel(0, 1000), 1);
  assert.equal(tokenLevel(100, 1000), 1);
  assert.equal(tokenLevel(300, 1000), 2);
  assert.equal(tokenLevel(600, 1000), 3);
  assert.equal(tokenLevel(1000, 1000), 4);
  assert.equal(tokenLevel(null, 1000), 0);
});

test("token month labels mark month boundaries across the latest year", () => {
  const days = buildDailyTokenGrid([], 365, new Date(2026, 6, 14, 12));
  const labels = buildTokenMonthLabels(days);

  assert.equal(days.length, 365);
  assert.equal(labels[0].date, "2025-08-01");
  assert.equal(labels.at(-1).date, "2026-07-01");
  assert.equal(labels.length, 12);
  assert.ok(labels.every(({ position }) => position >= 0 && position <= 1));
});

test("token period grid turns weekly totals and their running cumulative values into stacked bars", () => {
  const days = buildDailyTokenGrid([
    { startDate: "2026-07-01", tokens: 100 },
    { startDate: "2026-07-02", tokens: 200 },
    { startDate: "2026-07-08", tokens: 400 }
  ], 14, new Date(2026, 6, 14, 12));

  const weeks = buildTokenPeriodGrid(days, "weekly");
  const cumulative = buildTokenPeriodGrid(days, "cumulative");

  assert.equal(weeks.length, 14);
  assert.deepEqual(weeks.slice(0, 7).map(({ level }) => level), [0, 4, 4, 4, 4, 4, 4]);
  assert.deepEqual(weeks.slice(7).map(({ level }) => level), [4, 4, 4, 4, 4, 4, 4]);
  assert.ok(weeks.slice(0, 7).every(({ tokens }) => tokens === 300));
  assert.ok(weeks.slice(7).every(({ tokens }) => tokens === 400));
  assert.equal(cumulative.length, 14);
  assert.deepEqual(cumulative.slice(0, 7).map(({ level }) => level), [0, 0, 0, 0, 4, 4, 4]);
  assert.deepEqual(cumulative.slice(7).map(({ level }) => level), [4, 4, 4, 4, 4, 4, 4]);
  assert.ok(cumulative.slice(0, 7).every(({ tokens }) => tokens === 300));
  assert.ok(cumulative.slice(7).every(({ tokens }) => tokens === 700));
  assert.equal(new Set(weeks.map(({ key }) => key)).size, 14);
});
