'use client';

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

import Image from 'next/image';

import type { HomepageCollectionTextFields } from '@/services/homeCollections';

import Section from '@/components/common/Section';
import SectionHeader from '@/components/home/components/SectionHeader';
import { getCreationCardImageSrc } from '@/utils/creationHelpers';
import { buildMediaUrl } from '@/utils/images';

import { Link } from '@/i18n/navigation';

interface HomepageCreationSelectionFramedProps {
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  creations: any[];
  textFields?: HomepageCollectionTextFields | null;
}

const DESKTOP_TOTAL = 40;
const DESKTOP_SIDE = 20;
const MOBILE_POOL_SIZE = 36;
const MOBILE_SIDE = 6;
const MOBILE_GROUP_SIZE = 12;
const MOBILE_GROUP_COUNT = 3;

const sliceCyclic = <T,>(items: T[], start: number, count: number): T[] => {
  if (!items.length || count <= 0) return [];
  const normalizedStart = ((start % items.length) + items.length) % items.length;
  const result: T[] = [];
  for (let i = 0; i < count; i += 1) {
    result.push(items[(normalizedStart + i) % items.length]);
  }
  return result;
};

const HomepageCreationSelectionFramed: React.FC<HomepageCreationSelectionFramedProps> = ({
  creations,
  textFields,
}) => {
  const slides = useMemo(() => {
    const mapped = (creations || []).map((creation) => ({
      id: creation.id ?? creation.alkotasAzonosito ?? creation.nev ?? '',
      alkotasId: creation.alkotasAzonosito ?? '',
      src:
        (creation.galeria?.[0]?.id
          ? buildMediaUrl(creation.galeria[0].id, 'w256')
          : creation.fokep
            ? buildMediaUrl(creation.fokep.id, 'w256')
            : getCreationCardImageSrc(creation)) || '',
      title: creation.nev || '',
      subtitle: creation.megjelenitendoNev || '',
    }));

    return mapped.filter(
      (slide): slide is (typeof mapped)[number] & { src: string } =>
        typeof slide.src === 'string' && slide.src.length > 0
    );
  }, [creations]);

  const desktopSlides = useMemo(() => slides.slice(0, DESKTOP_TOTAL), [slides]);
  const frontSlides = useMemo(() => desktopSlides.slice(0, DESKTOP_SIDE), [desktopSlides]);
  const backSlides = useMemo(
    () => desktopSlides.slice(DESKTOP_SIDE, DESKTOP_TOTAL),
    [desktopSlides]
  );
  const getBackSlide = (index: number) => backSlides[index] ?? null;

  const [flipped, setFlipped] = useState<Record<number, boolean>>({});
  const flippedRef = useRef<Record<number, boolean>>({});
  const [mobileGroupIndex, setMobileGroupIndex] = useState(0);
  const [mobileFlipped, setMobileFlipped] = useState<Record<number, boolean>>({});
  const mobileFlippedRef = useRef<Record<number, boolean>>({});

  const mobilePool = useMemo(() => {
    if (!slides.length) return [];

    return slides.slice(0, Math.min(MOBILE_POOL_SIZE, slides.length));
  }, [slides]);

  const mobileSlides = useMemo(() => {
    if (!mobilePool.length) return [];
    const start = mobileGroupIndex * MOBILE_GROUP_SIZE;
    const count = Math.min(MOBILE_GROUP_SIZE, mobilePool.length);

    return sliceCyclic(mobilePool, start, count);
  }, [mobileGroupIndex, mobilePool]);

  const mobileFrontSlides = useMemo(() => mobileSlides.slice(0, MOBILE_SIDE), [mobileSlides]);
  const mobileBackSlides = useMemo(
    () => mobileSlides.slice(MOBILE_SIDE, MOBILE_GROUP_SIZE),
    [mobileSlides]
  );

  useEffect(() => {
    flippedRef.current = flipped;
  }, [flipped]);

  useEffect(() => {
    mobileFlippedRef.current = mobileFlipped;
  }, [mobileFlipped]);

  useEffect(() => {
    if (!frontSlides.length) return;
    const interval = window.setInterval(() => {
      const unflipped = frontSlides
        .map((_, index) => index)
        .filter((index) => !flippedRef.current[index]);
      if (!unflipped.length) {
        flippedRef.current = {};
        setFlipped({});
        return;
      }
      const nextIndex = unflipped[Math.floor(Math.random() * unflipped.length)];
      setFlipped((prev) => ({ ...prev, [nextIndex]: true }));
    }, 1800);

    return () => window.clearInterval(interval);
  }, [frontSlides, frontSlides.length]);

  useEffect(() => {
    setMobileGroupIndex(Math.floor(Math.random() * MOBILE_GROUP_COUNT));
  }, []);

  useEffect(() => {
    mobileFlippedRef.current = {};
    setMobileFlipped({});
  }, [mobileGroupIndex]);

  useEffect(() => {
    if (!mobileBackSlides.length) return;
    const interval = window.setInterval(() => {
      const unflipped = mobileFrontSlides
        .map((_, index) => index)
        .filter((index) => !mobileFlippedRef.current[index]);

      if (!unflipped.length) {
        mobileFlippedRef.current = {};
        setMobileFlipped({});
        return;
      }

      const nextIndex = unflipped[Math.floor(Math.random() * unflipped.length)];
      setMobileFlipped((prev) => ({ ...prev, [nextIndex]: true }));
    }, 1800);

    return () => window.clearInterval(interval);
  }, [mobileBackSlides.length, mobileFrontSlides]);

  if (!frontSlides.length) {
    return null;
  }

  return (
    <Section surface="ink">
      <div className="flex items-end justify-between gap-6">
        <SectionHeader
          eyebrow={textFields?.blockLabel || ''}
          eyebrowUrl="/alkotasok-kepekkel"
          title={textFields?.blockTitle || ''}
          description={textFields?.blockSubtitle || ''}
        />
      </div>

      <div className="grid grid-cols-2 gap-0 auto-rows-[150px] sm:hidden">
        {mobileFrontSlides.map((slide, index) => {
          const backSlide = mobileBackSlides[index] ?? null;
          const isFlipped = Boolean(mobileFlipped[index] && backSlide);
          return (
            <div
              key={`${slide.id}-mobile-${mobileGroupIndex}-${index}`}
              className="overflow-hidden border border-white/10 bg-white/5 mosaic-cell"
            >
              <div
                className={`relative h-full w-full mosaic-tile${isFlipped ? ' is-flipping' : ''}`}
              >
                <div className="absolute inset-0 mosaic-face mosaic-front">
                  <Image
                    src={slide.src}
                    alt=""
                    fill
                    sizes="50vw"
                    className="absolute inset-0 object-cover blur-2xl scale-110 opacity-35"
                    aria-hidden
                  />
                  {slide.alkotasId ? (
                    <Link
                      href={{
                        pathname: '/alkotas/[id]',
                        params: { id: slide.alkotasId },
                      }}
                      className="absolute inset-0 mosaic-link"
                      aria-label={slide.title || 'Alkotas'}
                    >
                      <Image
                        src={slide.src}
                        alt={slide.title}
                        fill
                        sizes="50vw"
                        className="absolute inset-0 h-full w-full object-contain"
                      />
                      <div className="absolute inset-0 bg-gradient-to-t from-black/55 via-black/10 to-transparent" />
                      <div className="mosaic-caption absolute left-3 bottom-3 right-3">
                        <div className="text-[9px] uppercase tracking-[0.24em] text-white/60 truncate">
                          {slide.subtitle}
                        </div>
                        <div className="mt-1 text-xs font-semibold truncate">{slide.title}</div>
                      </div>
                    </Link>
                  ) : (
                    <>
                      <Image
                        src={slide.src}
                        alt={slide.title}
                        fill
                        sizes="50vw"
                        className="absolute inset-0 h-full w-full object-contain"
                      />
                      <div className="absolute inset-0 bg-gradient-to-t from-black/55 via-black/10 to-transparent" />
                      <div className="mosaic-caption absolute left-3 bottom-3 right-3">
                        <div className="text-[9px] uppercase tracking-[0.24em] text-white/60 truncate">
                          {slide.subtitle}
                        </div>
                        <div className="mt-1 text-xs font-semibold truncate">{slide.title}</div>
                      </div>
                    </>
                  )}
                </div>
                {backSlide ? (
                  <div className="absolute inset-0 mosaic-face mosaic-back">
                    {isFlipped && (
                      <>
                        <Image
                          src={backSlide.src}
                          alt=""
                          fill
                          sizes="50vw"
                          className="absolute inset-0 object-cover blur-2xl scale-110 opacity-35"
                          aria-hidden
                        />
                        {backSlide.alkotasId ? (
                          <Link
                            href={{
                              pathname: '/alkotas/[id]',
                              params: { id: backSlide.alkotasId },
                            }}
                            className="absolute inset-0 mosaic-link"
                            aria-label={backSlide.title || 'Alkotas'}
                          >
                            <Image
                              src={backSlide.src}
                              alt={backSlide.title}
                              fill
                              sizes="50vw"
                              className="absolute inset-0 h-full w-full object-contain"
                            />
                            <div className="absolute inset-0 bg-gradient-to-t from-black/55 via-black/10 to-transparent" />
                            <div className="mosaic-caption absolute left-3 bottom-3 right-3">
                              <div className="text-[9px] uppercase tracking-[0.24em] text-white/60 truncate">
                                {backSlide.subtitle}
                              </div>
                              <div className="mt-1 text-xs font-semibold truncate">
                                {backSlide.title}
                              </div>
                            </div>
                          </Link>
                        ) : (
                          <>
                            <Image
                              src={backSlide.src}
                              alt={backSlide.title}
                              fill
                              sizes="50vw"
                              className="absolute inset-0 h-full w-full object-contain"
                            />
                            <div className="absolute inset-0 bg-gradient-to-t from-black/55 via-black/10 to-transparent" />
                            <div className="mosaic-caption absolute left-3 bottom-3 right-3">
                              <div className="text-[9px] uppercase tracking-[0.24em] text-white/60 truncate">
                                {backSlide.subtitle}
                              </div>
                              <div className="mt-1 text-xs font-semibold truncate">
                                {backSlide.title}
                              </div>
                            </div>
                          </>
                        )}
                      </>
                    )}
                  </div>
                ) : null}
              </div>
            </div>
          );
        })}
      </div>

      <div className="hidden sm:grid grid-cols-4 lg:grid-cols-5 gap-0 auto-rows-[160px] lg:auto-rows-[170px]">
        {frontSlides.map((slide, index) => {
          const backSlide = getBackSlide(index);
          const isFlipped = Boolean(flipped[index]);
          return (
            <div
              key={`${slide.id}-${index}`}
              className="overflow-hidden border border-white/10 bg-white/5 mosaic-cell"
            >
              <div
                className={`relative h-full w-full mosaic-tile${
                  flipped[index] ? ' is-flipping' : ''
                }`}
              >
                <div className="absolute inset-0 mosaic-face mosaic-front">
                  <Image
                    src={slide.src}
                    alt=""
                    fill
                    sizes="(min-width: 1024px) 10vw, (min-width: 640px) 25vw, 50vw"
                    className="absolute inset-0 object-cover blur-2xl scale-110 opacity-35"
                    aria-hidden
                  />
                  {slide.alkotasId ? (
                    <Link
                      href={{
                        pathname: '/alkotas/[id]',
                        params: { id: slide.alkotasId },
                      }}
                      className="absolute inset-0 mosaic-link"
                      aria-label={slide.title || 'Alkotas'}
                      // prefetch={false}
                    >
                      <Image
                        src={slide.src}
                        alt={slide.title}
                        fill
                        sizes="(min-width: 1024px) 10vw, (min-width: 640px) 25vw, 50vw"
                        className="absolute inset-0 h-full w-full object-contain"
                      />
                      <div className="absolute inset-0 bg-gradient-to-t from-black/50 via-black/10 to-transparent" />
                      <div className="mosaic-caption absolute left-4 bottom-4 right-4">
                        <div className="text-[9px] uppercase tracking-[0.28em] text-white/60">
                          {slide.subtitle}
                        </div>
                        <div className="mt-1 text-sm sm:text-base font-semibold truncate">
                          {slide.title}
                        </div>
                      </div>
                    </Link>
                  ) : (
                    <>
                      <Image
                        src={slide.src}
                        alt={slide.title}
                        fill
                        sizes="(min-width: 1024px) 10vw, (min-width: 640px) 25vw, 50vw"
                        className="absolute inset-0 h-full w-full object-contain"
                      />
                      <div className="absolute inset-0 bg-gradient-to-t from-black/50 via-black/10 to-transparent" />
                      <div className="mosaic-caption absolute left-4 bottom-4 right-4">
                        <div className="text-[9px] uppercase tracking-[0.28em] text-white/60">
                          {slide.subtitle}
                        </div>
                        <div className="mt-1 text-sm sm:text-base font-semibold">{slide.title}</div>
                      </div>
                    </>
                  )}
                </div>
                {backSlide ? (
                  <div className="absolute inset-0 mosaic-face mosaic-back">
                    {isFlipped && (
                      <>
                        <Image
                          src={backSlide.src}
                          alt=""
                          fill
                          sizes="(min-width: 1024px) 10vw, (min-width: 640px) 25vw, 50vw"
                          className="absolute inset-0 object-cover blur-2xl scale-110 opacity-35"
                          aria-hidden
                        />
                        {backSlide.alkotasId ? (
                          <Link
                            href={{
                              pathname: '/alkotas/[id]',
                              params: { id: backSlide.alkotasId },
                            }}
                            className="absolute inset-0 mosaic-link"
                            aria-label={backSlide.title || 'Alkotas'}
                            // prefetch={false}
                          >
                            <Image
                              src={backSlide.src}
                              alt={backSlide.title}
                              fill
                              sizes="(min-width: 1024px) 10vw, (min-width: 640px) 25vw, 50vw"
                              className="absolute inset-0 h-full w-full object-contain"
                            />
                            <div className="absolute inset-0 bg-gradient-to-t from-black/50 via-black/10 to-transparent" />
                            <div className="mosaic-caption absolute left-4 bottom-4 right-4">
                              <div className="text-[9px] uppercase tracking-[0.28em] text-white/60">
                                {backSlide.subtitle}
                              </div>
                              <div className="mt-1 text-sm sm:text-base font-semibold truncate">
                                {backSlide.title}
                              </div>
                            </div>
                          </Link>
                        ) : (
                          <>
                            <Image
                              src={backSlide.src}
                              alt={backSlide.title}
                              fill
                              sizes="(min-width: 1024px) 10vw, (min-width: 640px) 25vw, 50vw"
                              className="absolute inset-0 h-full w-full object-contain"
                            />
                            <div className="absolute inset-0 bg-gradient-to-t from-black/50 via-black/10 to-transparent" />
                            <div className="mosaic-caption absolute left-4 bottom-4 right-4">
                              <div className="text-[9px] uppercase tracking-[0.28em] text-white/60">
                                {backSlide.subtitle}
                              </div>
                              <div className="mt-1 text-sm sm:text-base font-semibold">
                                {backSlide.title}
                              </div>
                            </div>
                          </>
                        )}
                      </>
                    )}
                  </div>
                ) : null}
              </div>
            </div>
          );
        })}
      </div>
      <style>{`
          .mosaic-cell {
            perspective: 800px;
            perspective-origin: center;
          }
          .mosaic-tile {
            transform-style: preserve-3d;
            transform-origin: center;
            transition: transform 1400ms cubic-bezier(0.22, 1, 0.36, 1);
            will-change: transform;
            box-shadow: 0 10px 24px rgba(0, 0, 0, 0.25);
          }
          .mosaic-tile.is-flipping {
            transform: rotateY(180deg);
          }
          .mosaic-face {
            backface-visibility: hidden;
            pointer-events: none;
          }
          .mosaic-back {
            transform: rotateY(180deg);
          }
          .mosaic-link {
            pointer-events: auto;
          }
          .mosaic-tile.is-flipping .mosaic-front {
            pointer-events: none;
          }
          .mosaic-tile.is-flipping .mosaic-back {
            pointer-events: auto;
          }
          .mosaic-tile:not(.is-flipping) .mosaic-front {
            pointer-events: auto;
          }
          .mosaic-tile:not(.is-flipping) .mosaic-back {
            pointer-events: none;
          }
          .mosaic-caption {
            opacity: 0;
            transform: translateY(6px);
            transition: opacity 220ms ease, transform 220ms ease;
            pointer-events: none;
          }
          .mosaic-face:hover .mosaic-caption,
          .mosaic-face:focus-within .mosaic-caption {
            opacity: 1;
            transform: translateY(0);
          }
        `}</style>
    </Section>
  );
};

export default HomepageCreationSelectionFramed;
