"use client";

import { ArrowLeft, ArrowRight } from "lucide-react";
import { useEffect, useMemo, useRef, useState } from "react";
import { BrandLogoCard } from "@/components/ui/brand-logo-card";
import type { StorefrontBrandItem } from "@/types/brand";

const TRANSITION_DURATION_MS = 260;

export function HomeBrandLogosSlider({
  brands,
}: {
  brands: StorefrontBrandItem[];
}) {
  const normalizedBrands = useMemo(() => {
    if (brands.length === 0) {
      return [];
    }

    return brands.length >= 6
      ? brands
      : Array.from({ length: 6 }, (_, index) => brands[index % brands.length]);
  }, [brands]);

  const loopedBrands = useMemo(
    () => [...normalizedBrands, ...normalizedBrands, ...normalizedBrands],
    [normalizedBrands],
  );

  const baseLength = normalizedBrands.length;
  const trackRef = useRef<HTMLDivElement>(null);
  const [stepWidth, setStepWidth] = useState(204);
  const [index, setIndex] = useState(baseLength);
  const [isAnimating, setIsAnimating] = useState(true);
  const [isInteractionLocked, setIsInteractionLocked] = useState(false);

  useEffect(() => {
    const track = trackRef.current;

    if (!track) {
      return;
    }

    const measure = () => {
      const firstItem = track.firstElementChild as HTMLElement | null;

      if (!firstItem) {
        return;
      }

      const trackStyles = window.getComputedStyle(track);
      const gap = Number.parseFloat(trackStyles.columnGap || trackStyles.gap || "0");

      setStepWidth(Math.round(firstItem.getBoundingClientRect().width + gap));
    };

    measure();
    window.addEventListener("resize", measure);

    return () => {
      window.removeEventListener("resize", measure);
    };
  }, [loopedBrands.length]);

  useEffect(() => {
    if (baseLength === 0) {
      return;
    }

    let timeoutId: number | undefined;

    if (index >= baseLength * 2) {
      timeoutId = window.setTimeout(() => {
        setIsAnimating(false);
        setIndex(baseLength);
        window.requestAnimationFrame(() => {
          window.requestAnimationFrame(() => {
            setIsAnimating(true);
          });
        });
      }, TRANSITION_DURATION_MS);
    }

    if (index < baseLength) {
      timeoutId = window.setTimeout(() => {
        setIsAnimating(false);
        setIndex(baseLength * 2 - 1);
        window.requestAnimationFrame(() => {
          window.requestAnimationFrame(() => {
            setIsAnimating(true);
          });
        });
      }, TRANSITION_DURATION_MS);
    }

    return () => {
      if (timeoutId) {
        window.clearTimeout(timeoutId);
      }
    };
  }, [baseLength, index]);

  useEffect(() => {
    if (!isInteractionLocked || !isAnimating) {
      return;
    }

    const timeoutId = window.setTimeout(() => {
      setIsInteractionLocked(false);
    }, TRANSITION_DURATION_MS);

    return () => {
      window.clearTimeout(timeoutId);
    };
  }, [isAnimating, isInteractionLocked, index]);

  if (baseLength === 0) {
    return null;
  }

  function moveByStep(direction: 1 | -1) {
    if (isInteractionLocked) {
      return;
    }

    setIsInteractionLocked(true);
    setIsAnimating(true);
    setIndex((currentIndex) => currentIndex + direction);
  }

  return (
    <div className="relative">
      <div className="pointer-events-none absolute inset-y-0 left-10 z-10 hidden w-16 bg-[linear-gradient(90deg,rgba(250,250,250,1)_10%,rgba(250,250,250,0)_100%)] md:block" />
      <div className="pointer-events-none absolute inset-y-0 right-10 z-10 hidden w-16 bg-[linear-gradient(270deg,rgba(250,250,250,1)_10%,rgba(250,250,250,0)_100%)] md:block" />

      <div className="flex items-center justify-between gap-3 md:gap-6">
        <button
          type="button"
          aria-label="Prethodni brend"
          onClick={() => moveByStep(-1)}
          disabled={isInteractionLocked}
          className="inline-flex size-7 items-center justify-center border-0 bg-transparent text-primary transition-opacity disabled:opacity-40"
        >
          <ArrowLeft className="size-4" aria-hidden="true" />
        </button>

        <div className="flex-1 overflow-hidden">
          <div
            ref={trackRef}
            className="flex items-center gap-10 md:gap-16"
            style={{
              transform: `translateX(-${index * stepWidth}px)`,
              transition: isAnimating
                ? `transform ${TRANSITION_DURATION_MS}ms ease`
                : "none",
            }}
          >
            {loopedBrands.map((brand, itemIndex) => (
              <BrandLogoCard
                key={`${brand.id}-${itemIndex}`}
                name={brand.name}
                href={brand.href}
                imageUrl={brand.image?.src}
                imageAlt={brand.image?.alt}
              />
            ))}
          </div>
        </div>

        <button
          type="button"
          aria-label="Sljedeći brend"
          onClick={() => moveByStep(1)}
          disabled={isInteractionLocked}
          className="inline-flex size-7 items-center justify-center border-0 bg-transparent text-primary transition-opacity disabled:opacity-40"
        >
          <ArrowRight className="size-4" aria-hidden="true" />
        </button>
      </div>
    </div>
  );
}
