import { Link } from "@tanstack/react-router";
import { Heart } from "lucide-react";
import { useEffect, useRef, useState } from "react";
import { formatPrice } from "@/lib/format";
import { productImages, type Product } from "@/lib/products";
import { cn } from "@/lib/utils";
import { useShop } from "@/store/use-shop";
import { StarRating } from "./star-rating";

const SLIDE_MS = 1500;

export function ProductCard({ product }: { product: Product }) {
  const wishlist = useShop((s) => s.wishlist);
  const toggle = useShop((s) => s.toggleWishlist);
  const loved = wishlist.includes(product.id);
  const shots = productImages(product);
  const multi = shots.length > 1;
  const [shot, setShot] = useState(0);
  const [hovered, setHovered] = useState(false);
  const touchX = useRef(0);
  const swiped = useRef(false);

  useEffect(() => {
    setShot(0);
    setHovered(false);
  }, [product.id]);

  useEffect(() => {
    if (!hovered || !multi) return;
    const id = window.setInterval(() => {
      setShot((s) => (s + 1) % shots.length);
    }, SLIDE_MS);
    return () => window.clearInterval(id);
  }, [hovered, multi, shots.length, product.id]);

  function canHover() {
    return window.matchMedia("(hover: hover) and (pointer: fine)").matches;
  }

  function onEnter() {
    if (!multi || !canHover()) return;
    setHovered(true);
  }

  function onLeave() {
    setHovered(false);
    setShot(0);
  }

  const shown = hovered || shot !== 0 ? shots : shots.slice(0, 1);

  return (
    <article className="group relative flex flex-col" onMouseEnter={onEnter} onMouseLeave={onLeave}>
      <div
        className="relative overflow-hidden rounded-xl bg-muted"
        onTouchStart={(e) => {
          touchX.current = e.changedTouches[0].clientX;
          swiped.current = false;
        }}
        onTouchEnd={(e) => {
          if (!multi) return;
          const dx = e.changedTouches[0].clientX - touchX.current;
          if (Math.abs(dx) > 36) {
            swiped.current = true;
            setShot((s) => (s + (dx < 0 ? 1 : -1) + shots.length) % shots.length);
          }
        }}
      >
        <Link
          to="/product/$id"
          params={{ id: product.id }}
          className="relative block aspect-portrait"
          onClick={(e) => {
            if (swiped.current) {
              e.preventDefault();
              swiped.current = false;
            }
          }}
        >
          {shown.map((src, i) => (
            <img
              key={src}
              src={src}
              alt={i === 0 ? product.name : ""}
              loading={i === 0 ? "eager" : "lazy"}
              className={cn(
                "absolute inset-0 h-full w-full object-cover transition-opacity duration-500 ease-in-out",
                i === shot ? "opacity-100" : "opacity-0",
              )}
            />
          ))}
        </Link>
        {product.discount > 0 ? (
          <span className="pointer-events-none absolute left-2 top-2 rounded-full bg-accent px-2 py-0.5 text-[10px] font-bold text-accent-foreground sm:left-3 sm:top-3 sm:text-xs">
            -{product.discount}%
          </span>
        ) : null}
        {multi ? (
          <div className="pointer-events-none absolute bottom-2 left-1/2 z-10 flex -translate-x-1/2 gap-1">
            {shots.map((_, i) => (
              <span
                key={i}
                className={cn(
                  "h-1.5 rounded-full transition-all duration-300",
                  i === shot ? "w-4 bg-primary" : "w-1.5 bg-card/80",
                )}
              />
            ))}
          </div>
        ) : null}
      </div>
      <button
        type="button"
        aria-label={loved ? "Remove from wishlist" : "Add to wishlist"}
        onClick={() => toggle(product.id)}
        className={cn(
          "absolute right-2 top-2 z-10 flex size-8 items-center justify-center rounded-full bg-card/90 shadow-sm backdrop-blur-sm transition-colors sm:right-3 sm:top-3 sm:size-9",
          loved ? "text-accent" : "text-muted-foreground hover:text-foreground",
        )}
      >
        <Heart className={cn("size-4", loved && "fill-accent")} />
      </button>
      <div className="mt-3 space-y-1 px-0.5">
        <Link
          to="/product/$id"
          params={{ id: product.id }}
          className="line-clamp-2 block text-sm font-medium leading-snug text-foreground hover:text-primary"
        >
          {product.name}
        </Link>
        <div className="flex items-baseline gap-2">
          <span className="text-sm font-bold tabular-nums text-primary">
            {formatPrice(product.price)}
          </span>
          {product.compareAt > product.price ? (
            <span className="text-xs text-muted-foreground line-through tabular-nums">
              {formatPrice(product.compareAt)}
            </span>
          ) : null}
        </div>
        <StarRating value={product.rating} />
      </div>
    </article>
  );
}
