import { discountPercent } from "./format";
import type { Product } from "./payload";

// Previously duplicated independently in CartContent.tsx, CheckoutContent.tsx,
// and BestellbestaetigungContent.tsx — pulled into one place now that adding
// discount-code math to all three at once would otherwise mean hand-editing
// 3 near-identical blocks (and risking them drifting apart).

export type CartLine = { entry: { qty: number }; product: Product };
export type DiscountLike = { type: "percent" | "fixed"; value: number };

// Split out from computeCartTotals() below because callers need a subtotal
// figure *before* they can decide a shipping cost (e.g. checking it against
// a free-shipping threshold) — which computeCartTotals itself takes as an
// input, not something it can decide on its own.
export function computeSubtotal(items: CartLine[]): number {
  return items.reduce((sum, { entry, product }) => sum + entry.qty * product.price, 0);
}

export type CartTotals = {
  subtotal: number;
  /** compareAtPrice-based per-product savings — already excluded from
   * `subtotal` (which uses `price`, not `compareAtPrice`), this is a
   * separate display line only. */
  totalSavings: number;
  discountAmount: number;
  total: number;
};

export function computeCartTotals(items: CartLine[], shippingCost: number, discount?: DiscountLike | null): CartTotals {
  const subtotal = computeSubtotal(items);
  const totalSavings = items.reduce((sum, { entry, product }) => {
    const productDiscountPct = discountPercent(product.price, product.compareAtPrice);
    return productDiscountPct !== null ? sum + entry.qty * (product.compareAtPrice! - product.price) : sum;
  }, 0);
  const discountAmount = !discount
    ? 0
    : discount.type === "percent"
      ? (subtotal * discount.value) / 100
      : Math.min(discount.value, subtotal);
  const total = Math.max(0, subtotal - discountAmount) + shippingCost;
  return { subtotal, totalSavings, discountAmount, total };
}
