import { describe, it, expect } from "vitest";
import {
  isWithinBannerWindow,
  shouldShowBanner,
  type RestorableMigrationJournal,
} from "./categoryRestoreService";

const DAY = 24 * 60 * 60 * 1000;

describe("isWithinBannerWindow", () => {
  it("returns true for a migration just done", () => {
    const now = Date.parse("2026-04-20T00:00:00Z");
    const ts = "2026-04-19T00:00:00Z";
    expect(isWithinBannerWindow(ts, now)).toBe(true);
  });

  it("returns true on the 90-day boundary", () => {
    const now = Date.parse("2026-04-20T00:00:00Z");
    const ts = new Date(now - 90 * DAY).toISOString();
    expect(isWithinBannerWindow(ts, now)).toBe(true);
  });

  it("returns false past 90 days", () => {
    const now = Date.parse("2026-04-20T00:00:00Z");
    const ts = new Date(now - 91 * DAY).toISOString();
    expect(isWithinBannerWindow(ts, now)).toBe(false);
  });

  it("returns false for a timestamp in the future", () => {
    const now = Date.parse("2026-04-20T00:00:00Z");
    const ts = new Date(now + DAY).toISOString();
    expect(isWithinBannerWindow(ts, now)).toBe(false);
  });

  it("returns false for an unparseable timestamp", () => {
    const now = Date.parse("2026-04-20T00:00:00Z");
    expect(isWithinBannerWindow("not-a-date", now)).toBe(false);
  });

  it("respects a custom window length", () => {
    const now = Date.parse("2026-04-20T00:00:00Z");
    const ts = new Date(now - 31 * DAY).toISOString();
    expect(isWithinBannerWindow(ts, now, 30)).toBe(false);
    expect(isWithinBannerWindow(ts, now, 60)).toBe(true);
  });
});

describe("shouldShowBanner", () => {
  const now = Date.parse("2026-04-20T00:00:00Z");

  function journal(
    overrides: Partial<RestorableMigrationJournal> = {},
  ): RestorableMigrationJournal {
    return {
      timestamp: "2026-04-15T10:00:00Z",
      backupPath: "/tmp/profile_avant-migration.sref",
      outcome: {
        insertedV1Count: 1,
        updatedTransactionsCount: 2,
        updatedBudgetsCount: 0,
        updatedKeywordsCount: 0,
        deletedV2Count: 0,
        customPreservedCount: 0,
      },
      ...overrides,
    };
  }

  it("hides the banner when no migration has run", () => {
    expect(shouldShowBanner(null, null, now)).toBe(false);
  });

  it("shows the banner for a recent un-dismissed un-reverted migration", () => {
    expect(shouldShowBanner(journal(), null, now)).toBe(true);
  });

  it("hides the banner when the user already dismissed it", () => {
    expect(shouldShowBanner(journal(), "1", now)).toBe(false);
  });

  it("hides the banner when the migration was already reverted", () => {
    expect(
      shouldShowBanner(
        journal({ reverted_at: "2026-04-19T12:00:00Z" }),
        null,
        now,
      ),
    ).toBe(false);
  });

  it("hides the banner past the 90-day window", () => {
    expect(
      shouldShowBanner(
        journal({ timestamp: "2026-01-01T00:00:00Z" }),
        null,
        now,
      ),
    ).toBe(false);
  });

  it("ignores arbitrary dismissal-pref values that are not '1'", () => {
    // Defensive: we treat anything other than the literal "1" as "not
    // dismissed" so an accidental write of "0" or "" still shows the banner.
    expect(shouldShowBanner(journal(), "0", now)).toBe(true);
    expect(shouldShowBanner(journal(), "", now)).toBe(true);
  });
});
