"use client";
import { AnimatePresence, motion } from "motion/react";
import Link from "next/link";
import { HexCheck } from "@/components/honeycomb";
import { Container, SectionHeading, LinkButton } from "@/components/ui";
import { TrustBadges } from "@/components/trust-badges";
import { CartItemThumbnail } from "@/components/cart-item-thumbnail";
import { QuantityStepper } from "@/components/quantity-stepper";
import { ProductCard } from "@/components/product-card";
import { useCartStore, cartTotalCents, cartPhysicalQuantity, cartDiscountBase } from "@/store/cart-store";
import { SponsorshipLineDetails, SponsorshipThumb } from "@/components/sponsorship-cart-line";
import { getSponsorshipShopStrings } from "@/i18n/sponsorship/shop";
import WarenkorbLoading from "./loading";
import { useCartStock } from "@/hooks/use-cart-stock";
import { formatPrice } from "@/lib/format";
import { resolveShippingCostCents, getNextShippingTier, type ShippingTierLike } from "@/lib/shipping-calc";
import { resolveBulkDiscount, getNextBulkDiscountTier, type BulkDiscountTierLike } from "@/lib/bulk-discount-calc";
import { useI18n } from "@/i18n/i18n-provider";
import type { ProductWithRelations } from "@/lib/data";
const CROSS_SELL_LIMIT = 3;
export function WarenkorbContent({
tiers,
availableProducts,
bulkDiscountTiers,
}: {
tiers: ShippingTierLike[];
availableProducts: ProductWithRelations[];
bulkDiscountTiers: BulkDiscountTierLike[];
}) {
const { t, locale } = useI18n();
const sponsorshipStrings = getSponsorshipShopStrings(locale);
const items = useCartStore((s) => s.items);
const hasHydrated = useCartStore((s) => s.hasHydrated);
const setQuantity = useCartStore((s) => s.setQuantity);
const removeItem = useCartStore((s) => s.removeItem);
// Live-Bestand je Position — derselbe Hinweis wie auf der Produktkarte/
// -detailseite, aber hier fuer den ggf. seit dem Hinzufuegen veraenderten
// aktuellen Bestand (siehe use-cart-stock.ts).
const stock = useCartStock([...new Set(items.map((item) => item.productId))]);
const subtotal = cartTotalCents(items);
// Gesamtmenge ueber alle Positionen hinweg — mehrere verschiedene Artikel
// werden fuer die Versandstaffel zusammengezaehlt, nicht getrennt bewertet.
// Nur Glaeser zaehlen: eine Urkunde ohne Paket loest keinen Versand aus
// (wie physicalQuantity im Checkout-Server).
const totalQuantity = cartPhysicalQuantity(items);
const hasPhysical = totalQuantity > 0;
const shipping = !hasPhysical ? 0 : resolveShippingCostCents(tiers, totalQuantity);
const nextTier = !hasPhysical ? null : getNextShippingTier(tiers, totalQuantity);
// Live-Vorschau des serverseitig in api/checkout/route.ts automatisch
// angewendeten Mengenrabatts — Hoehe/Menge kommen aus den im Admin-Bereich
// (Gutscheine) gepflegten DiscountCode-Zeilen, nicht mehr aus Konstanten.
// Basis ohne Patenschaftspakete, wie im Server (discountBase).
const discountable = cartDiscountBase(items);
const hasDiscountable = discountable.quantity > 0;
const activeBulkDiscount = !hasDiscountable ? null : resolveBulkDiscount(bulkDiscountTiers, discountable.quantity);
const bulkDiscountCents = activeBulkDiscount
? Math.round((discountable.subtotalCents * activeBulkDiscount.percent) / 100)
: 0;
const nextBulkDiscount = !hasDiscountable ? null : getNextBulkDiscountTier(bulkDiscountTiers, discountable.quantity);
const cartProductIds = new Set(items.map((item) => item.productId));
const crossSellProducts = availableProducts
.filter((product) => !cartProductIds.has(product.id))
.slice(0, CROSS_SELL_LIMIT);
// Fuer den leeren Warenkorb: Honig zuerst, sonst was gerade verfuegbar ist.
const honeyFirst = availableProducts.filter((product) => product.category === "HONIG");
const emptyCartSuggestions = (honeyFirst.length > 0 ? honeyFirst : availableProducts).slice(0, 2);
// Siehe checkout-form.tsx: ohne diese Weiche flackert kurz die
// "leer"-Meldung auf, bevor der Cart-Store aus localStorage nachliest.
if (!hasHydrated) {
return
{t.cart.empty}
{item.weightGrams} g
)} {/* Siehe Kommentar im Cart-Drawer (site-chrome.tsx): persistenter aria-live-Wrapper, damit der erst nach dem ersten Rendern eintreffende Live-Bestand als Ansage bei Screenreadern ankommt. */}{sponsorship ? sponsorshipStrings.cart.soldOut : t.product.outOfStock}
) : !sponsorship && itemStock !== undefined && itemStock <= 5 ? ({t.product.onlyLeft(itemStock)}
) : null}{t.cartPage.nextTierHint(nextTier.unitsUntilNext, formatPrice(nextTier.priceCents, "EUR", locale))}
) : null} {activeBulkDiscount ? ({t.cartPage.bulkDiscountProgress(nextBulkDiscount.unitsUntilNext, nextBulkDiscount.percent)}