'use client';

import { useCallback, useEffect, useMemo, useRef, useState } from 'react';

import { useTranslations } from 'next-intl';
import Image from 'next/image';

import { ChevronLeft, ChevronRight, Play } from 'lucide-react';

import ImageMeta from '@/components/ImageMeta';
import YarlFullscreenLightbox from '@/components/lightbox/YarlFullscreenLightbox';
import YarlInlineCarousel from '@/components/lightbox/YarlInlineCarousel';
import {
  type AppLightboxSlide,
  buildVideoLightboxSlide,
  mapCreationImagesToLightboxSlides,
} from '@/components/lightbox/lightboxSlides';
import { Button } from '@/components/ui/button';
import { cn } from '@/lib/utils';

import type { ImageObject } from '@/types/Common';

interface CreationMediaVideo {
  id: string;
  title?: string | null;
  source?: string | null;
  rightsHolder?: string | null;
}

interface CreationMediaGalleryProps {
  images: ImageObject[];
  video?: CreationMediaVideo | null;
  title?: string;
  className?: string;
}

export default function CreationMediaGallery({
  images,
  video,
  title,
  className,
}: CreationMediaGalleryProps) {
  const t = useTranslations('imageMeta');
  const tCommon = useTranslations('common');
  const [index, setIndex] = useState(0);
  const [isOpen, setIsOpen] = useState(false);
  const [canScrollThumbnailsLeft, setCanScrollThumbnailsLeft] = useState(false);
  const [canScrollThumbnailsRight, setCanScrollThumbnailsRight] = useState(false);
  const thumbnailStripRef = useRef<HTMLDivElement>(null);
  const thumbnailButtonRefs = useRef<Array<HTMLButtonElement | null>>([]);

  const imageLabels = useMemo(
    () => ({
      source: t('source'),
      photo: t('photo'),
      rightsHolder: t('rightsHolder'),
    }),
    [t]
  );

  const slides = useMemo<AppLightboxSlide[]>(() => {
    const imageSlides = mapCreationImagesToLightboxSlides(images, {
      fallbackTitle: title,
      labels: imageLabels,
    });

    const videoSlide = video
      ? buildVideoLightboxSlide(video, {
          sourceLabel: t('videoSource'),
          rightsHolderLabel: t('rightsHolder'),
        })
      : null;

    return videoSlide ? [...imageSlides, videoSlide] : imageSlides;
  }, [imageLabels, images, t, title, video]);

  const inlineSlides = useMemo<AppLightboxSlide[]>(() => {
    const imageSlides = mapCreationImagesToLightboxSlides(images, {
      fallbackTitle: title,
      labels: imageLabels,
      optimizeImages: true,
    });

    const videoSlide = video
      ? buildVideoLightboxSlide(video, {
          sourceLabel: t('videoSource'),
          rightsHolderLabel: t('rightsHolder'),
        })
      : null;

    return videoSlide ? [...imageSlides, videoSlide] : imageSlides;
  }, [imageLabels, images, t, title, video]);

  useEffect(() => {
    if (index >= slides.length) setIndex(0);
  }, [index, slides.length]);

  const updateThumbnailOverflow = useCallback(() => {
    const strip = thumbnailStripRef.current;
    if (!strip) return;

    const maxScrollLeft = strip.scrollWidth - strip.clientWidth;
    setCanScrollThumbnailsLeft(maxScrollLeft > 1 && strip.scrollLeft > 1);
    setCanScrollThumbnailsRight(maxScrollLeft > 1 && strip.scrollLeft < maxScrollLeft - 1);
  }, []);

  const pageThumbnails = useCallback((direction: -1 | 1) => {
    const strip = thumbnailStripRef.current;
    if (!strip) return;

    strip.scrollBy({
      left: direction * Math.max(strip.clientWidth * 0.75, 64),
      behavior: 'smooth',
    });
  }, []);

  useEffect(() => {
    updateThumbnailOverflow();

    window.addEventListener('resize', updateThumbnailOverflow);
    return () => window.removeEventListener('resize', updateThumbnailOverflow);
  }, [slides.length, updateThumbnailOverflow]);

  // Keep the active thumbnail centered within its own horizontal strip. We must
  // NOT use element.scrollIntoView here: with block:'nearest' it also scrolls the
  // nearest vertical scroll container (the window), so on every page mount it would
  // yank the whole page down to the gallery (~700px). Scroll the strip only.
  useEffect(() => {
    const strip = thumbnailStripRef.current;
    const button = thumbnailButtonRefs.current[index];
    if (!strip || !button) return;

    const stripRect = strip.getBoundingClientRect();
    const buttonRect = button.getBoundingClientRect();
    const delta = buttonRect.left + buttonRect.width / 2 - (stripRect.left + stripRect.width / 2);
    strip.scrollBy({ left: delta, behavior: 'smooth' });
  }, [index]);

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

  const activeSlide = slides[index] ?? slides[0];

  const openFullscreen = (nextIndex = index) => {
    setIndex(nextIndex);
    setIsOpen(true);
  };

  const hasMultipleSlides = slides.length > 1;

  return (
    <figure className={cn('w-full', className)}>
      {/* main image area — nothing overlaid except the hover zoom hint */}
      <div className="relative aspect-[4/3] w-full cursor-zoom-in overflow-hidden bg-brand-secondary sm:aspect-video lg:aspect-[4/3]">
        <YarlInlineCarousel
          slides={inlineSlides}
          index={index}
          onView={setIndex}
          onSlideClick={(clickedIndex) => {
            if (!slides[clickedIndex]?.videoId) openFullscreen(clickedIndex);
          }}
          className="h-full w-full"
        />
      </div>

      {/* counter + thumbnails — below the image */}
      {hasMultipleSlides && (
        <div className="mt-3 flex items-center gap-3">
          <div className="relative min-w-0 flex-1">
            {canScrollThumbnailsLeft && (
              <>
                <div className="pointer-events-none absolute inset-y-0 left-0 z-10 w-10 bg-gradient-to-r from-brand-secondary to-transparent" />
                <Button
                  type="button"
                  variant="quiet"
                  size="icon"
                  aria-label={tCommon('previous')}
                  onClick={() => pageThumbnails(-1)}
                  className="absolute left-0 top-1/2 z-20 hidden h-8 w-8 -translate-y-1/2 bg-brand-secondary/95 p-0 text-brand-primary shadow-sm sm:inline-flex"
                >
                  <ChevronLeft className="h-4 w-4" aria-hidden="true" />
                </Button>
              </>
            )}

            <div
              ref={thumbnailStripRef}
              onScroll={updateThumbnailOverflow}
              className="no-scrollbar flex gap-1.5 overflow-x-auto scroll-smooth sm:px-9"
            >
              {slides.map((slide, i) => (
                <button
                  key={i}
                  ref={(node) => {
                    thumbnailButtonRefs.current[i] = node;
                  }}
                  type="button"
                  onClick={() => setIndex(i)}
                  className={cn(
                    'relative h-14 w-14 flex-shrink-0 overflow-hidden transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-mma-blue focus-visible:ring-offset-2',
                    i === index
                      ? 'ring-2 ring-brand-yellow ring-offset-1'
                      : 'opacity-60 hover:opacity-100'
                  )}
                >
                  {slide.thumbnail ? (
                    <Image
                      src={slide.thumbnail as string}
                      alt=""
                      fill
                      className="object-cover"
                      sizes="56px"
                    />
                  ) : (
                    <div className="h-full w-full bg-brand-primary/20" />
                  )}
                  {slide.videoId && (
                    <div className="absolute inset-0 flex items-center justify-center bg-black/30">
                      <Play className="h-4 w-4 fill-white text-white" />
                    </div>
                  )}
                </button>
              ))}
            </div>

            {canScrollThumbnailsRight && (
              <>
                <div className="pointer-events-none absolute inset-y-0 right-0 z-10 w-10 bg-gradient-to-l from-brand-secondary to-transparent" />
                <Button
                  type="button"
                  variant="quiet"
                  size="icon"
                  aria-label={tCommon('next')}
                  onClick={() => pageThumbnails(1)}
                  className="absolute right-0 top-1/2 z-20 hidden h-8 w-8 -translate-y-1/2 bg-brand-secondary/95 p-0 text-brand-primary shadow-sm sm:inline-flex"
                >
                  <ChevronRight className="h-4 w-4" aria-hidden="true" />
                </Button>
              </>
            )}
          </div>
          <span className="flex-shrink-0 text-xs font-semibold tabular-nums text-brand-primary/60">
            {String(index + 1).padStart(2, '0')} / {String(slides.length).padStart(2, '0')}
          </span>
        </div>
      )}

      <ImageMeta
        image={activeSlide.sourceImage ?? null}
        videoForrasa={activeSlide.videoId ? activeSlide.videoSource : undefined}
        videoJogtulajdonos={activeSlide.videoId ? activeSlide.videoRightsHolder : undefined}
      />

      <YarlFullscreenLightbox
        slides={slides}
        index={index}
        open={isOpen}
        onClose={() => setIsOpen(false)}
        onView={setIndex}
      />
    </figure>
  );
}
