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

export { isCacheableRemoteChatMediaUrl };

export function buildChatMediaCacheKey(input: {
  ownerKey: string;
  messageId: string;
  kind: ChatMediaKind;
}): string {
  return `${input.ownerKey}:${input.messageId}:${input.kind}`;
}

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

export function getSendResponseMediaTargets(
  response: ChatSendResponse,
): CacheRemoteChatMediaInput[] {
  const targets: CacheRemoteChatMediaInput[] = [];
  pushMediaTarget(targets, {
    messageId: response.messageId,
    kind: "image",
    remoteUrl: response.image.url,
  });
  pushMediaTarget(targets, {
    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.messageId}:${target.kind}:${target.remoteUrl}`;
    if (seen.has(key)) return false;
    seen.add(key);
    return true;
  });
}

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