import { beforeEach, describe, expect, it, vi } from "vitest";

import { ROUTES } from "@/router/routes";

import { consumePendingChatImageReturn } from "../chat_image_return_session";
import {
  clearPendingChatUnlock,
  peekPendingChatUnlock,
} from "../chat_unlock_session";
import {
  consumeSubscriptionExitUrl,
  consumeSubscriptionExplicitExitUrl,
  getSubscriptionFallbackExitUrl,
  peekSubscriptionExplicitExitUrl,
} from "../subscription_exit";

vi.mock("../chat_image_return_session", () => ({
  consumePendingChatImageReturn: vi.fn(),
}));
vi.mock("../chat_unlock_session", () => ({
  clearPendingChatUnlock: vi.fn(),
  peekPendingChatUnlock: vi.fn(),
}));

const consumePendingChatImageReturnMock = vi.mocked(
  consumePendingChatImageReturn,
);
const clearPendingChatUnlockMock = vi.mocked(clearPendingChatUnlock);
const peekPendingChatUnlockMock = vi.mocked(peekPendingChatUnlock);

describe("subscription exit helpers", () => {
  beforeEach(() => {
    consumePendingChatImageReturnMock.mockReset();
    clearPendingChatUnlockMock.mockReset();
    peekPendingChatUnlockMock.mockReset();
  });

  it("uses explicit chat image return urls first", async () => {
    consumePendingChatImageReturnMock.mockResolvedValue({
      reason: "image_paywall",
      messageId: "msg_1",
      returnUrl: "/chat?image=msg_1",
      createdAt: 1,
    });

    await expect(consumeSubscriptionExplicitExitUrl()).resolves.toBe(
      "/chat?image=msg_1",
    );
  });

  it("falls back to chat when requested", async () => {
    consumePendingChatImageReturnMock.mockResolvedValue(null);
    peekPendingChatUnlockMock.mockResolvedValue(null);

    await expect(consumeSubscriptionExitUrl("chat")).resolves.toBe(ROUTES.chat);
  });

  it("falls back to sidebar by default", async () => {
    consumePendingChatImageReturnMock.mockResolvedValue(null);
    peekPendingChatUnlockMock.mockResolvedValue(null);

    expect(getSubscriptionFallbackExitUrl(null)).toBe(ROUTES.sidebar);
    await expect(consumeSubscriptionExitUrl(null)).resolves.toBe(
      ROUTES.sidebar,
    );
  });

  it("peeks chat unlock return urls without clearing them", async () => {
    peekPendingChatUnlockMock.mockResolvedValue({
      reason: "single_message_unlock",
      messageId: "msg_1",
      kind: "image",
      returnUrl: "/chat?image=msg_1",
      stage: "payment",
      createdAt: 1,
    });

    await expect(peekSubscriptionExplicitExitUrl()).resolves.toBe(
      "/chat?image=msg_1",
    );
    expect(clearPendingChatUnlockMock).not.toHaveBeenCalled();
  });

  it("clears chat unlock return urls when consumed", async () => {
    consumePendingChatImageReturnMock.mockResolvedValue(null);
    peekPendingChatUnlockMock.mockResolvedValue({
      reason: "single_message_unlock",
      messageId: "msg_1",
      kind: "image",
      returnUrl: "/chat?image=msg_1",
      stage: "payment",
      createdAt: 1,
    });

    await expect(consumeSubscriptionExplicitExitUrl()).resolves.toBe(
      "/chat?image=msg_1",
    );
    expect(clearPendingChatUnlockMock).toHaveBeenCalledTimes(1);
  });
});
