// Pure-logic tests for the expiry-reminder cadence: which reminder kind
// (if any) applies to a relay subscription row right now. The send/dedup
// path hits SQLite + SMTP and isn't unit-tested here; this nails the
// decision that drives it.

import { test, describe } from "node:test";
import assert from "node:assert/strict";

import { reminderKindFor } from "../subscription-reminders.js";

const sub = (days_left, expired = false) => ({
  tier: "pro",
  expires_at: "2026-07-01T00:00:00.000Z",
  expired,
  days_left,
});

describe("reminderKindFor", () => {
  test("upcoming: smallest crossed threshold wins", () => {
    assert.equal(reminderKindFor(sub(8)), null); // beyond 7d
    assert.equal(reminderKindFor(sub(7)), "upcoming_7d");
    assert.equal(reminderKindFor(sub(5)), "upcoming_7d");
    assert.equal(reminderKindFor(sub(2)), "upcoming_7d");
    assert.equal(reminderKindFor(sub(1)), "upcoming_1d");
    assert.equal(reminderKindFor(sub(0)), "upcoming_1d"); // expires today, not yet lapsed
  });

  test("lapsed: only within the lapsed window", () => {
    assert.equal(reminderKindFor(sub(0, true)), "lapsed");
    assert.equal(reminderKindFor(sub(-1, true)), "lapsed");
    assert.equal(reminderKindFor(sub(-3, true)), "lapsed");
    assert.equal(reminderKindFor(sub(-4, true)), null); // aged out (window=3)
  });

  test("null-safe / malformed input", () => {
    assert.equal(reminderKindFor(null), null);
    assert.equal(reminderKindFor({}), null);
    assert.equal(reminderKindFor({ expired: false }), null); // no days_left
    assert.equal(reminderKindFor({ days_left: "soon" }), null);
  });

  test("respects custom thresholds", () => {
    const upcoming = [
      { days: 14, kind: "upcoming_14d" },
      { days: 3, kind: "upcoming_3d" },
    ];
    assert.equal(reminderKindFor(sub(14), { upcoming }), "upcoming_14d");
    assert.equal(reminderKindFor(sub(3), { upcoming }), "upcoming_3d");
    assert.equal(reminderKindFor(sub(15), { upcoming }), null);
  });
});
