'use client';

import { useCallback, useEffect, useState } from 'react';
import { useTranslations } from 'next-intl';
import { Download, FileText } from 'lucide-react';
import { DialogCloseButton } from '@/components/ui/shared/DialogCloseButton';
import { Button } from '@/components/ui/shared/Button';
import type { LabCaseAttachmentMeta } from '@/types/cases';

interface LabCaseAttachmentsDialogProps {
  open: boolean;
  onClose: () => void;
  caseId: string;
  attachments: LabCaseAttachmentMeta[];
  loadBlob: (caseId: string, attachmentId: string) => Promise<Blob>;
}

function downloadBlob(blob: Blob, fileName: string) {
  const url = URL.createObjectURL(blob);
  const anchor = document.createElement('a');
  anchor.href = url;
  anchor.download = fileName;
  anchor.click();
  URL.revokeObjectURL(url);
}

function formatFileSize(bytes: number): string {
  if (bytes < 1024) return `${bytes} B`;
  const kb = bytes / 1024;
  if (kb < 1024) return `${kb.toFixed(1)} KB`;
  return `${(kb / 1024).toFixed(1)} MB`;
}

function AttachmentPreviewTile({
  caseId,
  attachment,
  loadBlob,
  onDownload,
}: {
  caseId: string;
  attachment: LabCaseAttachmentMeta;
  loadBlob: (caseId: string, attachmentId: string) => Promise<Blob>;
  onDownload: (blob: Blob, fileName: string) => void;
}) {
  const t = useTranslations('cases');
  const [url, setUrl] = useState<string | null>(null);
  const [blob, setBlob] = useState<Blob | null>(null);
  const [failed, setFailed] = useState(false);
  const [downloading, setDownloading] = useState(false);

  useEffect(() => {
    let cancelled = false;
    let objectUrl: string | null = null;

    void (async () => {
      try {
        const loaded = await loadBlob(caseId, attachment.id);
        if (cancelled) return;
        objectUrl = URL.createObjectURL(loaded);
        setBlob(loaded);
        setUrl(objectUrl);
        setFailed(false);
      } catch {
        if (!cancelled) setFailed(true);
      }
    })();

    return () => {
      cancelled = true;
      if (objectUrl) URL.revokeObjectURL(objectUrl);
    };
  }, [caseId, attachment.id, loadBlob]);

  const isImage = attachment.mimeType.startsWith('image/');
  const isPdf = attachment.mimeType === 'application/pdf';

  return (
    <article className="rounded-md border border-border bg-background p-3 space-y-3">
      <div className="aspect-[4/3] w-full overflow-hidden rounded-md border border-border/60 bg-background-secondary">
        {url && isImage ? (
          <img src={url} alt={attachment.fileName} className="h-full w-full object-contain" />
        ) : url && isPdf ? (
          <iframe src={url} title={attachment.fileName} className="h-full w-full border-0" />
        ) : (
          <div className="flex h-full w-full flex-col items-center justify-center gap-2 p-4 text-text-muted">
            <FileText className="h-10 w-10 shrink-0 icon-flat" aria-hidden />
            <span className="line-clamp-2 text-center text-xs">
              {failed ? t('attachmentPreviewUnavailable') : attachment.fileName}
            </span>
          </div>
        )}
      </div>

      <div className="flex items-start justify-between gap-3">
        <div className="min-w-0">
          <p className="text-sm font-medium text-text-primary truncate" title={attachment.fileName}>
            {attachment.fileName}
          </p>
          <p className="text-xs text-text-muted mt-0.5">
            {formatFileSize(attachment.sizeBytes)}
          </p>
        </div>
        <Button
          type="button"
          variant="outline"
          size="sm"
          className="shrink-0"
          disabled={!blob || downloading}
          onClick={() => {
            if (!blob) return;
            setDownloading(true);
            try {
              onDownload(blob, attachment.fileName);
            } finally {
              setDownloading(false);
            }
          }}
        >
          <Download className="h-4 w-4 me-1.5" />
          {t('downloadAttachment')}
        </Button>
      </div>
    </article>
  );
}

export function LabCaseAttachmentsDialog({
  open,
  onClose,
  caseId,
  attachments,
  loadBlob,
}: LabCaseAttachmentsDialogProps) {
  const t = useTranslations('cases');

  const sortedAttachments = [...attachments].sort(
    (a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime(),
  );

  const handleDownload = useCallback((blob: Blob, fileName: string) => {
    downloadBlob(blob, fileName);
  }, []);

  const [downloadingAll, setDownloadingAll] = useState(false);

  const handleDownloadAll = useCallback(async () => {
    if (sortedAttachments.length === 0) return;
    setDownloadingAll(true);
    try {
      for (const attachment of sortedAttachments) {
        const blob = await loadBlob(caseId, attachment.id);
        downloadBlob(blob, attachment.fileName);
      }
    } finally {
      setDownloadingAll(false);
    }
  }, [caseId, loadBlob, sortedAttachments]);

  if (!open) return null;

  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center p-4 bg-black/50">
      <div
        className="w-full max-w-3xl max-h-[90vh] overflow-y-auto rounded-[var(--radius-md)] border border-border bg-background-secondary p-6 shadow-xl space-y-4"
        role="dialog"
        aria-modal="true"
        aria-labelledby="case-attachments-title"
      >
        <div className="flex items-start justify-between gap-3">
          <div>
            <h2 id="case-attachments-title" className="text-lg font-semibold text-text-primary">
              {t('attachmentsDialogTitle')}
            </h2>
            <p className="text-sm text-text-muted mt-1">{t('attachmentsDialogSubtitle')}</p>
          </div>
          <div className="flex items-center gap-2 shrink-0">
            {sortedAttachments.length > 1 ? (
              <Button
                type="button"
                variant="outline"
                size="sm"
                disabled={downloadingAll}
                onClick={() => void handleDownloadAll()}
              >
                <Download className="h-4 w-4 me-1.5" />
                {t('downloadAllAttachments')}
              </Button>
            ) : null}
            <DialogCloseButton onClick={onClose} />
          </div>
        </div>

        {sortedAttachments.length === 0 ? (
          <p className="text-sm text-text-muted">{t('noAttachments')}</p>
        ) : (
          <div className="grid gap-4 sm:grid-cols-2">
            {sortedAttachments.map((attachment) => (
              <AttachmentPreviewTile
                key={attachment.id}
                caseId={caseId}
                attachment={attachment}
                loadBlob={loadBlob}
                onDownload={handleDownload}
              />
            ))}
          </div>
        )}
      </div>
    </div>
  );
}
