"use client";

import { useState, useEffect, useCallback, useMemo, useRef } from "react";
import {
  ChevronLeft,
  ChevronRight,
  Download,
  FileText,
  Minus,
  Plus,
  Printer,
  X,
} from "lucide-react";
import { Button } from "@/shared/components/ui/button";
import type { RegistryAttachment } from "../types";
import { cn } from "@/shared/lib/utils";

interface AttachmentPreviewProps {
  /** All previewable attachments (non-NAS, with data) */
  attachments: RegistryAttachment[];
  /** Currently selected attachment index */
  initialIndex: number;
  /** Whether the preview is open */
  open: boolean;
  /** Close handler */
  onClose: () => void;
}

const ZOOM_MIN = 0.25;
const ZOOM_MAX = 5;
const ZOOM_STEP = 0.25;

/** Check if a MIME type can be previewed */
function isPreviewable(type: string): boolean {
  return type.startsWith("image/") || type === "application/pdf";
}

/** Filter to only previewable attachments with inline data */
export function getPreviewableAttachments(
  attachments: RegistryAttachment[],
): RegistryAttachment[] {
  return attachments.filter(
    (a) =>
      a.data &&
      a.data !== "" &&
      a.data !== "__network__" &&
      isPreviewable(a.type),
  );
}

