"use client";

import { useEffect, useMemo, useState } from "react";
import Image from "next/image";
import { useTranslations } from "next-intl";
import { ScrollReveal } from "@/components/ScrollReveal";

export type GalleryItem = {
  id: string;
  title: string;
  description: string;
  category: string;
  eventLabel: string;
  tags: string[];
  modelInstagram: string[];
  images: string[];
  coverImage: string;
};

function normalizeInstagramHref(value: string): string {
  const raw = value.trim();
  if (!raw) return "";
  if (/^https?:\/\//i.test(raw)) return raw;
  const handle = raw
    .replace(/^@+/, "")
    .replace(/^instagram\.com\//i, "")
    .replace(/^www\.instagram\.com\//i, "")
    .split(/[/?#]/)[0];
  return handle ? `https://instagram.com/${handle}` : "";
}

function instagramLabel(value: string): string {
  const raw = value.trim();
  if (raw.startsWith("@")) return raw;
  const handle = raw.replace(/^https?:\/\/(www\.)?instagram\.com\//i, "").split(/[/?#]/)[0];
  return handle ? `@${handle}` : raw;
}

function MetaChips({ item, t }: { item: GalleryItem; t: ReturnType<typeof useTranslations> }) {
  const chips: { label: string; value: string }[] = [];
  if (item.category) chips.push({ label: t("categoryLabel"), value: item.category });
  if (item.eventLabel) chips.push({ label: t("eventLabel"), value: item.eventLabel });
  if (item.tags.length) chips.push({ label: t("tagsLabel"), value: item.tags.join(" · ") });
  if (!chips.length) return null;

  return (
    <div className="flex flex-wrap gap-2">
      {chips.map((chip) => (
        <span
          key={chip.label}
          className="rounded-full border border-white/15 px-2.5 py-1 text-[0.68rem] uppercase tracking-[0.08em] text-[var(--rk-ink-muted)]"
        >
          <span className="opacity-70">{chip.label}:</span> <span className="text-[var(--rk-ink)]">{chip.value}</span>
        </span>
      ))}
    </div>
  );
}

function CreditLinks({
  item,
  photographerInstagram,
  t,
}: {
  item: GalleryItem;
  photographerInstagram: string;
  t: ReturnType<typeof useTranslations>;
}) {
  const links: { href: string; label: string; icon: string }[] = [];
  const photoHref = normalizeInstagramHref(photographerInstagram);
  if (photoHref) links.push({ href: photoHref, label: t("photographerCredit"), icon: "📸" });
  item.modelInstagram.forEach((handle) => {
    const href = normalizeInstagramHref(handle);
    if (href) links.push({ href, label: instagramLabel(handle), icon: "👤" });
  });
  if (!links.length) return null;

  return (
    <div className="flex flex-wrap gap-x-4 gap-y-1">
      {links.map((link) => (
        <a
          key={link.href}
          href={link.href}
          target="_blank"
          rel="noopener noreferrer"
          onClick={(e) => e.stopPropagation()}
          className="text-xs text-[var(--rk-ink-muted)] transition-colors hover:text-[var(--rk-ink)]"
        >
          {link.icon} {link.label}
        </a>
      ))}
    </div>
  );
}

// Feste, zentrierte Inhaltsspalte — 1120px, exakt wie die Mockup-Leinwand.
// Bewusst KEIN rk-shell/vw-Gutter und kein bis 1600px mitwachsendes Raster:
// die Seite soll auf FHD, 4K und einem 14"-Notebook pixelgleich aussehen,
// nur der Außenrand wächst (Merkblatt-Regel, Runde 138). Seitliche px-Werte
// sind feste Stufen, keine vw-Rechnung.
const PAGE_COL = "mx-auto w-full max-w-[1120px] px-5 sm:px-8";

export function PortfolioGallery({
  items,
  categories,
  photographerInstagram,
}: {
  items: GalleryItem[];
  categories: string[];
  photographerInstagram: string;
}) {
  const t = useTranslations("portfolio");
  const [activeCategory, setActiveCategory] = useState<string>("all");
  const [openId, setOpenId] = useState<string | null>(null);
  const [imgIndex, setImgIndex] = useState(0);
  const PAGE_SIZE = 24;
  const [visibleCount, setVisibleCount] = useState(PAGE_SIZE);

  const filtered = useMemo(
    () => items.filter((i) => activeCategory === "all" || i.category === activeCategory),
    [items, activeCategory]
  );

  // Reduziert die auf einmal ins DOM gerenderten (und damit angefragten)
  // Bilder — vorher wurden bei vielen Portfolio-Einträgen alle sofort
  // gerendert, was spürbares Lag verursachte. Beim Filterwechsel wieder von
  // vorne anzeigen.
  useEffect(() => setVisibleCount(PAGE_SIZE), [activeCategory]);
  const visible = filtered.slice(0, visibleCount);

  // Der eine bewusste strukturelle Bruch der Seite (Mockup: PortfolioFull) —
  // der chronologisch NEUESTE sichtbare Beitrag (nie eine "Featured"-Auswahl,
  // siehe Merkblatt-Regel) läuft groß über die volle Spaltenbreite, bevor das
  // gleichmäßige Raster beginnt. `items` ist bereits chronologisch sortiert
  // (createdAt: -1); Filtern ändert die Reihenfolge nicht, `visible[0]` ist
  // also immer der richtige Kandidat, auch nach "Mehr laden".
  const [lead, ...rest] = visible;

  const openItem = items.find((i) => i.id === openId) || null;

  useEffect(() => {
    if (!openItem) return;

    const onKeyDown = (e: KeyboardEvent) => {
      if (e.key === "Escape") setOpenId(null);
      if (e.key === "ArrowLeft") setImgIndex((i) => (i - 1 + openItem.images.length) % openItem.images.length);
      if (e.key === "ArrowRight") setImgIndex((i) => (i + 1) % openItem.images.length);
    };
    document.addEventListener("keydown", onKeyDown);
    document.body.style.overflow = "hidden";
    return () => {
      document.removeEventListener("keydown", onKeyDown);
      document.body.style.overflow = "";
    };
  }, [openItem]);

  const openLightbox = (item: GalleryItem) => {
    setOpenId(item.id);
    const coverIndex = item.images.indexOf(item.coverImage);
    setImgIndex(coverIndex >= 0 ? coverIndex : 0);
  };

  return (
    <>
      {/* Sticky-Filterleiste, 1:1 nach dem bestätigten Mockup (Portfolio.jpg,
          09.09.2026): eigener „Balken" — die Leiste bleibt --rk-bg mit
          translucent/blur (rgba(16,16,18,0.85)) und einer feinen
          Kupfer-Linie unten (rgba(201,138,75,0.25)), während der Galerie-
          Bereich darunter über einen Verlauf leicht Richtung --rk-surface
          driftet (siehe portfolio/page.tsx). Dadurch hebt sich der Balken
          dezent ab. Nur die eine Kategorie-Zeile (keine Tag-Zeile). Er
          parkt unter dem schwebenden Header (top = Header-Höhe). */}
      {categories.length > 1 && (
        <div className="sticky top-[4.5rem] z-20 border-b border-[#0f1011] bg-[#101012]">
          <div className={`${PAGE_COL} flex flex-wrap justify-center gap-2 py-6`}>
            <button
              type="button"
              onClick={() => setActiveCategory("all")}
              className={`rounded-full border px-4 py-2 text-xs uppercase tracking-[0.15em] transition-colors ${
                activeCategory === "all"
                  ? "border-[var(--rk-accent)] bg-[var(--rk-accent)] font-semibold text-[#141413]"
                  : "border-white/15 text-[var(--rk-ink-muted)] hover:border-white/40"
              }`}
            >
              {t("filterAll")}
            </button>
            {categories.map((cat) => (
              <button
                key={cat}
                type="button"
                onClick={() => setActiveCategory(cat)}
                className={`rounded-full border px-4 py-2 text-xs uppercase tracking-[0.15em] transition-colors ${
                  activeCategory === cat
                    ? "border-[var(--rk-accent)] bg-[var(--rk-accent)] font-semibold text-[#141413]"
                    : "border-white/15 text-[var(--rk-ink-muted)] hover:border-white/40"
                }`}
              >
                {cat}
              </button>
            ))}
          </div>
        </div>
      )}

      <div className={`${PAGE_COL} pt-12`}>
        {/* Großes Aufmacherbild = neuester Beitrag, Titel + Kategorie direkt
            aufs Foto (Scrim unten). Festes 21:9 in der festen Spalte →
            überall exakt 1120×480. */}
        {lead && (
          <ScrollReveal className="mb-7">
            <button
              type="button"
              onClick={() => openLightbox(lead)}
              className="rk-lift group relative block aspect-[16/9] w-full overflow-hidden text-left sm:aspect-[21/9]"
            >
              <Image
                src={lead.coverImage || lead.images[0]}
                alt={lead.title}
                fill
                sizes="1120px"
                priority
                className="object-cover transition-transform duration-700 ease-out group-hover:scale-105"
              />
              <div className="absolute inset-0 [background:linear-gradient(180deg,transparent_45%,rgba(16,16,18,0.85))]" />
              <div className="absolute inset-0 ring-1 ring-inset ring-white/10" />
              {lead.images.length > 1 && (
                <span className="absolute right-4 top-4 rounded-full bg-black/60 px-2 py-1 text-[0.65rem] uppercase tracking-[0.1em] text-[var(--rk-ink)] backdrop-blur">
                  {t("imageCount", { count: lead.images.length })}
                </span>
              )}
              <div className="absolute bottom-5 left-5 sm:bottom-7 sm:left-8">
                <p className="rk-wordmark text-xl drop-shadow-[0_2px_16px_rgba(0,0,0,0.8)] sm:text-3xl">{lead.title}</p>
                {(lead.category || lead.eventLabel) && (
                  <p className="mt-1.5 text-xs uppercase tracking-[0.15em] text-[var(--rk-accent)] drop-shadow-[0_1px_8px_rgba(0,0,0,0.9)]">
                    {[lead.category, lead.eventLabel].filter(Boolean).join(" · ")}
                  </p>
                )}
              </div>
            </button>
          </ScrollReveal>
        )}

        {/* Einheitliches 3-Spalten-Raster (Merkblatt: doch fester 3:4-Zuschnitt
            wie live, kein Masonry). Feste Spaltenzahl — kein Wachsen auf 4
            Spalten bei breiten Monitoren. Titel + Kategorie aufs Foto, wie
            beim Aufmacher, nur kleiner. Volltext/Chips/Credits bleiben in der
            Lightbox. */}
        <div className="grid grid-cols-1 gap-3.5 sm:grid-cols-2 lg:grid-cols-3">
          {rest.map((item, i) => (
            <ScrollReveal key={item.id} delayMs={(i % 3) * 100}>
              <button
                type="button"
                onClick={() => openLightbox(item)}
                className="rk-lift group relative block aspect-[3/4] w-full overflow-hidden text-left"
              >
                <Image
                  src={item.coverImage || item.images[0]}
                  alt={item.title}
                  fill
                  sizes="(min-width: 640px) 50vw, 100vw"
                  className="object-cover transition-transform duration-700 ease-out group-hover:scale-105"
                />
                <div className="absolute inset-0 [background:linear-gradient(180deg,transparent_50%,rgba(16,16,18,0.85))]" />
                <div className="absolute inset-0 ring-1 ring-inset ring-white/10" />
                {item.images.length > 1 && (
                  <span className="absolute right-3 top-3 rounded-full bg-black/60 px-2 py-1 text-[0.65rem] uppercase tracking-[0.1em] text-[var(--rk-ink)] backdrop-blur">
                    {t("imageCount", { count: item.images.length })}
                  </span>
                )}
                <div className="absolute bottom-4 left-4 sm:bottom-5 sm:left-5">
                  <p className="rk-wordmark text-sm drop-shadow-[0_2px_12px_rgba(0,0,0,0.8)] sm:text-base">{item.title}</p>
                  {item.category && (
                    <p className="mt-1 text-xs text-[var(--rk-accent)] drop-shadow-[0_1px_8px_rgba(0,0,0,0.9)]">
                      {item.category}
                    </p>
                  )}
                </div>
              </button>
            </ScrollReveal>
          ))}
        </div>

        {filtered.length > visibleCount && (
          <div className="mt-10 flex justify-center">
            <button
              type="button"
              onClick={() => setVisibleCount((v) => v + PAGE_SIZE)}
              className="rounded-lg border border-white/30 px-6 py-2.5 text-xs uppercase tracking-[0.2em] text-[var(--rk-ink)] transition-colors hover:border-white hover:bg-white/5"
            >
              {t("loadMore")}
            </button>
          </div>
        )}
      </div>

      {openItem && (
        <div
          className="fixed inset-0 z-50 flex items-center justify-center bg-black/90 p-4 backdrop-blur-sm sm:p-8"
          onClick={() => setOpenId(null)}
        >
          <button
            type="button"
            aria-label={t("close")}
            onClick={() => setOpenId(null)}
            className="absolute right-5 top-5 flex h-10 w-10 items-center justify-center border border-white/20 text-[var(--rk-ink)] hover:border-white/60"
          >
            ✕
          </button>

          {/* Kein enger max-w-Deckel — auf großen Monitoren soll sich das Foto
              in der Lightbox tatsächlich groß zeigen lassen; der Abstand zum
              Bildschirmrand kommt schon vom p-4 sm:p-8 des Overlays. */}
          <div
            className="relative flex max-h-full w-full max-w-[92rem] flex-col items-center overflow-y-auto"
            onClick={(e) => e.stopPropagation()}
          >
            <div className="relative w-full shrink-0 aspect-[4/3] sm:aspect-[16/10]">
              <Image
                src={openItem.images[imgIndex]}
                alt={openItem.title}
                fill
                sizes="90vw"
                className="object-contain"
                priority
              />
              {openItem.images.length > 1 && (
                <>
                  <button
                    type="button"
                    aria-label={t("prevImage")}
                    onClick={() => setImgIndex((i) => (i - 1 + openItem.images.length) % openItem.images.length)}
                    className="absolute left-0 top-1/2 flex h-11 w-11 -translate-y-1/2 items-center justify-center text-[var(--rk-ink)] hover:opacity-70"
                  >
                    ‹
                  </button>
                  <button
                    type="button"
                    aria-label={t("nextImage")}
                    onClick={() => setImgIndex((i) => (i + 1) % openItem.images.length)}
                    className="absolute right-0 top-1/2 flex h-11 w-11 -translate-y-1/2 items-center justify-center text-[var(--rk-ink)] hover:opacity-70"
                  >
                    ›
                  </button>
                </>
              )}
            </div>

            {openItem.images.length > 1 && (
              <div className="mt-4 flex max-w-full shrink-0 gap-2 overflow-x-auto px-2 py-1">
                {openItem.images.map((src, i) => (
                  <button
                    key={src}
                    type="button"
                    onClick={() => setImgIndex(i)}
                    className={`relative h-14 w-11 shrink-0 overflow-hidden rounded ${
                      i === imgIndex ? "ring-2 ring-white" : "opacity-70 ring-1 ring-white/15 hover:opacity-100"
                    }`}
                  >
                    <Image src={src} alt="" fill sizes="44px" className="object-cover" />
                  </button>
                ))}
              </div>
            )}

            <div className="mt-6 max-w-xl shrink-0 text-center">
              <h2 className="rk-wordmark text-xl">{openItem.title}</h2>
              <div className="mt-3 flex justify-center">
                <MetaChips item={openItem} t={t} />
              </div>
              <p className="mt-4 whitespace-pre-line text-sm leading-relaxed text-[var(--rk-ink-muted)]">
                {openItem.description}
              </p>
              <div className="mt-4 flex justify-center">
                <CreditLinks item={openItem} photographerInstagram={photographerInstagram} t={t} />
              </div>
            </div>
          </div>
        </div>
      )}
    </>
  );
}
