import type { Page } from "@playwright/test";

import { apiEnvelope } from "../data/common";
import { chatSendResponse, createChatSendResponse, createPaidImageHistoryResponse, createWeeklyLimitChatSendResponse, emptyChatHistoryResponse, emptyChatPreviewsResponse, insufficientCreditsUnlockImageResponse, insufficientCreditsUnlockVoiceResponse, paidImageChatSendResponse, paidImageUnlockHistoryResponse, paidVoiceHistoryResponse } from "../data/chat";

export interface ChatMockOptions {
  chatLimitTriggerAt?: number;
  chatSendTokenRefreshFlow: boolean;
  paidImageFlow: boolean;
  paidImageInsufficientCreditsFlow: boolean;
  paidVoiceInsufficientCreditsFlow: boolean;
}

export interface ChatMockState {
  hasExpiredChatSend: boolean;
  paidImageRequested: boolean;
  paidImageUnlocked: boolean;
}

export async function registerChatMocks(page: Page, options: ChatMockOptions, state: ChatMockState) {
  let sendCount = 0;

  await page.route("**/api/chat/opening-message", async (route) => {
    const body = route.request().postDataJSON() as {
      openingMessage?: unknown;
    } | undefined;
    await route.fulfill({
      json: apiEnvelope({
        messageId: "mock-opening-message",
        created: true,
        openingMessage:
          typeof body?.openingMessage === "string"
            ? body.openingMessage
            : "Hello",
        createdAt: "2026-07-23T00:00:00Z",
      }),
    });
  });

  await page.route("**/api/chat/history**", async (route) => {
    const response = options.paidVoiceInsufficientCreditsFlow
      ? paidVoiceHistoryResponse
      : options.paidImageInsufficientCreditsFlow
        ? createPaidImageHistoryResponse(false)
        : options.paidImageFlow && state.paidImageRequested
          ? createPaidImageHistoryResponse(state.paidImageUnlocked)
          : emptyChatHistoryResponse;
    await route.fulfill({ json: apiEnvelope(response) });
  });

  await page.route("**/api/chat/previews", async (route) => {
    await route.fulfill({ json: apiEnvelope(emptyChatPreviewsResponse) });
  });

  await page.route("**/api/chat/send", async (route) => {
    sendCount += 1;
    const requestBody = route.request().postDataJSON() as { message?: unknown } | undefined;
    const message = typeof requestBody?.message === "string" ? requestBody.message : "";
    if (options.chatSendTokenRefreshFlow && !state.hasExpiredChatSend) {
      state.hasExpiredChatSend = true;
      await route.fulfill({ status: 401, json: { message: "expired" } });
      return;
    }
    const response = message.includes("discount offer test")
      ? {
          ...chatSendResponse,
          reply: "I know you're thinking carefully about the price.",
          messageId: "discount-action-message",
          commercialAction: {
            actionId: "13ec8a10-58d7-4d24-b66b-8db5699a1aa8",
            type: "discountOffer",
            copy: "Want me to ask for my best private offer?",
            ctaLabel: "Yes, ask for me",
            target: "discountConsent",
            ruleId: "discount_after_price_objection",
          },
        }
      : message.includes("private album offer test")
      ? {
          ...chatSendResponse,
          reply: "You always know how to make me smile.",
          messageId: "commercial-action-message",
          commercialAction: {
            actionId: "commercial-action-1",
            type: "privateAlbumOffer",
            copy: "There are more private photos waiting for you.",
            ctaLabel: "Open private zone",
            target: "privateZone",
            ruleId: "private_album_after_appearance_praise",
          },
        }
      : options.paidImageFlow && message.includes("给我发图片")
      ? paidImageChatSendResponse
      : options.chatLimitTriggerAt != null && sendCount >= options.chatLimitTriggerAt
        ? createWeeklyLimitChatSendResponse(sendCount, options.chatLimitTriggerAt)
        : options.chatLimitTriggerAt != null
          ? createChatSendResponse(sendCount)
          : chatSendResponse;
    if (options.paidImageFlow && message.includes("给我发图片")) {
      state.paidImageRequested = true;
      state.paidImageUnlocked = false;
    }
    await route.fulfill({ json: apiEnvelope(response) });
  });

  await page.route("**/api/chat/unlock-history", async (route) => {
    if (options.paidImageFlow && state.paidImageRequested) state.paidImageUnlocked = true;
    const response = options.paidImageFlow && state.paidImageRequested ? paidImageUnlockHistoryResponse : { unlocked: true, reason: "no_locked_messages", totalLocked: 0, unlockedCount: 0, privateCount: 0, imageCount: 0, voiceCount: 0, requiredCredits: 0, currentCredits: 0, remainingCredits: 0, shortfallCredits: 0, costsByMessage: {}, messageIds: [] };
    await route.fulfill({ json: apiEnvelope(response) });
  });

  await page.route("**/api/chat/unlock-private", async (route) => {
    const response = options.paidVoiceInsufficientCreditsFlow
      ? insufficientCreditsUnlockVoiceResponse
      : options.paidImageInsufficientCreditsFlow || options.paidImageFlow && state.paidImageRequested && !state.paidImageUnlocked
        ? insufficientCreditsUnlockImageResponse
        : { unlocked: true, content: "Unlocked message", reason: "ok", creditBalance: 100, creditsCharged: 0, requiredCredits: 0, shortfallCredits: 0, lockDetail: { locked: false, showContent: true, showUpgrade: false, reason: null, hint: null, detail: null } };
    await route.fulfill({ json: apiEnvelope(response) });
  });
}
