// todo: only handles 1 video, later we want to handle multiple
/* eslint-disable @next/next/no-img-element */
'use client';

import { useState } from 'react';

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

import { PiCaretLeftBold, PiCaretRightBold } from 'react-icons/pi';
import { useMediaQuery } from 'react-responsive';
import Lightbox from 'yet-another-react-lightbox';
import { Fullscreen, Thumbnails } from 'yet-another-react-lightbox/plugins';
import Captions from 'yet-another-react-lightbox/plugins/captions';
import 'yet-another-react-lightbox/plugins/captions.css';
import Counter from 'yet-another-react-lightbox/plugins/counter';
import 'yet-another-react-lightbox/plugins/counter.css';
import 'yet-another-react-lightbox/plugins/thumbnails.css';
import Zoom from 'yet-another-react-lightbox/plugins/zoom';
import 'yet-another-react-lightbox/styles.css';

import ImageMeta from '@/components/ImageMeta';
import { cn } from '@/lib/utils';
import { buildImageMetaText, getImageByIdAndName } from '@/utils/images';

import { CreationGalleryImage } from '@/types/Creation';

import YouTubeVideo from './YoutubeVideo';

interface GalleryProps {
  images: CreationGalleryImage[];
  hasArrows?: boolean;
  videoId?: string;
  videoForrasa?: string | null;
}

const apiUrl = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:3000';
const baseFullSizeImgUrl = `${apiUrl}/imageRepository/getImage?key=`;

