import { useQuery } from "@tanstack/react-query";
import { useState, useEffect, useCallback } from "react";
import { ChevronLeft, ChevronRight, X, Images, Maximize2 } from "lucide-react";

interface GalleryImage {
  folder: string;
  fileName: string;
  thumb: string;
  large: string;
}

function Lightbox({
  images,
  startIndex,
  onClose,
}: {
  images: GalleryImage[];
  startIndex: number;
  onClose: () => void;
}) {
  const [index, setIndex] = useState(startIndex);

  const prev = useCallback(() => setIndex((i) => (i - 1 + images.length) % images.length), [images.length]);
  const next = useCallback(() => setIndex((i) => (i + 1) % images.length), [images.length]);

  useEffect(() => {
    const handler = (e: KeyboardEvent) => {
      if (e.key === "Escape") onClose();
      if (e.key === "ArrowLeft") prev();
      if (e.key === "ArrowRight") next();
    };
    window.addEventListener("keydown", handler);
    return () => window.removeEventListener("keydown", handler);
  }, [onClose, prev, next]);

  return (
    <div
      className="fixed inset-0 z-50 bg-black/95 flex items-center justify-center"
      onClick={onClose}
      data-testid="lightbox-overlay"
    >
      <button
        onClick={(e) => { e.stopPropagation(); onClose(); }}
        className="absolute top-4 right-4 text-white/70 hover:text-white z-50 p-2"
        data-testid="button-lightbox-close"
      >
        <X className="w-8 h-8" />
      </button>

      <button
        onClick={(e) => { e.stopPropagation(); prev(); }}
        className="absolute left-2 md:left-6 text-white/70 hover:text-white z-50 p-2"
        data-testid="button-lightbox-prev"
      >
        <ChevronLeft className="w-10 h-10" />
      </button>

      <button
        onClick={(e) => { e.stopPropagation(); next(); }}
        className="absolute right-2 md:right-6 text-white/70 hover:text-white z-50 p-2"
        data-testid="button-lightbox-next"
      >
        <ChevronRight className="w-10 h-10" />
      </button>

      <div className="max-w-[90vw] max-h-[85vh] flex items-center justify-center" onClick={(e) => e.stopPropagation()}>
        <img
          src={images[index].large}
          alt={images[index].fileName}
          className="max-w-full max-h-[85vh] object-contain rounded-lg"
          data-testid="img-lightbox"
        />
      </div>

      <div className="absolute bottom-4 text-white/60 text-sm" data-testid="text-lightbox-counter">
        {index + 1} / {images.length}
      </div>
    </div>
  );
}

function SingleImageCarousel({
  images,
  autoPlay = true,
  interval = 5000,
  onExpand,
}: {
  images: GalleryImage[];
  autoPlay?: boolean;
  interval?: number;
  onExpand?: (index: number) => void;
}) {
  const [index, setIndex] = useState(0);
  const [paused, setPaused] = useState(false);

  const prev = useCallback(() => setIndex((i) => (i - 1 + images.length) % images.length), [images.length]);
  const next = useCallback(() => setIndex((i) => (i + 1) % images.length), [images.length]);

  useEffect(() => {
    if (!autoPlay || paused || images.length <= 1) return;
    const timer = setInterval(next, interval);
    return () => clearInterval(timer);
  }, [autoPlay, paused, next, interval, images.length]);

  if (images.length === 0) return null;

  return (
    <div
      className="relative w-full h-full"
      onMouseEnter={() => setPaused(true)}
      onMouseLeave={() => setPaused(false)}
    >
      <div className="relative w-full aspect-[4/5] overflow-hidden rounded-b-lg">
        <img
          src={images[index].large || images[index].thumb}
          alt={images[index].fileName}
          className="w-full h-full object-cover transition-opacity duration-500"
          style={{ objectPosition: "center 25%" }}
          loading="lazy"
          data-testid="img-gallery-current"
        />

        <div className="absolute inset-0 bg-gradient-to-t from-black/40 via-transparent to-transparent" />

        <button
          onClick={prev}
          className="absolute left-1.5 top-1/2 -translate-y-1/2 w-7 h-7 rounded-full bg-black/50 hover:bg-black/70 flex items-center justify-center text-white/80 hover:text-white transition-all"
          data-testid="button-gallery-prev"
        >
          <ChevronLeft className="w-4 h-4" />
        </button>

        <button
          onClick={next}
          className="absolute right-1.5 top-1/2 -translate-y-1/2 w-7 h-7 rounded-full bg-black/50 hover:bg-black/70 flex items-center justify-center text-white/80 hover:text-white transition-all"
          data-testid="button-gallery-next"
        >
          <ChevronRight className="w-4 h-4" />
        </button>

        {onExpand && (
          <button
            onClick={() => onExpand(index)}
            className="absolute top-2 right-2 w-7 h-7 rounded-full bg-black/50 hover:bg-black/70 flex items-center justify-center text-white/80 hover:text-white transition-all"
            data-testid="button-gallery-expand"
          >
            <Maximize2 className="w-3.5 h-3.5" />
          </button>
        )}

        <div className="absolute bottom-2 left-0 right-0 flex justify-center gap-1">
          {images.slice(0, Math.min(images.length, 20)).map((_, i) => (
            <button
              key={i}
              onClick={() => setIndex(i)}
              className={`w-1.5 h-1.5 rounded-full transition-all ${i === index ? "bg-white w-3" : "bg-white/40 hover:bg-white/60"}`}
              data-testid={`button-gallery-dot-${i}`}
            />
          ))}
          {images.length > 20 && (
            <span className="text-white/50 text-[9px] ml-1">+{images.length - 20}</span>
          )}
        </div>
      </div>
    </div>
  );
}

