'use client';

import React, { useCallback, useEffect, useRef, useState } from 'react';
import { RiCloseLine } from '@remixicon/react';
import { Button } from '@/components/ui/button';

interface ProductImage {
  url: string;
  altText?: string;
}

interface ProductDetailGalleryProps {
  images: ProductImage[];
}

const ProductDetailGallery: React.FC<ProductDetailGalleryProps> = ({
  images,
}) => {
  const [zoomedIndex, setZoomedIndex] = useState<number | null>(null);
  const [activeIndex, setActiveIndex] = useState(0);
  const scrollerRef = useRef<HTMLDivElement>(null);
  const isZoomed = zoomedIndex !== null;

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

  // The slide whose left edge sits closest to the scroller's left edge is the
  // one in view. Measuring rects keeps this correct whatever the gap or width.
  const handleScroll = useCallback(() => {
    const scroller = scrollerRef.current;
    if (!scroller) return;

    const scrollerLeft = scroller.getBoundingClientRect().left;
    let nearest = 0;
    let smallestOffset = Infinity;

    Array.from(scroller.children).forEach((child, index) => {
      const offset = Math.abs(child.getBoundingClientRect().left - scrollerLeft);
      if (offset < smallestOffset) {
        smallestOffset = offset;
        nearest = index;
      }
    });

    setActiveIndex(nearest);
  }, []);

  const scrollToIndex = (index: number) => {
    const scroller = scrollerRef.current;
    const slide = scroller?.children[index];
    if (!scroller || !slide) return;

    const offset =
      slide.getBoundingClientRect().left - scroller.getBoundingClientRect().left;
    scroller.scrollTo({ left: scroller.scrollLeft + offset, behavior: 'smooth' });
  };

  // Close on Escape, and keep the page behind the overlay from scrolling.
  useEffect(() => {
    if (!isZoomed) return;

    const onKeyDown = (event: KeyboardEvent) => {
      if (event.key === 'Escape') close();
    };

    document.addEventListener('keydown', onKeyDown);
    const previousOverflow = document.body.style.overflow;
    document.body.style.overflow = 'hidden';

    return () => {
      document.removeEventListener('keydown', onKeyDown);
      document.body.style.overflow = previousOverflow;
    };
  }, [isZoomed, close]);

  if (images.length === 0) {
    return (
      <div className="aspect-square bg-zinc-50 flex items-center justify-center text-zinc-300">
        <i className="ri-image-line text-[120px]"></i>
      </div>
    );
  }

  const isSingle = images.length === 1;
  const zoomedImage = zoomedIndex !== null ? images[zoomedIndex] : null;

  return (
    <>
      {/* Swipeable carousel on mobile, grid from sm up */}
      <div
        ref={scrollerRef}
        onScroll={handleScroll}
        className="flex snap-x snap-mandatory gap-3 overflow-x-auto no-scrollbar sm:grid sm:grid-cols-2 sm:overflow-visible"
      >
        {images.map((image, index) => (
          <button
            key={index}
            onClick={() => setZoomedIndex(index)}
            aria-label={`Zoom ${image.altText || 'product image'}`}
            className={`relative aspect-square w-full shrink-0 snap-center overflow-hidden bg-white pointer-events-none sm:pointer-events-auto sm:shrink sm:cursor-zoom-in ${
              isSingle ? 'sm:col-span-2' : ''
            }`}
          >
            <img
              src={image.url}
              alt={image.altText || 'Product image'}
              className="w-full h-full object-cover"
            />
          </button>
        ))}
      </div>

      {/* Carousel pagination — the grid needs no dots, so mobile only */}
      {!isSingle && (
        <div className="flex justify-center gap-2 pt-4 sm:hidden">
          {images.map((_, index) => (
            <button
              key={index}
              onClick={() => scrollToIndex(index)}
              aria-label={`Go to image ${index + 1}`}
              aria-current={index === activeIndex}
              className={`h-1.5 rounded-full transition-all ${
                index === activeIndex
                  ? 'w-5 bg-foreground'
                  : 'w-1.5 bg-border hover:bg-foreground/40'
              }`}
            />
          ))}
        </div>
      )}

      {zoomedImage && (
        <div
          role="dialog"
          aria-modal="true"
          aria-label={zoomedImage.altText || 'Product image'}
          onClick={close}
          className="fixed inset-0 z-100 flex items-center justify-center bg-foreground/20 backdrop-blur-md p-6 md:p-10"
        >
          <img
            src={zoomedImage.url}
            alt={zoomedImage.altText || 'Product image'}
            onClick={(event) => event.stopPropagation()}
            className="max-h-full max-w-full object-contain bg-white"
          />

          <Button
            onClick={close}
            variant="ghost"
            size="icon-lg"
            aria-label="Close"
            className="absolute top-4 right-4 rounded-full bg-background shadow-sm hover:bg-secondary"
          >
            <RiCloseLine size={20} />
          </Button>
        </div>
      )}
    </>
  );
};

export default ProductDetailGallery;
