import type { TicketAttachment } from '@/features/tickets/types/ticket.types';
import { resolveAttachmentUrl } from '@/shared/utils/attachmentUrl';
import { apiClient } from '@/shared/utils/api';

function isAbsoluteUrl(url: string): boolean {
  return /^https?:\/\//i.test(url);
}

function isSameOriginUrl(url: string): boolean {
  if (!isAbsoluteUrl(url)) {
    return true;
  }

  try {
    return new URL(url).origin === window.location.origin;
  } catch {
    return false;
  }
}

function isApiDownloadPath(url: string): boolean {
  const path = isAbsoluteUrl(url) ? new URL(url).pathname + new URL(url).search : url;
  return /\/api\/v\d+\/attachments\/[^/]+\/download(?:\?|$)/.test(path);
}

export function toApiRelativePath(resolvedUrl: string): string {
  if (isAbsoluteUrl(resolvedUrl)) {
    const { pathname, search } = new URL(resolvedUrl);
    const path = `${pathname}${search}`;
    const versionedMatch = path.match(/^\/api\/v\d+/);
    if (versionedMatch) {
      return path.slice(versionedMatch[0].length) || '/';
    }
    return path;
  }

  const versionedMatch = resolvedUrl.match(/^\/api\/v\d+/);
  if (versionedMatch) {
    const path = resolvedUrl.slice(versionedMatch[0].length);
    return path.startsWith('/') ? path : `/${path}`;
  }

  return resolvedUrl.startsWith('/') ? resolvedUrl : `/${resolvedUrl}`;
}

export async function fetchAttachmentBlob(
  attachment: TicketAttachment,
  options?: { inline?: boolean },
): Promise<Blob> {
  const resolved = resolveAttachmentUrl(attachment, options);

  if (isAbsoluteUrl(resolved) && (!isSameOriginUrl(resolved) || !isApiDownloadPath(resolved))) {
    const response = await fetch(resolved, { credentials: 'include' });
    if (!response.ok) {
      throw new Error('Failed to fetch attachment');
    }
    return response.blob();
  }

  const response = await apiClient.get<Blob>(toApiRelativePath(resolved), {
    responseType: 'blob',
    headers: { Accept: '*/*' },
  });

  return response.data;
}

export async function openAttachmentInNewTab(
  attachment: TicketAttachment,
  options?: { inline?: boolean },
): Promise<void> {
  const blob = await fetchAttachmentBlob(attachment, options);
  const mime = attachment.mime_type || blob.type || 'application/octet-stream';
  const blobUrl = URL.createObjectURL(new Blob([blob], { type: mime }));
  const opened = window.open(blobUrl, '_blank', 'noopener,noreferrer');

  if (!opened) {
    URL.revokeObjectURL(blobUrl);
    throw new Error('Popup blocked');
  }

  window.setTimeout(() => URL.revokeObjectURL(blobUrl), 60_000);
}

export async function downloadAttachmentFile(attachment: TicketAttachment): Promise<void> {
  const blob = await fetchAttachmentBlob(attachment);
  const blobUrl = URL.createObjectURL(blob);
  const link = document.createElement('a');
  link.href = blobUrl;
  link.download = attachment.file_name;
  document.body.appendChild(link);
  link.click();
  link.remove();
  URL.revokeObjectURL(blobUrl);
}