export function PhotoGalleryWidget() {
  const { data: images, isLoading } = useQuery<GalleryImage[]>({
    queryKey: ["/api/gallery"],
  });

  const [lightboxIndex, setLightboxIndex] = useState<number | null>(null);

  if (isLoading) {
    return (
      <div className="bg-card rounded-lg border border-card-border overflow-hidden h-full" data-testid="widget-gallery-loading">
        <div className="p-3 flex items-center gap-2 border-b border-card-border">
          <Images className="w-4 h-4 text-primary" />
          <h3 className="font-bold text-card-foreground text-sm">Fotogalerie</h3>
        </div>
        <div className="aspect-[4/5] bg-muted animate-pulse" />
      </div>
    );
  }

  if (!images || images.length === 0) return null;

  return (
    <>
      <div className="bg-card rounded-lg border border-card-border overflow-hidden h-full" data-testid="widget-gallery">
        <div className="p-3 flex items-center gap-2 border-b border-card-border">
          <Images className="w-4 h-4 text-primary" />
          <h3 className="font-bold text-card-foreground text-sm">Fotogalerie</h3>
        </div>
        <SingleImageCarousel
          images={images}
          autoPlay={true}
          interval={10000}
          onExpand={(i) => setLightboxIndex(i)}
        />
      </div>

      {lightboxIndex !== null && (
        <Lightbox
          images={images}
          startIndex={lightboxIndex}
          onClose={() => setLightboxIndex(null)}
        />
      )}
    </>
  );
}

export default function GalleryPage() {
  const { data: images, isLoading } = useQuery<GalleryImage[]>({
    queryKey: ["/api/gallery"],
  });

  const [lightboxIndex, setLightboxIndex] = useState<number | null>(null);

  return (
    <div data-testid="page-gallery">
      {isLoading ? (
        <div className="max-w-3xl mx-auto">
          <div className="aspect-[4/3] bg-card rounded-lg animate-pulse" />
        </div>
      ) : images && images.length > 0 ? (
        <div className="max-w-3xl mx-auto">
          <div className="bg-card rounded-lg border border-card-border overflow-hidden">
            <SingleImageCarousel
              images={images}
              autoPlay={false}
              onExpand={(i) => setLightboxIndex(i)}
            />
          </div>
          <p className="text-center text-muted-foreground text-sm mt-3" data-testid="text-gallery-count">
            {images.length} Fotos
          </p>
        </div>
      ) : (
        <p className="text-center text-muted-foreground">Keine Fotos vorhanden</p>
      )}

      {lightboxIndex !== null && images && (
        <Lightbox
          images={images}
          startIndex={lightboxIndex}
          onClose={() => setLightboxIndex(null)}
        />
      )}
    </div>
  );
}