const Gallery: React.FC<GalleryProps> = ({ images = [], hasArrows, videoId, videoForrasa }) => {
  const isDesktop = useMediaQuery({ minWidth: 1024 });
  const isXL = useMediaQuery({ minWidth: 1280 });
  const isLG = useMediaQuery({ minWidth: 1024 });
  const isMD = useMediaQuery({ minWidth: 768 });
  // const isSM = useMediaQuery({ minWidth: 640 });

  const t = useTranslations('imageMeta');

  const [isOpen, setIsOpen] = useState<boolean>(false);
  const [index, setIndex] = useState<number>(0);

  if (!images.length && !videoId) return null;

  if (!images.length && videoId) {
    return (
      <div className="flex flex-col">
        <div className="relative w-full aspect-[4/3] lg:aspect-video bg-neutral-50 overflow-hidden rounded">
          <YouTubeVideo id={videoId} />
        </div>
        <ImageMeta image={null} videoForrasa={videoForrasa} />
      </div>
    );
  }

  // const carouselPadding = images.length === 1 ? 0 : 50;
  const carouselPadding = 60;

  const anyHasCaptionData = images.some(
    (image) => image.kepalairas || image.jogtulajdonos || image.kepkeszitoje || image.kepforrasa
  );

  const totalSlides = images.length + (videoId ? 1 : 0);

  const plugins =
    isDesktop && anyHasCaptionData
      ? [Zoom, Captions, Thumbnails, Fullscreen, ...(totalSlides > 1 ? [Counter] : [])]
      : [Zoom, Thumbnails, Fullscreen, ...(totalSlides > 1 ? [Counter] : [])];

  const captionsProps = isDesktop ? { showToggle: true, hidden: true } : undefined;

  const buttonIconClassName =
    'text-5xl p-2 bg-black/20 group-hover:bg-black/40 rounded-full text-white/80 backdrop-blur-sm shadow-lg transition';

  const dynamicCols = isXL
    ? totalSlides > 8
      ? 16
      : 8
    : isLG
      ? totalSlides > 7
        ? 14
        : 7
      : isMD
        ? totalSlides > 6
          ? 12
          : 6
        : 5;

  const dynamicGap = isXL && totalSlides <= 8 ? 'gap-2' : 'gap-1';

  const getNext = () => {
    return index + 1 >= totalSlides ? 0 : index + 1;
  };

  const getPrev = () => {
    return index - 1 < 0 ? totalSlides - 1 : index - 1;
  };

  return (
    <div className="flex flex-col gap-4">
      <div className="flex flex-col">
        <div className="w-full flex flex-row items-stretch gap-2">
          {images.length > 1 && hasArrows && (
            <button
              className="hidden sm:flex items-center justify-center p-2 text-xl text-white/80"
              onClick={(e) => {
                e.preventDefault();
                e.stopPropagation();
                setIndex(getPrev());
              }}
              aria-label="Előző kép"
            >
              <PiCaretLeftBold className={buttonIconClassName} />
            </button>
          )}

          <div className="relative w-full aspect-[4/3] lg:aspect-video bg-neutral-50 overflow-hidden rounded">
            {images.map((img, i) => (
              <Slide
                key={img.id ?? i}
                image={img}
                active={index === i + (videoId ? 1 : 0)}
                contain
              />
            ))}
            {videoId && (
              <div
                className={cn(
                  'absolute top-0 left-0 w-full h-full',
                  index === 0
                    ? 'pointer-events-auto opacity-100 z-10 '
                    : 'pointer-events-none opacity-0'
                )}
              >
                <YouTubeVideo id={videoId} />
              </div>
            )}

            {images.length > 1 && hasArrows && (
              <>
                <button
                  className="sm:hidden absolute inset-y-0 left-0 w-1/4 flex items-center justify-start text-xl text-white/80 z-30"
                  onClick={(e) => {
                    e.preventDefault();
                    e.stopPropagation();
                    setIndex(getPrev());
                  }}
                  aria-label="Előző kép"
                >
                  <PiCaretLeftBold className="text-5xl p-2 bg-black/20 rounded-full text-white/80 backdrop-blur-sm shadow-lg" />
                </button>

                <button
                  className="sm:hidden absolute inset-y-0 right-0 w-1/4 flex items-center justify-end text-xl text-white/80 z-30"
                  onClick={(e) => {
                    e.preventDefault();
                    e.stopPropagation();
                    setIndex(getNext());
                  }}
                  aria-label="Következő kép"
                >
                  <PiCaretRightBold className="text-5xl p-2 bg-black/20 rounded-full text-white/80 backdrop-blur-sm shadow-lg" />
                </button>
              </>
            )}
            {(videoId ? index > 0 : true) && (
              <button
                type="button"
                onClick={() => {
                  setIsOpen(true);
                }}
                className="absolute inset-0 w-full h-full cursor-pointer hover:opacity-90 transition-opacity z-20"
                aria-label="Kép megnyitása"
              />
            )}
          </div>

          {images.length > 1 && hasArrows && (
            <button
              className="hidden sm:flex items-center justify-center p-2 text-xl text-white/80"
              onClick={(e) => {
                e.preventDefault();
                e.stopPropagation();
                setIndex(getNext());
              }}
              aria-label="Következő kép"
            >
              <PiCaretRightBold className={buttonIconClassName} />
            </button>
          )}
        </div>
        <ImageMeta
          image={videoId && index === 0 ? null : videoId ? images[index - 1] : images[index]}
          videoForrasa={videoId && index === 0 ? videoForrasa : undefined}
        />
      </div>

      {totalSlides > 1 && (
        <>
          {/* Mobile: horizontal strip */}
          <div className="w-full flex gap-2 overflow-x-auto no-scrollbar sm:hidden px-4">
            {images.map((img, i) => (
              <button
                key={img.id ?? i}
                onClick={() => {
                  setIndex(i + (videoId ? 1 : 0));
                }}
                className={cn(
                  'relative flex-none w-24 aspect-square overflow-hidden rounded bg-neutral-100',
                  index === i + (videoId ? 1 : 0) && 'ring-4 ring-mma-yellow'
                )}
                aria-label="Kép megnyitása"
              >
                <Image
                  src={getImageByIdAndName(img.id, img.fileName)}
                  alt={img.kepalairas || ''}
                  className="w-full h-full object-cover"
                  width={128}
                  height={128}
                />
              </button>
            ))}
            {videoId && (
              <button
                onClick={() => setIndex(0)}
                className={cn(
                  'relative flex-none w-24 aspect-square overflow-hidden rounded bg-neutral-100 order-first',
                  index === 0 && 'ring-4 ring-mma-yellow'
                )}
                aria-label="Videó megnyitása"
              >
                <img
                  src={`https://img.youtube.com/vi/${videoId}/hqdefault.jpg`}
                  alt="Videó"
                  className="w-full h-full object-cover"
                  loading="lazy"
                />
                <span className="absolute inset-0 flex items-center justify-center">
                  <svg
                    width="40"
                    height="40"
                    viewBox="0 0 24 24"
                    fill="white"
                    className="drop-shadow"
                  >
                    <path d="M8 5v14l11-7z"></path>
                  </svg>
                </span>
              </button>
            )}
          </div>

          {/* Desktop: dense grid with dynamic columns to keep single row */}
          <div
            className={cn('hidden sm:grid', dynamicGap)}
            style={{
              gridTemplateColumns: `repeat(${dynamicCols}, minmax(0, 1fr))`,
            }}
          >
            {images.map((img, i) => (
              <button
                key={img.id ?? i}
                onClick={() => {
                  setIndex(i + (videoId ? 1 : 0));
                }}
                className={cn(
                  'relative aspect-square overflow-hidden rounded bg-neutral-100',
                  index === i + (videoId ? 1 : 0) && 'ring-4 ring-mma-yellow'
                )}
                aria-label="Kép megnyitása"
              >
                <Image
                  src={getImageByIdAndName(img.id, img.fileName)}
                  alt={img.kepalairas || ''}
                  className="w-full h-full object-cover"
                  width={128}
                  height={128}
                />
              </button>
            ))}
            {videoId && (
              <button
                onClick={() => {
                  setIndex(0);
                }}
                className={cn(
                  'relative aspect-square overflow-hidden rounded bg-neutral-100 order-first',
                  index === 0 && 'ring-4 ring-mma-yellow'
                )}
                aria-label="Videó megnyitása"
              >
                <img
                  src={`https://img.youtube.com/vi/${videoId}/hqdefault.jpg`}
                  alt="Videó"
                  className="w-full h-full object-cover"
                  loading="lazy"
                />
                <span className="absolute inset-0 flex items-center justify-center">
                  <svg
                    width="56"
                    height="56"
                    viewBox="0 0 24 24"
                    fill="white"
                    className="drop-shadow"
                  >
                    <path d="M8 5v14l11-7z"></path>
                  </svg>
                </span>
              </button>
            )}
          </div>
        </>
      )}

      <Lightbox
        open={isOpen}
        close={() => setIsOpen(false)}
        index={index}
        slides={
          videoId
            ? [
                {
                  src: `https://img.youtube.com/vi/${videoId}/hqdefault.jpg`,
                  width: 1280,
                  height: 720,
                  videoId,
                  title: undefined,
                  description: undefined,
                } as {
                  src: string;
                  width: number;
                  height: number;
                  videoId: string;
                  title?: string;
                  description?: string;
                },
                ...images.map((img) => ({
                  src: baseFullSizeImgUrl + img.key,
                  width: img.width,
                  height: img.height,
                  title: img.kepalairas?.trim() || undefined,
                  description: buildImageMetaText(img, false, {
                    source: t('source'),
                    photo: t('photo'),
                    rightsHolder: t('rightsHolder'),
                  }),
                })),
              ]
            : images.map((img) => ({
                src: baseFullSizeImgUrl + img.key,
                width: img.width,
                height: img.height,
                title: img.kepalairas?.trim() || undefined,
                description: buildImageMetaText(img, false, {
                  source: t('source'),
                  photo: t('photo'),
                  rightsHolder: t('rightsHolder'),
                }),
              }))
        }
        plugins={plugins}
        zoom={{ maxZoomPixelRatio: 3, scrollToZoom: true }}
        counter={{
          container: {
            style: {
              top: 'unset',
              bottom: 0,
              left: 'unset',
              fontWeight: 700,
              fontSize: '20px',
            },
          },
        }}
        carousel={{
          padding: carouselPadding,
          finite: true,
          preload: 5,
        }}
        captions={captionsProps}
        thumbnails={
          totalSlides > 1
            ? { showToggle: true, hidden: false }
            : { showToggle: false, hidden: true }
        }
        render={{
          buttonPrev: totalSlides > 1 ? undefined : () => null,
          buttonNext: totalSlides > 1 ? undefined : () => null,
          slide: ({ slide }) => {
            // Render custom video slide when present
            const s = slide as { videoId?: string };
            if (s.videoId) {
              return (
                <div className="w-full h-full flex items-center justify-center p-4">
                  <div className="w-full max-w-5xl aspect-video">
                    <YouTubeVideo id={s.videoId} />
                  </div>
                </div>
              );
            }
            return undefined;
          },
        }}
      />
    </div>
  );
};

export default Gallery;

interface SlideProps {
  image: CreationGalleryImage;
  contain?: boolean;
  className?: string;
  active?: boolean;
  videoId?: string;
}

const Slide: React.FC<SlideProps> = ({ image, contain, className, active, videoId }) => {
  return (
    <div
      className={cn(
        'absolute top-0 left-0 w-full h-full bg-neutral-50',
        active ? 'pointer-events-auto opacity-100 z-10' : 'pointer-events-none opacity-0',
        className
      )}
    >
      {image.key && (
        <Image
          src={`${apiUrl}/imageRepository/getImage?key=${image.key}`}
          alt={image.kepalairas || 'profilkép'}
          className={cn(contain ? 'object-contain' : 'object-cover')}
          fill
          sizes="(max-width: 640px) 100vw, (max-width: 1200px) 66vw, 60vw"
        />
      )}
      {videoId && (
        <div className="absolute top-0 left-0 w-full h-full bg-no-repeat bg-center">
          <YouTubeVideo id={videoId} />
        </div>
      )}
    </div>
  );
};
