"use client";

import {
  Children,
  useCallback,
  useEffect,
  useRef,
  useState,
  type ReactNode,
} from "react";
import { ChevronLeft, ChevronRight } from "lucide-react";
import { Button } from "@/components/ui/button";
import { cn } from "@/lib/utils";

interface ResponsiveCarouselProps {
  children: ReactNode;
  /** Tailwind width classes for each slide on mobile */
  slideClassName?: string;
  /** Tailwind classes for the desktop grid */
  desktopClassName?: string;
}

export function ResponsiveCarousel({
  children,
  slideClassName = "w-[84vw] max-w-[340px]",
  desktopClassName = "md:grid md:grid-cols-2 lg:grid-cols-3 md:gap-6",
}: ResponsiveCarouselProps) {
  const scrollRef = useRef<HTMLDivElement>(null);
  const items = Children.toArray(children);
  const [active, setActive] = useState(0);

  const updateActiveIndex = useCallback(() => {
    const el = scrollRef.current;
    if (!el || el.children.length === 0) return;

    const center = el.scrollLeft + el.clientWidth / 2;
    let closest = 0;
    let minDist = Infinity;

    Array.from(el.children).forEach((child, i) => {
      const slide = child as HTMLElement;
      const slideCenter = slide.offsetLeft + slide.offsetWidth / 2;
      const dist = Math.abs(center - slideCenter);
      if (dist < minDist) {
        minDist = dist;
        closest = i;
      }
    });

    setActive(closest);
  }, []);

  useEffect(() => {
    const el = scrollRef.current;
    if (!el) return;
    updateActiveIndex();
    el.addEventListener("scroll", updateActiveIndex, { passive: true });
    return () => el.removeEventListener("scroll", updateActiveIndex);
  }, [updateActiveIndex, items.length]);

  const scrollTo = (index: number) => {
    const el = scrollRef.current;
    if (!el) return;
    const clamped = Math.max(0, Math.min(index, items.length - 1));
    const slide = el.children[clamped] as HTMLElement | undefined;
    slide?.scrollIntoView({
      behavior: "smooth",
      inline: "center",
      block: "nearest",
    });
  };

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

  return (
    <>
      {/* Mobile carousel */}
      <div className="mt-10 md:hidden">
        <div
          ref={scrollRef}
          className="-mx-4 flex gap-4 overflow-x-auto scroll-smooth px-4 pb-2 snap-x snap-mandatory [scrollbar-width:none] [-ms-overflow-style:none] [&::-webkit-scrollbar]:hidden"
        >
          {items.map((child, i) => (
            <div
              key={i}
              className={cn("snap-center shrink-0", slideClassName)}
            >
              {child}
            </div>
          ))}
        </div>

        {items.length > 1 && (
          <div className="mt-4 flex items-center justify-center gap-4">
            <Button
              type="button"
              variant="outline"
              size="icon-sm"
              onClick={() => scrollTo(active - 1)}
              disabled={active === 0}
              aria-label="上一張"
            >
              <ChevronLeft className="size-4" />
            </Button>

            <div className="flex items-center gap-1.5" role="tablist">
              {items.map((_, i) => (
                <button
                  key={i}
                  type="button"
                  role="tab"
                  aria-selected={i === active}
                  aria-label={`第 ${i + 1} 張`}
                  onClick={() => scrollTo(i)}
                  className={cn(
                    "rounded-full transition-all duration-300",
                    i === active
                      ? "h-2 w-6 bg-primary"
                      : "size-2 bg-muted-foreground/30 hover:bg-muted-foreground/50"
                  )}
                />
              ))}
            </div>

            <Button
              type="button"
              variant="outline"
              size="icon-sm"
              onClick={() => scrollTo(active + 1)}
              disabled={active === items.length - 1}
              aria-label="下一張"
            >
              <ChevronRight className="size-4" />
            </Button>
          </div>
        )}
      </div>

      {/* Desktop grid */}
      <div className={cn("mt-10 hidden", desktopClassName)}>{children}</div>
    </>
  );
}