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

import type { ChatAction } from "@/data/schemas/chat";
import type { PaymentOrderStatusResponse } from "@/data/schemas/payment";

import {
  resolveChatActionTarget,
  type ChatActionNavigationContext,
} from "../chat-action-navigation";

const baseAction: ChatAction = {
  actionId: "action-1",
  kind: "support",
  type: "openProfile",
  copy: "Open it here.",
  ctaLabel: "Open",
  ruleId: null,
  orderId: null,
};

function createContext(
  order: Partial<PaymentOrderStatusResponse> = {},
): ChatActionNavigationContext {
  const orderResponse: PaymentOrderStatusResponse = {
    orderId: "order-1",
    status: "pending",
    orderType: "dol",
    planId: "topup-100",
    creditsAdded: 0,
    ...order,
  };
  return {
    characterRoutes: {
      splash: "/characters/elio/splash",
      chat: "/characters/elio/chat",
      call: "/characters/elio/call",
      privateZone: "/characters/elio/private-zone",
      tip: "/characters/elio/tip",
    },
    characterSlug: "elio",
    profileUrl: "/profile?returnTo=chat",
    feedbackUrl: "/feedback?returnTo=chat",
    coinsRulesUrl: "/coins-rules?returnTo=chat",
    getOrderStatus: vi.fn(async () => orderResponse),
  };
}

describe("resolveChatActionTarget", () => {
  it.each([
    ["giftOffer", "/characters/elio/tip?chatActionId=action-1"],
    ["privateAlbumOffer", "/characters/elio/private-zone"],
    ["openProfile", "/profile?returnTo=chat"],
    ["openWallet", "/profile?returnTo=chat"],
    ["openCoinsRules", "/coins-rules?returnTo=chat"],
    ["openFeedback", "/feedback?returnTo=chat"],
  ] as const)("maps %s to an allowlisted internal page", async (type, expected) => {
    await expect(
      resolveChatActionTarget({ ...baseAction, type }, createContext()),
    ).resolves.toBe(expected);
  });

  it("maps VIP and top-up actions to typed subscription routes", async () => {
    await expect(
      resolveChatActionTarget(
        { ...baseAction, kind: "commercial", type: "activateVip" },
        createContext(),
      ),
    ).resolves.toBe(
      "/subscription?type=vip&returnTo=chat&character=elio&chatActionId=action-1",
    );
    await expect(
      resolveChatActionTarget(
        { ...baseAction, kind: "commercial", type: "topUp" },
        createContext(),
      ),
    ).resolves.toBe(
      "/subscription?type=topup&returnTo=chat&character=elio&chatActionId=action-1",
    );
  });

  it("resumes a pending VIP order using its owned order id", async () => {
    const action: ChatAction = {
      ...baseAction,
      type: "resumePayment",
      orderId: "order-1",
    };
    await expect(
      resolveChatActionTarget(
        action,
        createContext({ orderType: "vip_monthly" }),
      ),
    ).resolves.toBe(
      "/subscription?type=vip&returnTo=chat&character=elio&resumeOrderId=order-1",
    );
  });

  it("does not resume an order that is no longer pending", async () => {
    const action: ChatAction = {
      ...baseAction,
      type: "resumePayment",
      orderId: "order-1",
    };
    await expect(
      resolveChatActionTarget(action, createContext({ status: "paid" })),
    ).resolves.toBe("/profile?returnTo=chat");
    await expect(
      resolveChatActionTarget(action, createContext({ status: "expired" })),
    ).resolves.toBe("/feedback?returnTo=chat");
  });
});
