import { MAX_AUTO_SAVE_SIZE_BYTES } from '../constants/attachment.constants';
import type { Attachment } from '../models/attachment.model';

const ROOM_URL_PATTERN = /\/room\/([^/]+)/;
const DIRECT_MESSAGE_URL_PATTERN = /^\/(?:dm|pm)\/([^/]+)/;
const DIRECT_MESSAGE_ATTACHMENT_STORAGE_PREFIX = 'direct-message:';

export function isAttachmentMedia(attachment: Pick<Attachment, 'mime'>): boolean {
  return attachment.mime.startsWith('image/') ||
    attachment.mime.startsWith('video/') ||
    attachment.mime.startsWith('audio/');
}

export function shouldAutoRequestWhenWatched(attachment: Attachment): boolean {
  return attachment.isImage ||
    (isAttachmentMedia(attachment) && attachment.size <= MAX_AUTO_SAVE_SIZE_BYTES);
}

export function shouldPersistDownloadedAttachment(attachment: Pick<Attachment, 'size' | 'mime'>): boolean {
  return attachment.size <= MAX_AUTO_SAVE_SIZE_BYTES ||
    attachment.mime.startsWith('video/') ||
    attachment.mime.startsWith('audio/');
}

export function shouldCopyUploaderMediaToAppData(
  attachment: Pick<Attachment, 'size' | 'mime'>,
  sourcePath?: string | null,
  canCopyFiles = false
): boolean {
  return canCopyFiles &&
    !!sourcePath &&
    (attachment.mime.startsWith('video/') || attachment.mime.startsWith('audio/')) &&
    attachment.size > MAX_AUTO_SAVE_SIZE_BYTES;
}

export function getWatchedAttachmentRoomIdFromUrl(url: string): string | null {
  const path = url.split(/[?#]/, 1)[0];
  const directMessageMatch = path.match(DIRECT_MESSAGE_URL_PATTERN);

  if (directMessageMatch) {
    return `${DIRECT_MESSAGE_ATTACHMENT_STORAGE_PREFIX}${decodeUrlSegment(directMessageMatch[1])}`;
  }

  const roomMatch = path.match(ROOM_URL_PATTERN);

  return roomMatch ? decodeUrlSegment(roomMatch[1]) : null;
}

export function isDirectMessageAttachmentRoomId(roomId: string | null | undefined): boolean {
  return !!roomId && roomId.startsWith(DIRECT_MESSAGE_ATTACHMENT_STORAGE_PREFIX);
}

function decodeUrlSegment(value: string): string {
  try {
    return decodeURIComponent(value);
  } catch {
    return value;
  }
}
