import React, {
  useEffect, useMemo, useState, useCallback, startTransition, useDeferredValue
} from "react";
import {
  getCurrentUser, getProducts, createBooking, getFavorites,
  updateFavorites, logout, API_BASE, getCategories
} from "../api";
import ProductCard from "./ProductCard";
import CartItem from "./CartItem";
import { useLocation, useNavigate } from "react-router-dom";

const DEFAULT_BG1 = "#0a6bff";
const DEFAULT_BG2 = "#00e0aa";

function applyOrderColorsFromStorage() {
  const c1 = localStorage.getItem("order_bg1") || DEFAULT_BG1;
  const c2 = localStorage.getItem("order_bg2") || DEFAULT_BG2;
  document.documentElement.style.setProperty("--order-bg1", c1);
  document.documentElement.style.setProperty("--order-bg2", c2);
}

// --- NEU: lokale Bestände anhand des Warenkorbs reduzieren
function decrementStockLocal(prevProducts, cart) {
  const delta = {};
  for (const { product, quantity } of Object.values(cart)) {
    delta[product.id] = (delta[product.id] || 0) + quantity;
  }
  return prevProducts.map((p) =>
    delta[p.id] ? { ...p, stock: (Number(p.stock) || 0) - delta[p.id] } : p
  );
}



const PAGE_SIZE = 20;

// deterministische Farbe je Kategorie
function hueFromString(s) {
  let h = 0;
  for (let i = 0; i < s.length; i++) h = (h * 31 + s.charCodeAt(i)) | 0;
  return (h >>> 0) % 360;
}

// Pastell (inaktiv) vs. kräftig + Glow (aktiv)
function chipStyleFor(cat, active) {
  const strong = (h) => ({
    bg: `hsl(${h} 85% 72%)`,
    br: `hsla(${h} 65% 35% / .60)`,
    glow: `0 0 0 5px hsla(${h} 95% 55% / .40), 0 0 22px hsla(${h} 95% 55% / .50)`,
    fg: "#0b1220",
  });
  const soft = (h) => ({
    bg: `hsl(${h} 65% 90%)`,
    br: `hsla(${h} 40% 40% / .35)`,
    glow: "none",
    fg: "#0b1220",
  });
  if (cat === "Alle") return active
    ? { bg:"hsl(210 75% 74%)", br:"hsla(210 65% 35%/.6)", glow:"0 0 0 5px hsla(210 95% 55%/.4),0 0 22px hsla(210 95% 55%/.5)", fg:"#0b1220" }
    : { bg:"hsl(210 55% 90%)", br:"hsla(210 40% 40%/.35)", glow:"none", fg:"#0b1220" };
  if (cat === "Favoriten") return active
    ? { bg:"hsl(52 90% 72%)", br:"hsla(52 70% 35%/.6)", glow:"0 0 0 5px hsla(52 98% 50%/.4),0 0 22px hsla(52 98% 50%/.5)", fg:"#0b1220" }
    : { bg:"hsl(52 80% 90%)", br:"hsla(52 55% 40%/.35)", glow:"none", fg:"#0b1220" };
  const h = hueFromString(cat);
  return active ? strong(h) : soft(h);
}

function ringColorForCategory(cat) {
  if (!cat) return "#22c55e";
  // nutzt deine bestehende Farblogik der Chips:
  return chipStyleFor(cat, true).br; // starke Border-Farbe der Kategorie
}
// robustes Aktiv-Flag (API kann bool/zahl/string liefern)
function isActiveProduct(p) {
  const v = p?.is_active;
  return v === true || v === 1 || v === "true" || v === "1";
}

const MemoProductCard = React.memo(ProductCard);

