// Rein clientseitiger Warenkorb (Phase 1, kein Backend). Speichert im localStorage.
// TODO Phase 2: durch echten Cloudflare-Worker-Warenkorb/Checkout ersetzen.

import { getProduct } from "../data/products";
import { effektiverZeilenpreis } from "../data/rabatt";
import { findeGutschein, gutscheinRabatt, type Gutschein } from "../data/gutscheine";

export interface CartItem {
  slug: string;
  name: string;
  preis: number;
  menge: number;
  // Ob dieser Artikel gerade gekauft werden soll oder nur "im Warenkorb liegen bleibt" für
  // später. Fehlt das Feld (ältere, bereits gespeicherte Warenkörbe), gilt es als ausgewählt —
  // siehe istAusgewaehlt().
  ausgewaehlt?: boolean;
}

/** true, sofern nicht explizit auf false gesetzt — hält ältere localStorage-Warenkörbe ohne
 *  dieses Feld weiterhin vollständig "ausgewählt" (kein Verhaltensbruch für Bestandsbesucher). */
export function istAusgewaehlt(item: CartItem): boolean {
  return item.ausgewaehlt !== false;
}

const KEY = "vandiy_cart_v1";

export function getCart(): CartItem[] {
  if (typeof localStorage === "undefined") return [];
  try {
    return JSON.parse(localStorage.getItem(KEY) || "[]");
  } catch {
    return [];
  }
}

export function saveCart(items: CartItem[]) {
  localStorage.setItem(KEY, JSON.stringify(items));
  window.dispatchEvent(new CustomEvent("cart:changed", { detail: items }));
}

/** Nie mehr als tatsächlich auf Lager ist — greift unabhängig davon, welche Oberfläche
 *  addToCart()/updateQuantity() aufruft, damit diese Regel garantiert eingehalten wird und
 *  nicht nur an einer einzelnen Stelle in der UI. */
function maxBestand(slug: string): number {
  const produkt = getProduct(slug);
  return produkt ? produkt.bestand : Infinity;
}

export function addToCart(item: Omit<CartItem, "menge">, menge = 1) {
  const cart = getCart();
  const max = maxBestand(item.slug);
  const existing = cart.find((i) => i.slug === item.slug);
  if (existing) {
    existing.menge = Math.min(existing.menge + menge, max);
  } else {
    cart.push({ ...item, menge: Math.min(Math.max(1, menge), max) });
  }
  saveCart(cart);
}

export function updateQuantity(slug: string, menge: number) {
  let cart = getCart();
  menge = Math.min(menge, maxBestand(slug));
  if (menge <= 0) {
    cart = cart.filter((i) => i.slug !== slug);
  } else {
    const item = cart.find((i) => i.slug === slug);
    if (item) item.menge = menge;
  }
  saveCart(cart);
}

export function removeFromCart(slug: string) {
  saveCart(getCart().filter((i) => i.slug !== slug));
}

/** Legt fest, ob ein Artikel jetzt gekauft werden soll (true) oder nur im Warenkorb liegen
 *  bleibt, ohne mitgekauft zu werden (false) — z.B. wenn man sich noch nicht sicher ist. */
export function setAusgewaehlt(slug: string, ausgewaehlt: boolean) {
  const cart = getCart();
  const item = cart.find((i) => i.slug === slug);
  if (item) item.ausgewaehlt = ausgewaehlt;
  saveCart(cart);
}

export function cartCount(): number {
  return getCart().reduce((sum, i) => sum + i.menge, 0);
}

// Zwischensumme inkl. Produkt-Rabatt (Prozent/Betrag) UND Mengenrabatt-Staffel — schaut sich
// dafür live die aktuellen Produktdaten an (nicht den bei addToCart gespeicherten Preis), damit
// ein nachträglich geänderter/abgelaufener Rabatt sich sofort korrekt auswirkt. Zählt NUR
// Artikel, die gerade zum Kauf ausgewählt sind — abgewählte Artikel bleiben im Warenkorb liegen,
// fließen aber nicht in Summe/Checkout ein.
export function cartTotal(): number {
  return getCart()
    .filter(istAusgewaehlt)
    .reduce((sum, i) => {
      const produkt = getProduct(i.slug);
      return sum + (produkt ? effektiverZeilenpreis(produkt, i.menge) : i.menge * i.preis);
    }, 0);
}

const COUPON_KEY = "vandiy_coupon_v1";

export function getCouponCode(): string {
  if (typeof localStorage === "undefined") return "";
  return localStorage.getItem(COUPON_KEY) || "";
}

export function setCouponCode(code: string) {
  localStorage.setItem(COUPON_KEY, code.trim());
  window.dispatchEvent(new CustomEvent("cart:changed", { detail: getCart() }));
}

export function clearCoupon() {
  localStorage.removeItem(COUPON_KEY);
  window.dispatchEvent(new CustomEvent("cart:changed", { detail: getCart() }));
}

/** Der aktuell eingelöste Gutschein, falls der gespeicherte Code (noch) gültig ist. */
export function appliedCoupon(): Gutschein | undefined {
  const code = getCouponCode();
  if (!code) return undefined;
  return findeGutschein(code);
}

/** Rabatt-Betrag in Euro, den der eingelöste Gutschein auf die gegebene Zwischensumme gibt. */
export function couponDiscount(subtotal: number): number {
  const g = appliedCoupon();
  return g ? gutscheinRabatt(g, subtotal) : 0;
}
