import type {
  ChatMediaKind,
  ChatMessage,
  ChatSendResponse,
} from "@/data/schemas/chat";
import type { CacheRemoteChatMediaInput } from "@/data/repositories/interfaces";
import { isCacheableRemoteChatMediaUrl } from "@/lib/chat/chat_media_url";
import { buildChatMediaCacheKey } from "@/lib/chat/chat_cache_keys";

export { buildChatMediaCacheKey, isCacheableRemoteChatMediaUrl };

export function getMessageMediaTargets(
  message: ChatMessage,
  characterId: string,
): CacheRemoteChatMediaInput[] {
  const targets: CacheRemoteChatMediaInput[] = [];
  pushMediaTarget(targets, {
    characterId,
    messageId: message.id,
    kind: "image",
    remoteUrl: message.image.url,
  });
  pushMediaTarget(targets, {
    characterId,
    messageId: message.id,
    kind: "audio",
    remoteUrl: message.audioUrl,
  });
  return targets;
}

export function getSendResponseMediaTargets(
  response: ChatSendResponse,
  characterId: string,
): CacheRemoteChatMediaInput[] {
  const targets: CacheRemoteChatMediaInput[] = [];
  pushMediaTarget(targets, {
    characterId,
    messageId: response.messageId,
    kind: "image",
    remoteUrl: response.image.url,
  });
  if (!response.lockDetail.locked) {
    pushMediaTarget(targets, {
      characterId,
      messageId: response.messageId,
      kind: "audio",
      remoteUrl: response.audioUrl,
    });
  }
  return targets;
}

export function fallbackChatMediaMimeType(kind: ChatMediaKind): string {
  return kind === "image" ? "image/*" : "audio/mpeg";
}

export function uniqueMediaTargets(
  targets: readonly CacheRemoteChatMediaInput[],
): CacheRemoteChatMediaInput[] {
  const seen = new Set<string>();
  return targets.filter((target) => {
    const key = `${target.characterId}:${target.messageId}:${target.kind}:${target.remoteUrl}`;
    if (seen.has(key)) return false;
    seen.add(key);
    return true;
  });
}

function pushMediaTarget(
  targets: CacheRemoteChatMediaInput[],
  input: {
    characterId: string;
    messageId: string;
    kind: ChatMediaKind;
    remoteUrl: string | null;
  },
): void {
  if (input.messageId.length === 0) return;
  if (
    !input.remoteUrl ||
    !isCacheableRemoteChatMediaUrl(input.remoteUrl)
  ) {
    return;
  }
  targets.push({
    characterId: input.characterId,
    messageId: input.messageId,
    kind: input.kind,
    remoteUrl: input.remoteUrl,
  });
}
