'use client';

import { useEffect, useState, type ReactNode } from 'react';
import { ChevronLeft, ChevronRight } from 'lucide-react';
import { cn } from '@/lib/utils';

const DEFAULT_VISIBLE_COUNT = 3;

export interface PortfolioCarouselImage {
  id: string;
  url: string;
  title?: string | null;
}

interface PortfolioCarouselProps {
  images: PortfolioCarouselImage[];
  getImageUrl: (url: string) => string;
  renderOverlay?: (image: PortfolioCarouselImage) => ReactNode;
  visibleCount?: number;
  className?: string;
}

function useResponsiveVisibleCount(desktopCount: number) {
  const [count, setCount] = useState(desktopCount);

  useEffect(() => {
    const mq = window.matchMedia('(min-width: 640px)');
    const update = () => setCount(mq.matches ? desktopCount : 1);
    update();
    mq.addEventListener('change', update);
    return () => mq.removeEventListener('change', update);
  }, [desktopCount]);

  return count;
}

export function PortfolioCarousel({
  images,
  getImageUrl,
  renderOverlay,
  visibleCount = DEFAULT_VISIBLE_COUNT,
  className,
}: PortfolioCarouselProps) {
  const [startIndex, setStartIndex] = useState(0);
  const responsiveCount = useResponsiveVisibleCount(visibleCount);
  const maxStart = Math.max(0, images.length - responsiveCount);
  const canPrev = startIndex > 0;
  const canNext = startIndex < maxStart;
  const visibleImages = images.slice(startIndex, startIndex + responsiveCount);
  const showNav = images.length > responsiveCount;

  useEffect(() => {
    if (startIndex > maxStart) {
      setStartIndex(maxStart);
    }
  }, [startIndex, maxStart]);

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

  return (
    <div className={cn('space-y-2.5', className)}>
      <div className="relative">
        <div
          className={cn(
            'grid gap-2 min-w-0 sm:gap-3',
            responsiveCount === 3 && 'grid-cols-3',
            responsiveCount === 2 && 'grid-cols-2',
            responsiveCount === 1 && 'grid-cols-1'
          )}
        >
          {visibleImages.map((img) => (
            <div
              key={img.id}
              className="group relative aspect-[4/3] overflow-hidden border border-[#e2ddd2] bg-[var(--home-sand)] sm:aspect-square"
            >
              {/* eslint-disable-next-line @next/next/no-img-element */}
              <img
                src={getImageUrl(img.url)}
                alt={img.title || 'Portfolio photo'}
                className="h-full w-full object-cover"
              />
              {renderOverlay?.(img)}
              {img.title && (
                <p className="absolute bottom-0 inset-x-0 bg-gradient-to-t from-black/70 to-transparent px-2.5 py-2 text-xs text-white truncate">
                  {img.title}
                </p>
              )}
            </div>
          ))}
        </div>

        {showNav && (
          <>
            <button
              type="button"
              onClick={() => setStartIndex((i) => Math.max(0, i - 1))}
              disabled={!canPrev}
              aria-label="Previous photos"
              className={cn(
                'absolute left-2 top-1/2 z-10 flex h-9 w-9 -translate-y-1/2 items-center justify-center',
                'bg-[var(--home-ink)]/80 text-white transition-opacity',
                'disabled:pointer-events-none disabled:opacity-0',
                'sm:left-3'
              )}
            >
              <ChevronLeft className="h-5 w-5" />
            </button>
            <button
              type="button"
              onClick={() => setStartIndex((i) => Math.min(maxStart, i + 1))}
              disabled={!canNext}
              aria-label="Next photos"
              className={cn(
                'absolute right-2 top-1/2 z-10 flex h-9 w-9 -translate-y-1/2 items-center justify-center',
                'bg-[var(--home-ink)]/80 text-white transition-opacity',
                'disabled:pointer-events-none disabled:opacity-0',
                'sm:right-3'
              )}
            >
              <ChevronRight className="h-5 w-5" />
            </button>
          </>
        )}
      </div>

      {showNav && (
        <div className="flex items-center justify-center gap-1.5">
          {Array.from({ length: maxStart + 1 }).map((_, i) => (
            <button
              key={i}
              type="button"
              aria-label={`Go to photo set ${i + 1}`}
              onClick={() => setStartIndex(i)}
              className={cn(
                'h-1.5 rounded-full transition-all',
                i === startIndex ? 'w-5 bg-[var(--home-ink)]' : 'w-1.5 bg-slate-300'
              )}
            />
          ))}
        </div>
      )}
    </div>
  );
}
