"use client";

import type { Slider } from "@/app/[name]/(Main)/types/Types";
import clsx from "clsx";
import Link from "next/link";
import { useCallback, useEffect, useMemo, useRef, useState } from "react";

type Props = {
  sliders: Slider[];
};

const AUTOPLAY_MS = 8000;

function getVisibleSliders(sliders: Slider[]) {
  return sliders
    .filter((slider) => slider.isActive !== false && slider.imageUrl)
    .sort((a, b) => (a.order ?? 0) - (b.order ?? 0));
}

function SliderSlide({
  slider,
  priority,
}: {
  slider: Slider;
  priority?: boolean;
}) {
  const image = (
    // eslint-disable-next-line @next/next/no-img-element
    <img
      src={slider.imageUrl}
      alt={slider.title || "promo banner"}
      loading={priority ? "eager" : "lazy"}
      draggable={false}
      className="h-full w-full object-cover"
      onError={(event) => {
        event.currentTarget.src = "/assets/images/food-image.png";
      }}
    />
  );

  const slideContent = (
    <div className="relative aspect-[2.4/1] w-full overflow-hidden rounded-2xl">
      {image}
      {slider.title ? (
        <div className="pointer-events-none absolute bottom-6 right-3 max-w-[75%]">
          <p className="truncate text-right text-sm font-medium text-white drop-shadow-[0_2px_4px_rgba(0,0,0,0.7)]">
            {slider.title}
          </p>
        </div>
      ) : null}
    </div>
  );

  if (!slider.link) {
    return slideContent;
  }

  const isExternal = /^https?:\/\//i.test(slider.link);

  if (isExternal) {
    return (
      <a
        href={slider.link}
        target="_blank"
        rel="noopener noreferrer"
        className="block w-full shrink-0 snap-center"
        aria-label={slider.title || "promo banner"}
      >
        {slideContent}
      </a>
    );
  }

  return (
    <Link
      href={slider.link}
      className="block w-full shrink-0 snap-center"
      aria-label={slider.title || "promo banner"}
    >
      {slideContent}
    </Link>
  );
}

export default function HomeSliderCarousel({ sliders }: Props) {
  const visibleSliders = useMemo(() => getVisibleSliders(sliders), [sliders]);
  const scrollRef = useRef<HTMLDivElement>(null);
  const slideRefs = useRef<(HTMLDivElement | null)[]>([]);
  const autoplayPausedRef = useRef(false);
  const [activeIndex, setActiveIndex] = useState(0);

  const scrollToIndex = useCallback((index: number) => {
    slideRefs.current[index]?.scrollIntoView({
      behavior: "smooth",
      block: "nearest",
      inline: "start",
    });
  }, []);

  useEffect(() => {
    const container = scrollRef.current;
    if (!container || visibleSliders.length <= 1) return;

    const handleScroll = () => {
      const slideWidth = container.clientWidth;
      if (!slideWidth) return;

      const nextIndex = Math.round(container.scrollLeft / slideWidth);
      setActiveIndex(Math.min(nextIndex, visibleSliders.length - 1));
    };

    container.addEventListener("scroll", handleScroll, { passive: true });
    handleScroll();

    return () => {
      container.removeEventListener("scroll", handleScroll);
    };
  }, [visibleSliders.length]);

  useEffect(() => {
    if (visibleSliders.length <= 1) return;

    const intervalId = window.setInterval(() => {
      if (autoplayPausedRef.current) return;

      setActiveIndex((currentIndex) => {
        const nextIndex = (currentIndex + 1) % visibleSliders.length;
        scrollToIndex(nextIndex);
        return nextIndex;
      });
    }, AUTOPLAY_MS);

    return () => {
      window.clearInterval(intervalId);
    };
  }, [scrollToIndex, visibleSliders.length]);

  const pauseAutoplay = useCallback(() => {
    autoplayPausedRef.current = true;
    window.setTimeout(() => {
      autoplayPausedRef.current = false;
    }, AUTOPLAY_MS * 2);
  }, []);

  if (visibleSliders.length === 0) {
    return null;
  }

  return (
    <section className="mb-1 w-full" aria-label="promotional banners">
      <div
        ref={scrollRef}
        dir="ltr"
        className="flex w-full snap-x snap-mandatory overflow-x-auto noscrollbar touch-pan-x"
        onTouchStart={pauseAutoplay}
        onMouseDown={pauseAutoplay}
      >
        {visibleSliders.map((slider, index) => (
          <div
            key={slider.id}
            ref={(element) => {
              slideRefs.current[index] = element;
            }}
            className="w-full shrink-0 snap-start"
          >
            <SliderSlide slider={slider} priority={index === 0} />
          </div>
        ))}
      </div>

      {visibleSliders.length > 1 ? (
        <div className="mt-2 flex items-center justify-center gap-1.5">
          {visibleSliders.map((slider, index) => (
            <button
              key={slider.id}
              type="button"
              aria-label={`Go to slide ${index + 1}`}
              aria-current={index === activeIndex}
              onClick={() => {
                pauseAutoplay();
                setActiveIndex(index);
                scrollToIndex(index);
              }}
              className={clsx(
                "h-1.5 rounded-full transition-all duration-200",
                index === activeIndex ? "w-5 bg-primary" : "w-1.5 bg-foreground/25",
              )}
            />
          ))}
        </div>
      ) : null}
    </section>
  );
}