export function AttachmentPreview({
  attachments,
  initialIndex,
  open,
  onClose,
}: AttachmentPreviewProps) {
  const [currentIndex, setCurrentIndex] = useState(initialIndex);
  const [zoom, setZoom] = useState(1);
  const [pan, setPan] = useState({ x: 0, y: 0 });
  const [isPanning, setIsPanning] = useState(false);
  const panStart = useRef({ x: 0, y: 0, panX: 0, panY: 0 });
  const containerRef = useRef<HTMLDivElement>(null);

  const resetView = useCallback(() => {
    setZoom(1);
    setPan({ x: 0, y: 0 });
  }, []);

  const navigateTo = useCallback(
    (index: number) => {
      setCurrentIndex(index);
      resetView();
    },
    [resetView],
  );

  const att = attachments[currentIndex];
  const hasMultiple = attachments.length > 1;
  const isImage = att?.type.startsWith("image/");
  const isPdf = att?.type === "application/pdf";

  // Build blob URL for PDF viewer (more reliable than data: URI in iframes)
  const pdfBlobUrl = useMemo(() => {
    if (!isPdf || !att?.data) return null;
    try {
      // data is a data URI like "data:application/pdf;base64,..."
      const base64 = att.data.split(",")[1];
      if (!base64) return null;
      const bytes = atob(base64);
      const arr = new Uint8Array(bytes.length);
      for (let i = 0; i < bytes.length; i++) arr[i] = bytes.charCodeAt(i);
      const blob = new Blob([arr], { type: "application/pdf" });
      return URL.createObjectURL(blob);
    } catch {
      return null;
    }
  }, [isPdf, att?.data]);

  // Revoke blob URL on cleanup
  useEffect(() => {
    return () => {
      if (pdfBlobUrl) URL.revokeObjectURL(pdfBlobUrl);
    };
  }, [pdfBlobUrl]);

  // Keyboard navigation
  useEffect(() => {
    if (!open) return;
    const handleKey = (e: KeyboardEvent) => {
      switch (e.key) {
        case "Escape":
          onClose();
          break;
        case "ArrowLeft":
          e.preventDefault();
          if (hasMultiple)
            setCurrentIndex((i) => {
              const next = i > 0 ? i - 1 : attachments.length - 1;
              resetView();
              return next;
            });
          break;
        case "ArrowRight":
          e.preventDefault();
          if (hasMultiple)
            setCurrentIndex((i) => {
              const next = i < attachments.length - 1 ? i + 1 : 0;
              resetView();
              return next;
            });
          break;
        case "+":
        case "=":
          e.preventDefault();
          setZoom((z) => Math.min(z + ZOOM_STEP, ZOOM_MAX));
          break;
        case "-":
          e.preventDefault();
          setZoom((z) => Math.max(z - ZOOM_STEP, ZOOM_MIN));
          break;
        case "0":
          e.preventDefault();
          setZoom(1);
          setPan({ x: 0, y: 0 });
          break;
      }
    };
    window.addEventListener("keydown", handleKey);
    return () => window.removeEventListener("keydown", handleKey);
  }, [open, hasMultiple, attachments.length, onClose, resetView]);

  // Mouse wheel zoom (images only)
  const handleWheel = useCallback(
    (e: React.WheelEvent) => {
      if (!isImage) return;
      e.preventDefault();
      const delta = e.deltaY > 0 ? -ZOOM_STEP : ZOOM_STEP;
      setZoom((z) => Math.max(ZOOM_MIN, Math.min(z + delta, ZOOM_MAX)));
    },
    [isImage],
  );

  // Pan handling (images only, when zoomed in)
  const handleMouseDown = useCallback(
    (e: React.MouseEvent) => {
      if (!isImage || zoom <= 1) return;
      e.preventDefault();
      setIsPanning(true);
      panStart.current = {
        x: e.clientX,
        y: e.clientY,
        panX: pan.x,
        panY: pan.y,
      };
    },
    [isImage, zoom, pan],
  );

  const handleMouseMove = useCallback(
    (e: React.MouseEvent) => {
      if (!isPanning) return;
      setPan({
        x: panStart.current.panX + (e.clientX - panStart.current.x),
        y: panStart.current.panY + (e.clientY - panStart.current.y),
      });
    },
    [isPanning],
  );

  const handleMouseUp = useCallback(() => {
    setIsPanning(false);
  }, []);

  const goNext = useCallback(() => {
    setCurrentIndex((i) => {
      const next = i < attachments.length - 1 ? i + 1 : 0;
      resetView();
      return next;
    });
  }, [attachments.length, resetView]);

  const goPrev = useCallback(() => {
    setCurrentIndex((i) => {
      const next = i > 0 ? i - 1 : attachments.length - 1;
      resetView();
      return next;
    });
  }, [attachments.length, resetView]);

  const handleDownload = useCallback(() => {
    if (!att) return;
    const a = document.createElement("a");
    a.href = att.data;
    a.download = att.name;
    a.click();
  }, [att]);

  const handlePrint = useCallback(() => {
    if (!att) return;
    if (isPdf && pdfBlobUrl) {
      const iframe = document.createElement("iframe");
      iframe.style.display = "none";
      iframe.src = pdfBlobUrl;
      document.body.appendChild(iframe);
      iframe.onload = () => {
        iframe.contentWindow?.print();
        setTimeout(() => document.body.removeChild(iframe), 1000);
      };
    } else if (isImage) {
      const w = window.open("", "_blank");
      if (w) {
        w.document.write(
          `<html><head><title>${att.name}</title></head><body style="margin:0;display:flex;justify-content:center;align-items:center;min-height:100vh;background:#111"><img src="${att.data}" style="max-width:100%;max-height:100vh;object-fit:contain"/></body></html>`,
        );
        w.document.close();
        w.onload = () => w.print();
      }
    }
  }, [att, isPdf, pdfBlobUrl, isImage]);

  if (!open || !att) return null;

  const fileExt =
    att.name.split(".").pop()?.toUpperCase() ??
    att.type.split("/")[1]?.toUpperCase() ??
    "FILE";

  return (
    <div className="fixed inset-0 z-[100] flex flex-col bg-black/90 backdrop-blur-sm animate-in fade-in duration-200">
      {/* ── Top bar ── */}
      <div className="flex items-center justify-between px-4 py-2.5 bg-black/60 border-b border-white/10 shrink-0">
        <div className="flex items-center gap-3 min-w-0">
          <FileText className="h-4 w-4 text-white/70 shrink-0" />
          <div className="min-w-0">
            <p className="text-sm font-medium text-white truncate">
              {att.name}
            </p>
            <p className="text-[11px] text-white/50">
              {(att.size / 1024).toFixed(0)} KB • {fileExt}
              {hasMultiple && (
                <span className="ml-2">
                  {currentIndex + 1} / {attachments.length}
                </span>
              )}
            </p>
          </div>
        </div>

        <div className="flex items-center gap-1 shrink-0">
          {/* Zoom controls (images only) */}
          {isImage && (
            <>
              <Button
                variant="ghost"
                size="icon"
                className="h-8 w-8 text-white/70 hover:text-white hover:bg-white/10"
                onClick={() =>
                  setZoom((z) => Math.max(z - ZOOM_STEP, ZOOM_MIN))
                }
                title="Micșorează (−)"
              >
                <Minus className="h-4 w-4" />
              </Button>
              <button
                type="button"
                className="px-2 text-xs text-white/70 hover:text-white font-mono min-w-[3.5rem] text-center"
                onClick={() => {
                  setZoom(1);
                  setPan({ x: 0, y: 0 });
                }}
                title="Resetează zoom (0)"
              >
                {Math.round(zoom * 100)}%
              </button>
              <Button
                variant="ghost"
                size="icon"
                className="h-8 w-8 text-white/70 hover:text-white hover:bg-white/10"
                onClick={() =>
                  setZoom((z) => Math.min(z + ZOOM_STEP, ZOOM_MAX))
                }
                title="Mărește (+)"
              >
                <Plus className="h-4 w-4" />
              </Button>
              <div className="w-px h-5 bg-white/20 mx-1" />
            </>
          )}

          <Button
            variant="ghost"
            size="icon"
            className="h-8 w-8 text-white/70 hover:text-white hover:bg-white/10"
            onClick={handlePrint}
            title="Printează"
          >
            <Printer className="h-4 w-4" />
          </Button>
          <Button
            variant="ghost"
            size="icon"
            className="h-8 w-8 text-white/70 hover:text-white hover:bg-white/10"
            onClick={handleDownload}
            title="Descarcă"
          >
            <Download className="h-4 w-4" />
          </Button>
          <div className="w-px h-5 bg-white/20 mx-1" />
          <Button
            variant="ghost"
            size="icon"
            className="h-8 w-8 text-white/70 hover:text-white hover:bg-white/10"
            onClick={onClose}
            title="Închide (Esc)"
          >
            <X className="h-4 w-4" />
          </Button>
        </div>
      </div>

      {/* ── Content area ── */}
      <div
        ref={containerRef}
        className={cn(
          "flex-1 relative overflow-hidden flex items-center justify-center",
          isImage && zoom > 1 && "cursor-grab",
          isPanning && "cursor-grabbing",
        )}
        onWheel={handleWheel}
        onMouseDown={handleMouseDown}
        onMouseMove={handleMouseMove}
        onMouseUp={handleMouseUp}
        onMouseLeave={handleMouseUp}
      >
        {/* Navigation arrows */}
        {hasMultiple && (
          <>
            <button
              type="button"
              className="absolute left-3 top-1/2 -translate-y-1/2 z-10 flex items-center justify-center w-10 h-10 rounded-full bg-black/50 text-white/70 hover:text-white hover:bg-black/70 transition-colors"
              onClick={(e) => {
                e.stopPropagation();
                goPrev();
              }}
              title="Anterior (←)"
            >
              <ChevronLeft className="h-5 w-5" />
            </button>
            <button
              type="button"
              className="absolute right-3 top-1/2 -translate-y-1/2 z-10 flex items-center justify-center w-10 h-10 rounded-full bg-black/50 text-white/70 hover:text-white hover:bg-black/70 transition-colors"
              onClick={(e) => {
                e.stopPropagation();
                goNext();
              }}
              title="Următor (→)"
            >
              <ChevronRight className="h-5 w-5" />
            </button>
          </>
        )}

        {/* Image preview */}
        {isImage && (
          /* eslint-disable-next-line @next/next/no-img-element */
          <img
            src={att.data}
            alt={att.name}
            className="select-none transition-transform duration-150"
            style={{
              transform: `translate(${pan.x}px, ${pan.y}px) scale(${zoom})`,
              maxWidth: zoom <= 1 ? "90%" : undefined,
              maxHeight: zoom <= 1 ? "90%" : undefined,
              objectFit: "contain",
            }}
            draggable={false}
          />
        )}

        {/* PDF preview */}
        {isPdf && pdfBlobUrl && (
          <iframe
            src={pdfBlobUrl}
            className="w-full h-full border-0"
            title={att.name}
          />
        )}

        {/* PDF without blob fallback */}
        {isPdf && !pdfBlobUrl && (
          <div className="text-center space-y-4 p-8">
            <FileText className="h-16 w-16 text-white/30 mx-auto" />
            <p className="text-white/60 text-sm">
              Previzualizarea PDF nu este disponibilă.
            </p>
            <Button
              variant="outline"
              className="border-white/20 text-white hover:bg-white/10"
              onClick={handleDownload}
            >
              <Download className="mr-2 h-4 w-4" /> Descarcă fișierul
            </Button>
          </div>
        )}

        {/* Unsupported type fallback */}
        {!isImage && !isPdf && (
          <div className="text-center space-y-4 p-8">
            <FileText className="h-16 w-16 text-white/30 mx-auto" />
            <p className="text-white/60 text-sm">
              Previzualizare indisponibilă pentru {fileExt}.
            </p>
            <Button
              variant="outline"
              className="border-white/20 text-white hover:bg-white/10"
              onClick={handleDownload}
            >
              <Download className="mr-2 h-4 w-4" /> Descarcă fișierul
            </Button>
          </div>
        )}
      </div>

      {/* ── Bottom thumbnails (when multiple) ── */}
      {hasMultiple && (
        <div className="flex items-center justify-center gap-2 px-4 py-2 bg-black/60 border-t border-white/10 shrink-0 overflow-x-auto">
          {attachments.map((a, idx) => (
            <button
              key={a.id}
              type="button"
              className={cn(
                "shrink-0 rounded border-2 transition-all",
                idx === currentIndex
                  ? "border-white/80 ring-1 ring-white/30"
                  : "border-transparent opacity-50 hover:opacity-80",
              )}
              onClick={() => navigateTo(idx)}
              title={a.name}
            >
              {a.type.startsWith("image/") ? (
                /* eslint-disable-next-line @next/next/no-img-element */
                <img
                  src={a.data}
                  alt={a.name}
                  className="h-10 w-14 object-cover rounded"
                  draggable={false}
                />
              ) : (
                <div className="h-10 w-14 flex items-center justify-center bg-white/10 rounded">
                  <FileText className="h-4 w-4 text-white/70" />
                </div>
              )}
            </button>
          ))}
        </div>
      )}
    </div>
  );
}
