import type { UiMessage } from "@/stores/chat/ui-message";
import type { PendingChatPromotion } from "@/data/storage/navigation";
import { todayString } from "@/utils/date";

import {
  applySingleUnlockOutput,
  type UnlockMessageOutput,
} from "./unlock";

const PROMOTION_COPY = {
  voice: "I left a voice message for you. Unlock it to listen.",
  image: "I sent you a private photo. Unlock it to view.",
  private: "I have something private to tell you. Unlock it to read.",
} as const;

export interface ChatPromotionState {
  session: PendingChatPromotion;
  message: UiMessage;
}

export function createChatPromotionState(
  session: PendingChatPromotion,
  messageId?: string,
): ChatPromotionState {
  const isImage = session.promotionType === "image";
  const isPrivate = session.promotionType === "private";

  return {
    session,
    message: {
      displayId: `promotion:${session.clientLockId}`,
      ...(messageId ? { remoteId: messageId } : {}),
      content: "",
      isFromAI: true,
      date: todayString(),
      locked: true,
      lockReason: session.lockType,
      imagePaywalled: isImage ? true : undefined,
      lockedPrivate: isPrivate ? true : undefined,
      privateMessageHint: PROMOTION_COPY[session.promotionType],
    },
  };
}

export function appendPromotionMessage(
  messages: readonly UiMessage[],
  promotion: ChatPromotionState | null,
): UiMessage[] {
  if (!promotion) return [...messages];
  return [
    ...messages.filter(
      (message) =>
        message.displayId !== promotion.message.displayId &&
        (!promotion.message.remoteId ||
          !message.isFromAI ||
          message.remoteId !== promotion.message.remoteId),
    ),
    promotion.message,
  ];
}

export function applyPromotionUnlockOutput(
  promotion: ChatPromotionState | null,
  output: UnlockMessageOutput,
): ChatPromotionState | null {
  if (
    !promotion ||
    promotion.message.displayId !== output.displayMessageId
  ) {
    return promotion;
  }
  return {
    ...promotion,
    message:
      applySingleUnlockOutput([promotion.message], output)[0] ??
      promotion.message,
  };
}
