import { beforeEach, describe, expect, it, vi } from "vitest";
import { createStorage } from "unstorage";
import memoryDriver from "unstorage/drivers/memory";

import { SessionAsyncUtil } from "@/utils/session-storage";

import { NavigationStorage } from "../navigation_storage";

describe("NavigationStorage", () => {
  beforeEach(() => {
    SessionAsyncUtil.setStorage(createStorage({ driver: memoryDriver() }));
    vi.useRealTimers();
  });

  it("saves, peeks, and consumes pending chat unlock sessions", async () => {
    await NavigationStorage.savePendingChatUnlock({
      messageId: "msg_1",
      kind: "image",
      returnUrl: "/chat?image=msg_1",
      stage: "payment",
    });

    await expect(NavigationStorage.peekPendingChatUnlock()).resolves.toMatchObject({
      messageId: "msg_1",
      kind: "image",
      returnUrl: "/chat?image=msg_1",
      stage: "payment",
    });

    await expect(
      NavigationStorage.consumePendingChatUnlock(),
    ).resolves.toMatchObject({
      messageId: "msg_1",
      kind: "image",
    });
    await expect(NavigationStorage.peekPendingChatUnlock()).resolves.toBeNull();
  });

  it("drops expired pending chat unlock sessions", async () => {
    vi.useFakeTimers();
    vi.setSystemTime(new Date("2026-07-03T00:00:00.000Z"));

    await NavigationStorage.savePendingChatUnlock({
      messageId: "msg_1",
      kind: "private",
      returnUrl: "/chat",
      stage: "auth",
    });

    vi.setSystemTime(new Date("2026-07-03T00:31:00.000Z"));

    await expect(NavigationStorage.peekPendingChatUnlock()).resolves.toBeNull();
  });

  it("stores a one-time promotion and carries it through unlock navigation", async () => {
    const promotion = await NavigationStorage.savePendingChatPromotion("image");

    expect(promotion).toMatchObject({
      promotionType: "image",
      lockType: "image_paywall",
    });
    expect(promotion.clientLockId).toMatch(/^promotion_/);
    await expect(
      NavigationStorage.consumePendingChatPromotion(),
    ).resolves.toEqual(promotion);
    await expect(
      NavigationStorage.consumePendingChatPromotion(),
    ).resolves.toBeNull();

    await NavigationStorage.savePendingChatUnlock({
      displayMessageId: `promotion:${promotion.clientLockId}`,
      kind: "image",
      lockType: promotion.lockType,
      clientLockId: promotion.clientLockId,
      promotion,
      returnUrl: "/chat",
      stage: "auth",
    });
    await expect(NavigationStorage.peekPendingChatUnlock()).resolves.toMatchObject({
      lockType: "image_paywall",
      clientLockId: promotion.clientLockId,
      promotion,
    });
  });

  it("saves and consumes pending chat image return sessions", async () => {
    await NavigationStorage.savePendingChatImageReturn({
      messageId: "msg_1",
      returnUrl: "/chat?image=msg_1",
    });

    await expect(
      NavigationStorage.consumePendingChatImageReturn(),
    ).resolves.toMatchObject({
      messageId: "msg_1",
      returnUrl: "/chat?image=msg_1",
    });
    await expect(
      NavigationStorage.consumePendingChatImageReturn(),
    ).resolves.toBeNull();
  });
});
