"use client";

import Image from "next/image";
import { RevealGroup, RevealItem } from "../../../components/Reveal";
import { formatPrice, discountPercent, formatDate } from "../../../lib/format";
import { AddToCartInlineButton } from "../../../components/AddToCartInlineButton";
import { WishlistButton } from "../../../components/WishlistButton";
import { useWishlist } from "../../../lib/useWishlist";
import { effectiveTaxRate } from "../../../lib/cartTotals";
import type { Product } from "../../../lib/payload";

// Client Component so removing an item (WishlistButton toggling it off)
// disappears from this grid immediately — the server-rendered initial
// list alone doesn't react to that client-side toggle at all (the parent
// page.tsx is a Server Component, its render is fixed at request time).
// useWishlist()'s live `items` is the actual source of truth for which
// products are still wishlisted; `initialProducts` only supplies the
// display data (name/image/price) for whatever numericIds are currently
// wishlisted, since the wishlist itself only stores product ids.
export function MerklisteGrid({
  initialProducts,
  defaultTaxRate,
  kleinunternehmer,
}: {
  initialProducts: Product[];
  defaultTaxRate: number;
  kleinunternehmer: boolean;
}) {
  const { items } = useWishlist();
  // Preserve the wishlist's own order (most-recently-added-first, via
  // `items`) rather than initialProducts' own order. Zipped with the
  // originating wishlist item (not just the product) so purchasedAt stays
  // attached — the earlier `.map().filter()` chain that only kept the
  // product lost that association.
  const productsByNumericId = new Map(initialProducts.map((p) => [p.numericId, p]));
  const visibleEntries = items
    .map((item) => ({ item, product: productsByNumericId.get(item.productId) }))
    .filter((entry): entry is { item: (typeof items)[number]; product: Product } => Boolean(entry.product));

  if (visibleEntries.length === 0) {
    return <p className="text-body text-text-muted">Du hast noch keine Produkte gemerkt.</p>;
  }

  return (
    <RevealGroup className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6 w-full">
      {visibleEntries.map(({ item, product }) => {
        const discount = discountPercent(product.price, product.compareAtPrice);
        const taxRate = effectiveTaxRate(product, defaultTaxRate);
        const fullyOutOfStock = product.variants.length > 0 ? product.variants.every((v) => v.outOfStock) : product.outOfStock;
        // Already-purchased takes precedence over "Ausverkauft" — a
        // customer who already bought this doesn't need a restock notice,
        // they need to know they already own it (and can still remove it
        // manually via WishlistButton — this is a status note, not an
        // auto-removal, see feedback discussion this implements).
        return (
          <RevealItem key={`${product.id}-${item.variant}`} className="bg-bg-base border border-border rounded-md overflow-hidden flex flex-col h-full">
            <div className="relative w-full aspect-[276/210] overflow-hidden">
              <Image
                src={product.image}
                alt={product.name}
                fill
                sizes="(min-width: 1024px) 33vw, (min-width: 640px) 50vw, 100vw"
                className={`object-cover ${item.purchasedAt || fullyOutOfStock ? "opacity-60" : ""}`}
              />
              {item.purchasedAt ? (
                <span className="absolute top-3 left-3 rounded-full bg-success-subtle px-2.5 py-1 text-label font-bold text-success">
                  Gekauft am {formatDate(item.purchasedAt)}
                </span>
              ) : (
                fullyOutOfStock && (
                  <span className="absolute top-3 left-3 rounded-full bg-text-muted px-2.5 py-1 text-label font-bold text-bg-base">
                    Ausverkauft
                  </span>
                )
              )}
              <WishlistButton productId={product.numericId} className="absolute top-3 right-3" />
            </div>
            <div className="flex flex-col gap-4 items-start px-5 pb-5 pt-4 w-full flex-1">
              <p className="font-semibold text-h4 text-text-primary w-full" style={{ fontFamily: "var(--font-lora)" }}>
                {product.name}
              </p>
              <div className="flex flex-col gap-1 items-start">
                <p className="flex items-baseline gap-1.5">
                  {discount !== null && (
                    <span className="text-label text-text-muted line-through">{formatPrice(product.compareAtPrice!)}</span>
                  )}
                  <span className="font-bold text-h4 text-text-primary">{formatPrice(product.price)}</span>
                  {!kleinunternehmer && <span className="text-label text-text-muted">inkl. {taxRate}% MwSt.</span>}
                </p>
              </div>
              {/* No className override — AddToCartInlineButton's `className`
                  prop REPLACES its whole default styling (`?? defaultClass`,
                  not a merge), so passing just "w-full" here previously threw
                  away all the button's actual styling. Its default is
                  already `w-full`. */}
              <AddToCartInlineButton id={product.id} outOfStock={product.outOfStock} maxQty={product.maxQty} variants={product.variants} />
            </div>
          </RevealItem>
        );
      })}
    </RevealGroup>
  );
}