export default function Order({ user: userProp }) {
  const navigate = useNavigate();
  const location = useLocation();
  const stateUser = location.state?.user || null;

  const [user, setUser] = useState(userProp || stateUser || null);
  const [products, setProducts] = useState([]);
  const [categories, setCategories] = useState([]);
  const [selectedCategory, setSelectedCategory] = useState("Alle");
  const deferredCategory = useDeferredValue(selectedCategory); // INP
  const [page, setPage] = useState(1);

  const [cart, setCart] = useState({});
  const [favorites, setFavorites] = useState(new Set());
  const [error, setError] = useState("");
  const [loading, setLoading] = useState(true);

  const collator = useMemo(() => new Intl.Collator("de", { sensitivity: "base" }), []);

  useEffect(() => {
    let cancelled = false;
  
    // Farben sofort anwenden + Listener registrieren
    applyOrderColorsFromStorage();
    const onChange = (e) => {
      const { bg1, bg2 } = e.detail || {};
      if (bg1) document.documentElement.style.setProperty("--order-bg1", bg1);
      if (bg2) document.documentElement.style.setProperty("--order-bg2", bg2);
    };
    window.addEventListener("order-bg-change", onChange);
  
    // Daten laden
    (async () => {
      setLoading(true);
      try {
        const [u, prod, cats] = await Promise.all([
          userProp || stateUser ? (userProp || stateUser) : getCurrentUser(),
          getProducts(),
          typeof getCategories === "function" ? getCategories() : Promise.resolve(null),
        ]);
        if (cancelled) return;
  
        setUser(u || null);
        setProducts(Array.isArray(prod) ? prod : []);
        setCategories(
          cats && Array.isArray(cats)
            ? cats
            : Array.from(new Set((prod || []).map((p) => p.category).filter(Boolean)))
        );
  
        if (u?.id) {
          try {
            const f = await getFavorites(u.id);
            if (!cancelled && Array.isArray(f)) setFavorites(new Set(f));
          } catch {}
        }
      } catch (e) {
        if (!cancelled) setError(e?.message || "Initiale Daten konnten nicht geladen werden.");
      } finally {
        if (!cancelled) setLoading(false);
      }
    })();
  
    // Cleanup des Effects
    return () => {
      cancelled = true;
      window.removeEventListener("order-bg-change", onChange);
    };
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [userProp, stateUser]);
  

  const activeProducts = useMemo(
    () => (products || []).filter(isActiveProduct),
    [products]
  );

  const sortedProducts = useMemo(() => {
    const arr = (activeProducts || []).slice();
    arr.sort((a, b) => collator.compare(a?.name || "", b?.name || ""));
    return arr;
  }, [activeProducts, collator]);

  const filtered = useMemo(() => {
    if (deferredCategory === "Favoriten") {
      return sortedProducts.filter((p) => favorites.has(p.id));
    }
    if (deferredCategory === "Alle") return sortedProducts;
    return sortedProducts.filter((p) => p.category === deferredCategory);
  }, [sortedProducts, deferredCategory, favorites]);

  const onSelectCategory = useCallback((cat) => {
    startTransition(() => {
      setSelectedCategory(cat);
      setPage(1);
    });
  }, []);

const DEFAULT_AVATAR = "/avatar-default.png";

const avatarSrc = useMemo(() => {
  const raw = user?.avatar_url?.trim();
  if (!raw) return DEFAULT_AVATAR;
  if (/^(https?:|data:|blob:|\/\/)/i.test(raw)) return raw;
  if (raw === DEFAULT_AVATAR) return raw;
  return `${API_BASE}${raw.startsWith("/") ? raw : `/${raw}`}`;
}, [user?.avatar_url, API_BASE]);

  const total = filtered.length;
  const pageCount = Math.max(1, Math.ceil(total / PAGE_SIZE));
  const currentPage = Math.min(page, pageCount);
  const startIdx = (currentPage - 1) * PAGE_SIZE;
  const endIdx = Math.min(startIdx + PAGE_SIZE, total);
  const pageItems = useMemo(
    () => filtered.slice(startIdx, endIdx),
    [filtered, startIdx, endIdx]
  );

  const handleSelect = useCallback((product) => {
    startTransition(() => {
      setCart((prev) => {
        const qty = prev[product.id]?.quantity || 0;
        return { ...prev, [product.id]: { product, quantity: qty + 1 } };
      });
    });
  }, []);
  const handleIncrement = useCallback((id) =>
    startTransition(() => {
      setCart((prev) => ({ ...prev, [id]: { ...prev[id], quantity: prev[id].quantity + 1 } }));
    }), []);
  const handleDecrement = useCallback((id) =>
    startTransition(() => {
      setCart((prev) => {
        const item = prev[id];
        if (!item) return prev;
        if (item.quantity <= 1) {
          const { [id]: _, ...rest } = prev;
          return rest;
        }
        return { ...prev, [id]: { ...item, quantity: item.quantity - 1 } };
      });
    }), []);

  const handleToggleFavorite = useCallback(async (id) => {
    const before = new Set(favorites);
    const next = new Set(favorites);
    next.has(id) ? next.delete(id) : next.add(id);
    setFavorites(next);
    try {
      if (!user?.id) throw new Error("Kein Nutzer geladen.");
      await updateFavorites(user.id, [...next]);
    } catch (e) {
      setFavorites(before);
      setError(e?.message || "Favoriten konnten nicht gespeichert werden.");
    }
  }, [favorites, user?.id]);

  const cartItems = useMemo(() => Object.values(cart), [cart]);
  const cartTotalCents = useMemo(
    () => cartItems.reduce((s, { product, quantity }) => s + product.price_cents * quantity, 0),
    [cartItems]
  );

  const handlePay = useCallback(async () => {
    const balance = user?.balance_cents ?? 0;
    if (balance < cartTotalCents) { setError("Zu wenig Geld."); return; }
    try {
      for (const { product, quantity } of cartItems) {
        await createBooking(
          user.id,
          product.id,
          quantity,
          product.price_cents * quantity
        );
      }
      setProducts((prev) => decrementStockLocal(prev, cart));

      try {
        const refreshed = await getCurrentUser();
        if (refreshed) setUser(refreshed);
      } catch {}
      
      setCart({});
      
      try { await logout(); } finally { navigate("/", { replace: true }); }
    } catch (e) {
      setError(e?.message || "Bezahlen fehlgeschlagen.");
    }
  }, [cartItems, cartTotalCents, navigate, user?.balance_cents, user?.id]);

  const handleLogout = useCallback(async () => {
    try { await logout(); } finally { navigate("/", { replace: true }); }
  }, [navigate]);

  const effectiveBalanceCents = (user?.balance_cents ?? 0) - cartTotalCents;
  const balance = (effectiveBalanceCents / 100).toFixed(2).replace(".", ",");
  const balanceColor = effectiveBalanceCents <= 0 ? "text-red-400" : "text-green-400";

  // Kategorien-UI aus aktiven Produkten ableiten (ohne useMemo)
  const catsBase = (categories && categories.length)
    ? categories
    : Array.from(new Set((activeProducts || []).map(p => p.category).filter(Boolean)));
  const catsForUI = ["Alle", ...catsBase, "Favoriten"];

  if (loading) {
    return <div className="flex items-center justify-center h-screen bg-gray-900 text-white">Lädt …</div>;
  }

  return (
    <div className="flex h-screen">
      {/* Produktbereich */}
      <div
        className="w-3/4 flex flex-col p-4"
        style={{
          background: `
            radial-gradient(1600px 800px at 70% 0%, var(--order-bg1, ${DEFAULT_BG1}) 0%, transparent 60%),
            radial-gradient(1600px 800px at 10% 100%, var(--order-bg2, ${DEFAULT_BG2}) 0%, transparent 60%),
            linear-gradient(180deg,var(--order-bg2, ${DEFAULT_BG1}) 0%,var(--order-bg1, ${DEFAULT_BG2}) 100%)`
        }}
      >
        {/* Kategorie-Chips */}
        <div className="flex flex-wrap items-center gap-3 mb-3">
          {catsForUI.map((cat) => {
            const active = selectedCategory === cat;
            const c = chipStyleFor(cat, active);
            return (
              <button
                key={cat}
                onClick={() => onSelectCategory(cat)}
                className="px-4 py-2 rounded-xl font-semibold transition shadow-sm hover:shadow outline-none border focus:ring-2"
                style={{
                  backgroundColor: c.bg,
                  color: c.fg,
                  borderColor: c.br,
                  boxShadow: active ? c.glow : "none",
                  transform: active ? "translateZ(0) scale(1.02)" : "none",
                  transition: "background-color .14s, border-color .14s, box-shadow .16s, transform .12s",
                }}
              >
                {cat}
              </button>
            );
          })}
          <div className="ml-auto text-sm text-gray-400">
            {total === 0 ? "0" : `${startIdx + 1}`}–{endIdx} von {total}
          </div>
        </div>

        {/* Grid */}
        <div className="grid grid-cols-[repeat(auto-fill,minmax(250px,1fr))] gap-4 overflow-auto flex-1 auto-rows-min">
          {pageItems.map((p) => (
            <div
              key={p.id}
              style={{ contentVisibility: "auto", containIntrinsicSize: "300px 360px" }}
            >
              <MemoProductCard
                product={p}
                onSelect={handleSelect}
                isFavorite={favorites.has(p.id)}
                onToggleFavorite={handleToggleFavorite}
                count={cart[p.id]?.quantity || 0}
                ringColor={ringColorForCategory(p.category)}
              />
            </div>
          ))}
          {pageItems.length === 0 && (
            <div className="text-gray-400 italic">Keine Produkte gefunden.</div>
          )}
        </div>

        {/* Pagination */}
        <div className="mt-3 flex items-center justify-center gap-1 select-none">
          <button
            onClick={() => startTransition(() => setPage((p) => Math.max(1, p - 1)))}
            disabled={currentPage <= 1}
            className="px-3 py-1 rounded-md bg-gray-700 text-gray-200 disabled:opacity-40">‹</button>

          {Array.from({ length: pageCount }, (_, i) => i + 1).map((n) => (
            <button
              key={n}
              onClick={() => startTransition(() => setPage(n))}
              className={`px-3 py-1 rounded-md ${n === currentPage ? "bg-green-500 text-white" : "bg-gray-700 text-gray-200 hover:bg-gray-600"}`}>
              {n}
            </button>
          ))}

          <button
            onClick={() => startTransition(() => setPage((p) => Math.min(pageCount, p + 1)))}
            disabled={currentPage >= pageCount}
            className="px-3 py-1 rounded-md bg-gray-700 text-gray-200 disabled:opacity-40">›</button>
        </div>
      </div>

      {/* Warenkorb */}
      <div className="w-1/4 relative bg-gray-950 p-4 flex flex-col justify-between">
        <div className="relative z-10 flex flex-col flex-1">
          <div className="flex items-center mb-4">
            <img
              src={avatarSrc}
              alt="Profil"
              className="w-12 h-12 rounded-full mr-3 object-cover ring-1 ring-white/10"
              loading="lazy" decoding="async"
              onError={(e) => { e.currentTarget.onerror = null; e.currentTarget.src = DEFAULT_AVATAR; }}
            />
            <span className="font-semibold text-white text-lg">
              Willkommen {user?.name || user?.alias}
            </span>
          </div>

          <div className="mb-4">
            <div className="text-white text-sm font-bold">Kontostand:</div>
            <div className={`text-2xl font-bold ${balanceColor}`}>€{balance}</div>
          </div>

          <div className="bg-gray-100 rounded-xl p-4 overflow-auto flex-1 mb-4">
            {Object.values(cart).length === 0 && <div className="text-gray-500 italic">Warenkorb ist leer</div>}
            {Object.values(cart).map((item) => (
              <CartItem key={item.product.id} item={item} onIncrement={handleIncrement} onDecrement={handleDecrement} />
            ))}
          </div>

          {error && <div className="text-red-500 mb-2 truncate">{error}</div>}
          <div className="text-right text-white font-semibold mb-2">
            Einkaufssumme: €{(cartTotalCents / 100).toFixed(2).replace(".", ",")}
          </div>
        </div>

        <div className="relative z-10 flex gap-3 mb-3">
          <button onClick={handleLogout}
                  className="flex-1 bg-red-700 hover:bg-red-600 text-white py-2 rounded-xl font-semibold">
            Abbrechen
          </button>
          <button onClick={handlePay}
                  disabled={cartItems.length === 0}
                  className="flex-1 bg-green-700 hover:bg-green-600 text-white py-2 rounded-xl font-semibold disabled:opacity-50">
            Bezahlen
          </button>
        </div>
      </div>
    </div>
  );
}
