import { useState, useEffect, useCallback } from "react";
import { createPortal } from "react-dom";
import { FiX, FiChevronLeft, FiChevronRight, FiFile, FiDownload } from "react-icons/fi";
import type { PostContent } from "@/api/generated/private/models/postContent";
import { mediaUrl } from "@/utils/mediaUrl";

interface Props {
  items: readonly PostContent[];
}

export default function MediaGallery({ items }: Props) {
  const [lightboxIndex, setLightboxIndex] = useState<number | null>(null);

  // Grid shows first 4; lightbox navigates all
  const visible = items.slice(0, 4);
  const overflow = items.length - visible.length;
  const isOpen = lightboxIndex !== null;

  const prev = useCallback(() => {
    setLightboxIndex((i) => (i !== null ? (i - 1 + items.length) % items.length : null));
  }, [items.length]);

  const next = useCallback(() => {
    setLightboxIndex((i) => (i !== null ? (i + 1) % items.length : null));
  }, [items.length]);

  const close = useCallback(() => setLightboxIndex(null), []);

  useEffect(() => {
    if (!isOpen) return;
    function onKey(e: KeyboardEvent) {
      if (e.key === "Escape") close();
      if (e.key === "ArrowLeft") prev();
      if (e.key === "ArrowRight") next();
    }
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, [isOpen, close, prev, next]);

  if (!items?.length) return null;

  const layoutClass = visible.length === 1 ? "grid-cols-1" : "grid-cols-2";

  return (
    <>
      <div className={`mt-3 grid ${layoutClass} overflow-hidden rounded-xl border border-brand-lines/15`}>
        {visible.map((it, i) => (
          <MediaItem
            key={it.id}
            item={it}
            overflowCount={i === 3 && overflow > 0 ? overflow : 0}
            onOpen={() => setLightboxIndex(i)}
          />
        ))}
      </div>

      {isOpen &&
        createPortal(
          <div
            className="fixed inset-0 z-50 flex items-center justify-center bg-black/80 backdrop-blur-sm"
            onClick={close}
          >
            {/* Close */}
            <button
              type="button"
              onClick={close}
              className="absolute right-4 top-4 flex h-9 w-9 items-center justify-center rounded-full bg-white/10 text-white hover:bg-white/20 transition-colors"
              aria-label="Zavřít"
            >
              <FiX size={20} />
            </button>

            {/* Prev */}
            {items.length > 1 && (
              <button
                type="button"
                onClick={(e) => { e.stopPropagation(); prev(); }}
                className="absolute left-4 flex h-10 w-10 items-center justify-center rounded-full bg-white/10 text-white hover:bg-white/20 transition-colors"
                aria-label="Předchozí"
              >
                <FiChevronLeft size={24} />
              </button>
            )}

            {/* Content */}
            <LightboxContent item={items[lightboxIndex!]} />

            {/* Next */}
            {items.length > 1 && (
              <button
                type="button"
                onClick={(e) => { e.stopPropagation(); next(); }}
                className="absolute right-4 flex h-10 w-10 items-center justify-center rounded-full bg-white/10 text-white hover:bg-white/20 transition-colors"
                aria-label="Další"
              >
                <FiChevronRight size={24} />
              </button>
            )}

            {/* Dots */}
            {items.length > 1 && (
              <div
                className="absolute bottom-5 flex items-center gap-2"
                onClick={(e) => e.stopPropagation()}
              >
                {items.map((_: PostContent, i: number) => (
                  <button
                    key={i}
                    type="button"
                    onClick={() => setLightboxIndex(i)}
                    aria-label={`Položka ${i + 1}`}
                    className={[
                      "h-2 rounded-full transition-all duration-200",
                      i === lightboxIndex ? "w-5 bg-white" : "w-2 bg-white/40 hover:bg-white/70",
                    ].join(" ")}
                  />
                ))}
              </div>
            )}
          </div>,
          document.body,
        )}
    </>
  );
}

function LightboxContent({ item }: { item: PostContent }) {
  const url = mediaUrl(item.file) ?? "";
  const mime = item.mime_type ?? "";

  if (mime.startsWith("video/")) {
    return (
      <video
        src={url}
        controls
        className="max-h-[90vh] max-w-[90vw] rounded-xl shadow-2xl"
        onClick={(e) => e.stopPropagation()}
      />
    );
  }

  if (mime.startsWith("image/")) {
    return (
      <img
        src={url}
        alt={item.alt_text ?? ""}
        className="max-h-[90vh] max-w-[90vw] rounded-xl object-contain shadow-2xl select-none"
        onClick={(e) => e.stopPropagation()}
        draggable={false}
      />
    );
  }

  const filename = url.split("/").pop() ?? "soubor";
  return (
    <a
      href={url}
      download
      target="_blank"
      rel="noreferrer"
      onClick={(e) => e.stopPropagation()}
      className="flex flex-col items-center gap-4 rounded-2xl border border-white/20 bg-white/10 px-10 py-8 text-white hover:bg-white/20 transition-colors"
    >
      <FiFile size={48} />
      <span className="max-w-xs truncate text-sm">{filename}</span>
      <FiDownload size={20} className="opacity-70" />
    </a>
  );
}

function MediaItem({
  item,
  onOpen,
  overflowCount = 0,
}: {
  item: PostContent;
  onOpen: () => void;
  overflowCount?: number;
}) {
  const url = mediaUrl(item.file) ?? "";
  const mime = item.mime_type ?? "";

  const overlay = overflowCount > 0 ? (
    <div
      className="absolute inset-0 flex items-center justify-center bg-black/55 cursor-pointer"
      onClick={(e) => { e.stopPropagation(); onOpen(); }}
    >
      <span className="text-3xl font-semibold text-white">+{overflowCount}</span>
    </div>
  ) : null;

  if (mime.startsWith("video/")) {
    return (
      <div className="relative aspect-square w-full bg-black cursor-pointer" onClick={(e) => { e.stopPropagation(); onOpen(); }}>
        <video src={url} muted playsInline preload="metadata" className="h-full w-full object-cover pointer-events-none" />
        <div className="absolute inset-0 flex items-center justify-center bg-black/20">
          <div className="flex h-10 w-10 items-center justify-center rounded-full bg-white/20">
            <svg viewBox="0 0 24 24" fill="white" className="h-5 w-5 translate-x-0.5"><path d="M8 5v14l11-7z"/></svg>
          </div>
        </div>
        {overlay}
      </div>
    );
  }

  if (mime.startsWith("image/")) {
    return (
      <div className="relative aspect-square w-full bg-brand-bg/60">
        <img
          src={url}
          alt={item.alt_text ?? ""}
          className="h-full w-full cursor-zoom-in object-cover transition-opacity hover:opacity-90"
          loading="lazy"
          onClick={(e) => { e.stopPropagation(); onOpen(); }}
        />
        {overlay}
      </div>
    );
  }

  const filename = url.split("/").pop() ?? "soubor";
  return (
    <div className="relative aspect-square w-full p-2">
      <a
        href={url}
        download
        target="_blank"
        rel="noreferrer"
        onClick={(e) => e.stopPropagation()}
        className="flex h-full w-full flex-col items-center justify-center gap-2 rounded-xl border border-brand-lines/20 bg-brand-bgLight/30 px-3 hover:bg-brand-lines/10 transition-colors"
      >
        <FiFile size={28} className="text-brand-text/40" />
        <span className="w-full truncate text-center text-[11px] text-brand-text/60 leading-tight">{filename}</span>
        <FiDownload size={13} className="text-brand-text/30" />
      </a>
      {overlay}
    </div>
  );
}
