export interface SplashLatestMessageSource {
  type?: string | null;
  content?: string | null;
  audioUrl?: string | null;
  imageUrl?: string | null;
  isSynthetic?: boolean;
  lockReason?: string | null;
  image?: {
    type?: string | null;
    url?: string | null;
  } | null;
  lockDetail?: {
    reason?: string | null;
  } | null;
}

const IMAGE_PREVIEW_TEXT = "[图片]";
const VOICE_PREVIEW_TEXT = "[语音]";
const FALLBACK_PREVIEW_TEXT = "[消息]";

export function getSplashLatestMessagePreview(
  message: SplashLatestMessageSource | null | undefined,
): string | null {
  if (!message || message.isSynthetic) return null;

  if (isVoiceMessage(message)) return VOICE_PREVIEW_TEXT;
  if (isImageMessage(message)) return IMAGE_PREVIEW_TEXT;

  const content = message.content?.trim() ?? "";
  return content.length > 0 ? content : FALLBACK_PREVIEW_TEXT;
}

export function getLatestSplashMessagePreview(
  messages: readonly SplashLatestMessageSource[],
): string | null {
  for (let index = messages.length - 1; index >= 0; index -= 1) {
    const message = messages[index];
    if (message && !message.isSynthetic) {
      return getSplashLatestMessagePreview(message);
    }
  }
  return null;
}

function isVoiceMessage(message: SplashLatestMessageSource): boolean {
  const type = normalizeMessageType(message.type);
  return (
    type === "voice" ||
    type === "audio" ||
    hasValue(message.audioUrl) ||
    getLockReason(message) === "voice_message"
  );
}

function isImageMessage(message: SplashLatestMessageSource): boolean {
  const type = normalizeMessageType(message.type);
  return (
    type === "image" ||
    hasValue(message.imageUrl) ||
    hasValue(message.image?.url) ||
    hasValue(message.image?.type) ||
    getLockReason(message) === "image" ||
    getLockReason(message) === "image_paywall"
  );
}

function getLockReason(message: SplashLatestMessageSource): string | null {
  return message.lockReason ?? message.lockDetail?.reason ?? null;
}

function normalizeMessageType(value: string | null | undefined): string {
  return value?.trim().toLowerCase() ?? "";
}

function hasValue(value: string | null | undefined): boolean {
  return value != null && value.trim().length > 0;
}
