function CartDrawer({ open, cart, setQty, removeItem, onClose, onConfirm }) {
  if (!open) return null;
  const subtotal = cart.reduce((s, i) => s + i.qty * i.price, 0);
  const total = subtotal;

  return (
    <>
      <div className="scrim-right" onClick={onClose}></div>
      <aside className="drawer" role="dialog" aria-label="Panier">
        <div className="between" style={{ padding: "20px 22px", borderBottom: "1px solid var(--line)" }}>
          <div>
            <div style={{ fontFamily: "Instrument Serif, serif", fontSize: 24 }}>Votre panier</div>
            <div className="small muted">{cart.length} article{cart.length > 1 ? "s" : ""}</div>
          </div>
          <button className="btn btn-ghost btn-sm" onClick={onClose} aria-label="Fermer"><Icon.X /></button>
        </div>

        <div style={{ flex: 1, overflow: "auto", padding: 22 }}>
          {cart.length === 0 && (
            <div style={{ textAlign: "center", padding: "40px 20px", color: "var(--muted)" }}>
              <div style={{ fontSize: 40, marginBottom: 8 }}>🧺</div>
              <p style={{ marginBottom: 18 }}>Votre panier est vide.</p>
              <button className="btn btn-primary btn-sm" onClick={onClose}>Voir le menu</button>
            </div>
          )}
          {cart.map(item => (
            <div key={item.id} style={{ display: "flex", gap: 12, padding: "14px 0", borderBottom: "1px dashed var(--line)" }}>
              <div style={{ flex: 1 }}>
                <div style={{ fontWeight: 500, fontFamily: "Instrument Serif, serif", fontSize: 17 }}>{item.name}</div>
                <div className="small muted num" style={{ marginTop: 2 }}>
                  {item.price.toFixed(2).replace(".", ",")} € l'unité
                </div>
                <div className="row" style={{ marginTop: 10, gap: 12 }}>
                  <QtyControl qty={item.qty} setQty={(q) => setQty(item.id, q)} />
                  <button onClick={() => removeItem(item.id)} className="small" style={{ color: "var(--muted)", padding: 0, background: "none", textDecoration: "underline" }}>
                    Supprimer
                  </button>
                </div>
              </div>
              <div className="num" style={{ fontWeight: 600 }}>
                {(item.price * item.qty).toFixed(2).replace(".", ",")} €
              </div>
            </div>
          ))}
        </div>

        {cart.length > 0 && (
          <div style={{ padding: 22, borderTop: "1px solid var(--line)", background: "var(--cream)" }}>
            <div className="between" style={{ marginTop: 10, paddingTop: 12 }}>
              <span style={{ fontWeight: 600 }}>Total</span>
              <span className="num" style={{ fontWeight: 700, fontSize: 22 }}>{total.toFixed(2).replace(".", ",")} €</span>
            </div>
            <button className="btn btn-primary btn-block" style={{ marginTop: 14 }} onClick={onConfirm}>
              Valider la commande <Icon.ArrowRight />
            </button>
            <p className="xs muted" style={{ textAlign: "center", marginTop: 8 }}>
              Étape suivante : confirmation et paiement sécurisé
            </p>
          </div>
        )}
      </aside>
    </>
  );
}

function QtyControl({ qty, setQty }) {
  return (
    <div style={{ display: "inline-flex", alignItems: "center", border: "1px solid var(--line)", borderRadius: 999, padding: "2px" }}>
      <button onClick={() => setQty(Math.max(1, qty - 1))} style={{ width: 26, height: 26, borderRadius: 999, display: "grid", placeItems: "center" }}><Icon.Minus /></button>
      <span className="num" style={{ minWidth: 22, textAlign: "center", fontSize: 14, fontWeight: 600 }}>{qty}</span>
      <button onClick={() => setQty(qty + 1)} style={{ width: 26, height: 26, borderRadius: 999, display: "grid", placeItems: "center" }}><Icon.Plus /></button>
    </div>
  );
}

function Line({ label, value }) {
  return (
    <div className="between" style={{ padding: "4px 0" }}>
      <span className="small muted">{label}</span>
      <span className="num">{value.toFixed(2).replace(".", ",")} €</span>
    </div>
  );
}

// ── Confirmation modal ──────────────────────────────────────────
const RESTAURANT_LAT = 48.84018, RESTAURANT_LON = 2.37855;

function haversineKm(lat1, lon1, lat2, lon2) {
  const R = 6371;
  const dLat = (lat2 - lat1) * Math.PI / 180;
  const dLon = (lon2 - lon1) * Math.PI / 180;
  const a = Math.sin(dLat / 2) ** 2 +
    Math.cos(lat1 * Math.PI / 180) * Math.cos(lat2 * Math.PI / 180) * Math.sin(dLon / 2) ** 2;
  return R * 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
}

async function geocodeAddress(address) {
  const url = "https://photon.komoot.io/api/?q=" + encodeURIComponent(address) + "&limit=1&lang=fr&bbox=2.2241,48.8156,2.4699,48.9021";
  const data = await fetch(url).then(r => r.json());
  if (!data.features?.length) return null;
  const [lon, lat] = data.features[0].geometry.coordinates;
  return { lat, lon };
}

function photonDisplayName(p) {
  const parts = [
    p.housenumber && p.street ? `${p.housenumber} ${p.street}` : p.street || p.name,
    p.postcode && p.city ? `${p.postcode} ${p.city}` : p.city,
  ].filter(Boolean);
  return parts.join(", ");
}

function isDeliveryOpen() {
  const now = new Date();
  const day = now.getDay(); // 0=dim, 1=lun … 5=ven, 6=sam
  if (day === 0 || day === 6) return false; // livraison lun-ven uniquement
  const h = now.getHours(), m = now.getMinutes(), total = h * 60 + m;
  return total >= 12 * 60 && total < 14 * 60 + 30;
}

function ConfirmCartModal({ cart, onClose, onPay, authUser }) {
  const deliveryAvailable = authUser || isDeliveryOpen();
  const [type, setType] = React.useState(deliveryAvailable ? "Livraison" : "À emporter");
  const [form, setForm] = React.useState({ name: "", phone: "", email: "", address: "", note: "" });
  const [zoneError, setZoneError] = React.useState("");
  const [zoneChecking, setZoneChecking] = React.useState(false);
  const [suggestions, setSuggestions] = React.useState([]);
  const [showSuggestions, setShowSuggestions] = React.useState(false);
  const selectedCoordsRef = React.useRef(null);
  const debounceRef = React.useRef(null);
  const subtotal = cart.reduce((s, i) => s + i.qty * i.price, 0);
  const total = subtotal;

  React.useEffect(() => {
    if (type !== "Livraison" || form.address.length < 3) { setSuggestions([]); return; }
    clearTimeout(debounceRef.current);
    debounceRef.current = setTimeout(async () => {
      try {
        const url = "https://photon.komoot.io/api/?q=" + encodeURIComponent(form.address) + "&limit=5&lang=fr&bbox=2.2241,48.8156,2.4699,48.9021";
        const data = await fetch(url).then(r => r.json());
        const seen = new Set();
        const items = (data.features || []).map(f => ({
          label: photonDisplayName(f.properties),
          lat: f.geometry.coordinates[1],
          lon: f.geometry.coordinates[0],
        })).filter(s => {
          if (!s.label || seen.has(s.label)) return false;
          seen.add(s.label);
          return true;
        });
        setSuggestions(items);
        setShowSuggestions(true);
      } catch { setSuggestions([]); }
    }, 400);
    return () => clearTimeout(debounceRef.current);
  }, [form.address, type]);

  const valid = form.name.trim() && form.phone.trim() && (type === "À emporter" || form.address.trim()) && !zoneChecking;

  const handleSubmit = async () => {
    if (type === "Livraison") {
      setZoneError("");
      setZoneChecking(true);
      try {
        const coords = selectedCoordsRef.current || await geocodeAddress(form.address);
        if (!coords) {
          setZoneError("Adresse introuvable. Veuillez vérifier votre saisie.");
          setZoneChecking(false);
          return;
        }
        const dist = haversineKm(RESTAURANT_LAT, RESTAURANT_LON, coords.lat, coords.lon);
        if (dist > 2) {
          setZoneError(`Adresse hors zone de livraison (${dist.toFixed(1)} km du restaurant). Nous livrons uniquement dans un rayon de 2 km.`);
          setZoneChecking(false);
          return;
        }
      } catch {
        setZoneError("Impossible de vérifier l'adresse. Veuillez réessayer.");
        setZoneChecking(false);
        return;
      }
      setZoneChecking(false);
    }
    onPay({ type, ...form, total });
  };

  return (
    <div className="scrim" onClick={(e) => e.target === e.currentTarget && onClose()}>
      <div className="modal" style={{ maxWidth: 560 }}>
        <div className="between" style={{ padding: "20px 24px", borderBottom: "1px solid var(--line)" }}>
          <div>
            <div className="label" style={{ color: "var(--accent)" }}>Étape 1 / 3</div>
            <div style={{ fontFamily: "Instrument Serif, serif", fontSize: 24 }}>Confirmer votre commande</div>
          </div>
          <button className="btn btn-ghost btn-sm" onClick={onClose}><Icon.X /></button>
        </div>

        <div style={{ padding: 24 }}>
          <div className="label">Récapitulatif</div>
          <div style={{ background: "var(--cream)", borderRadius: 12, padding: 14, marginTop: 6, marginBottom: 22 }}>
            {cart.map(i => (
              <div key={i.id} className="between" style={{ padding: "4px 0" }}>
                <span className="small">{i.qty} × {i.name}</span>
                <span className="small num">{(i.qty * i.price).toFixed(2).replace(".", ",")} €</span>
              </div>
            ))}
            <div className="between" style={{ marginTop: 8, paddingTop: 8, borderTop: "1px dashed var(--line)" }}>
              <span style={{ fontWeight: 600 }}>Total</span>
              <span className="num" style={{ fontWeight: 700 }}>{total.toFixed(2).replace(".", ",")} €</span>
            </div>
          </div>

          <div className="label">Mode de retrait</div>
          <div className="grid-2" style={{ marginTop: 6, marginBottom: 18 }}>
            {[
              { id: "Livraison",  sub: deliveryAvailable ? "Sous 30–45 min" : "Indisponible actuellement", disabled: !deliveryAvailable },
              { id: "À emporter", sub: "Prêt en 20 min", disabled: false },
            ].map(t => (
              <button key={t.id} onClick={() => !t.disabled && setType(t.id)} style={{
                padding: 14, borderRadius: 12,
                background: type === t.id ? "var(--ink)" : "#fff",
                color: type === t.id ? "#fff" : t.disabled ? "var(--muted)" : "var(--ink)",
                border: "1px solid " + (type === t.id ? "var(--ink)" : "var(--line)"),
                fontWeight: 500, textAlign: "left",
                opacity: t.disabled ? .55 : 1,
                cursor: t.disabled ? "not-allowed" : "pointer",
              }}>
                <div>{t.id}</div>
                <div className="xs" style={{ opacity: .7, marginTop: 2 }}>{t.sub}</div>
              </button>
            ))}
          </div>
          {!deliveryAvailable && (
            <div style={{ marginTop: -10, marginBottom: 16, fontSize: 12, color: "var(--muted)", background: "var(--cream)", borderRadius: 8, padding: "8px 12px" }}>
              La livraison est disponible du lundi au vendredi de 12h à 14h30.
            </div>
          )}

          <div className="grid-2">
            <div className="field">
              <label className="label">Nom complet *</label>
              <input className="input" value={form.name} onChange={e => setForm({...form, name: e.target.value})} placeholder="Marie Dupont" />
            </div>
            <div className="field">
              <label className="label">Téléphone *</label>
              <input className="input" value={form.phone} onChange={e => setForm({...form, phone: e.target.value})} placeholder="06 12 34 56 78" />
            </div>
          </div>
          <div className="field" style={{ marginTop: 12 }}>
            <label className="label">Email <span style={{ fontWeight: 400, textTransform: "none", letterSpacing: 0 }}>(pour reçu de commande)</span></label>
            <input className="input" type="email" value={form.email} onChange={e => setForm({...form, email: e.target.value})} placeholder="marie@exemple.fr" autoComplete="email" />
          </div>
          {type === "Livraison" && (
            <div className="field" style={{ marginTop: 12, position: "relative" }}>
              <label className="label">Adresse de livraison *</label>
              <input
                className="input"
                value={form.address}
                onChange={e => { setForm({...form, address: e.target.value}); setZoneError(""); setShowSuggestions(true); selectedCoordsRef.current = null; }}
                onBlur={() => setTimeout(() => setShowSuggestions(false), 150)}
                onFocus={() => suggestions.length && setShowSuggestions(true)}
                placeholder="9 rue Henri Desgranges, 75012 Paris"
                autoComplete="off"
              />
              {showSuggestions && suggestions.length > 0 && (
                <ul style={{
                  position: "absolute", top: "100%", left: 0, right: 0, zIndex: 200,
                  background: "#fff", border: "1px solid var(--line)", borderRadius: 10,
                  boxShadow: "var(--shadow-lg)", margin: 0, padding: 0, listStyle: "none",
                  maxHeight: 220, overflowY: "auto",
                }}>
                  {suggestions.map((s, i) => (
                    <li key={i}
                      onMouseDown={() => { setForm(f => ({...f, address: s.label})); selectedCoordsRef.current = { lat: s.lat, lon: s.lon }; setSuggestions([]); setShowSuggestions(false); setZoneError(""); }}
                      style={{
                        padding: "10px 14px", fontSize: 13, cursor: "pointer",
                        borderBottom: i < suggestions.length - 1 ? "1px solid var(--line)" : "none",
                      }}
                      onMouseEnter={e => e.currentTarget.style.background = "var(--cream)"}
                      onMouseLeave={e => e.currentTarget.style.background = "#fff"}
                    >{s.label}</li>
                  ))}
                </ul>
              )}
              {zoneError && (
                <div style={{ marginTop: 6, fontSize: 12, color: "var(--danger)", background: "oklch(0.97 0.02 25)", border: "1px solid oklch(0.92 0.04 25)", borderRadius: 8, padding: "8px 12px" }}>
                  {zoneError}
                </div>
              )}
            </div>
          )}
          <div className="field" style={{ marginTop: 12 }}>
            <label className="label">Note pour le restaurant</label>
            <textarea className="textarea" rows="2" value={form.note} onChange={e => setForm({...form, note: e.target.value})} placeholder="Instructions de livraison, allergies…" />
          </div>
        </div>

        <div className="between" style={{ padding: "16px 24px", borderTop: "1px solid var(--line)", background: "var(--cream)" }}>
          <span className="small muted">Total à payer : <strong className="num" style={{ color: "var(--ink)" }}>{total.toFixed(2).replace(".", ",")} €</strong></span>
          <button className="btn btn-primary" disabled={!valid} onClick={handleSubmit}>
            {zoneChecking ? "Vérification…" : authUser ? "Confirmer la commande" : "Continuer vers le paiement"} <Icon.ArrowRight />
          </button>
        </div>
      </div>
    </div>
  );
}

// ── Payment modal ───────────────────────────────────────────────
function PaymentModal({ details, cart, onClose, onSuccess }) {
  const [processing, setProcessing] = React.useState(false);
  const [initError, setInitError]   = React.useState("");
  const [cardError, setCardError]   = React.useState("");
  const [intentReady, setIntentReady] = React.useState(false);
  const stripeRef       = React.useRef(null);
  const cardElRef       = React.useRef(null);
  const clientSecretRef = React.useRef(null);
  const cardContainerRef = React.useRef(null);
  const total = details.total;

  React.useEffect(() => {
    if (!window.Stripe) { setInitError("Stripe.js non chargé. Veuillez rafraîchir la page."); return; }

    let active = true;
    setIntentReady(false); setInitError(""); setCardError("");

    fetch("/api/create-payment-intent", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ amount: total }),
    })
      .then(r => r.json())
      .then(data => {
        if (!active) return;
        if (data.error) { setInitError(data.error); return; }

        try {
          clientSecretRef.current = data.clientSecret;
          stripeRef.current = Stripe(data.publishableKey);
          const elements = stripeRef.current.elements();
          cardElRef.current = elements.create("card", {
            style: {
              base: {
                fontSize: "15px", color: "#101010",
                fontFamily: "DM Sans, system-ui, sans-serif",
                fontSmoothing: "antialiased",
                "::placeholder": { color: "#aaa49a" },
              },
              invalid: { color: "#c0392b" },
            },
          });
          if (cardContainerRef.current) {
            cardElRef.current.mount(cardContainerRef.current);
            cardElRef.current.on("change", e => { if (active) setCardError(e.error ? e.error.message : ""); });
            cardElRef.current.on("ready",  () => { if (active) setIntentReady(true); });
          }
        } catch (e) {
          if (active) setInitError(e.message || "Impossible de charger le formulaire de paiement.");
        }
      })
      .catch(() => { if (active) setInitError("Impossible d'initialiser le paiement sécurisé."); });

    return () => {
      active = false;
      if (cardElRef.current) { try { cardElRef.current.unmount(); } catch (_) {} cardElRef.current = null; }
    };
  }, []);

  const submit = async () => {
    if (!stripeRef.current || !clientSecretRef.current || !cardElRef.current) return;
    setProcessing(true); setCardError("");
    try {
      const { error, paymentIntent } = await stripeRef.current.confirmCardPayment(
        clientSecretRef.current,
        { payment_method: { card: cardElRef.current } }
      );
      if (error) {
        setCardError(error.message); setProcessing(false);
      } else if (paymentIntent && paymentIntent.status === "succeeded") {
        onSuccess();
      } else {
        setCardError("Paiement non abouti. Veuillez réessayer."); setProcessing(false);
      }
    } catch (e) {
      setCardError("Une erreur est survenue. Veuillez réessayer."); setProcessing(false);
    }
  };

  const canSubmit = !processing && intentReady && !initError && !cardError;

  return (
    <div className="scrim" onClick={(e) => e.target === e.currentTarget && !processing && onClose()}>
      <div className="modal" style={{ maxWidth: 460 }}>
        <div className="between" style={{ padding: "20px 24px", borderBottom: "1px solid var(--line)" }}>
          <div>
            <div className="label" style={{ color: "var(--accent)" }}>Étape 2 / 3</div>
            <div style={{ fontFamily: "Instrument Serif, serif", fontSize: 24 }}>Paiement sécurisé</div>
          </div>
          <button className="btn btn-ghost btn-sm" onClick={onClose} disabled={processing}><Icon.X /></button>
        </div>

        <div style={{ padding: 24 }}>
          <div className="label">Informations carte</div>
          {initError ? (
            <div style={{ marginTop: 6, background: "oklch(0.97 0.02 25)", border: "1px solid oklch(0.92 0.04 25)", borderRadius: 10, padding: "12px 14px", color: "var(--danger)", fontSize: 13 }}>
              {initError}
            </div>
          ) : (
            <div style={{ position: "relative", marginTop: 6 }}>
              <div ref={cardContainerRef} style={{
                padding: "13px", border: "1px solid var(--line)",
                borderRadius: 10, background: "#fff", minHeight: 46,
              }} />
              {!intentReady && (
                <div style={{
                  position: "absolute", inset: 0, display: "flex",
                  alignItems: "center", padding: "0 13px",
                  pointerEvents: "none",
                }}>
                  <span className="small muted">Chargement du formulaire sécurisé…</span>
                </div>
              )}
            </div>
          )}
          {cardError && <div style={{ color: "var(--danger)", fontSize: 13, marginTop: 8 }}>{cardError}</div>}

          <div className="row" style={{ marginTop: 18, color: "var(--muted)", fontSize: 12, gap: 6 }}>
            <Icon.Lock /> <span>Paiement sécurisé SSL · Stripe · Aucune donnée stockée</span>
          </div>
        </div>

        <div className="between" style={{ padding: "16px 24px", borderTop: "1px solid var(--line)", background: "var(--cream)" }}>
          <span className="small muted">À régler : <strong className="num" style={{ color: "var(--ink)" }}>{total.toFixed(2).replace(".", ",")} €</strong></span>
          <button className="btn btn-primary" disabled={!canSubmit} onClick={submit}>
            {processing ? "Traitement…" : "Payer maintenant"}
            {!processing && <Icon.ArrowRight />}
          </button>
        </div>
      </div>
    </div>
  );
}

// ── Order confirmation page ─────────────────────────────────────
function OrderConfirmation({ order, setRoute }) {
  if (!order) return null;
  return (
    <main style={{ padding: "60px 0 80px" }}>
      <div className="container" style={{ maxWidth: 720 }}>
        <div style={{ textAlign: "center", marginBottom: 40 }}>
          <div style={{
            width: 72, height: 72, borderRadius: "50%",
            background: "oklch(0.95 0.06 150)", color: "oklch(0.40 0.14 150)",
            display: "grid", placeItems: "center", margin: "0 auto 24px"
          }}>
            <svg viewBox="0 0 24 24" width="34" height="34" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M5 12.5l4.5 4.5L19 7.5"/></svg>
          </div>
          <div className="label" style={{ color: "var(--accent)" }}>Étape 3 / 3 · Commande confirmée</div>
          <h1 style={{ marginTop: 8, marginBottom: 14 }}>Merci, {order.name.split(" ")[0]} !</h1>
          <p className="muted" style={{ fontSize: 17, maxWidth: 520, margin: "0 auto" }}>
            Votre commande <strong style={{ color: "var(--ink)" }} className="num">{order.id}</strong> est bien enregistrée.
            {order.type === "Livraison"
              ? " Notre livreur arrive sous 30 à 45 minutes."
              : " Elle sera prête à retirer dans 20 minutes."}
          </p>
        </div>

        <div className="order-grid" style={{ marginBottom: 24 }}>
          <Card title="Détails" rows={[
            ["Numéro", <span className="num">{order.id}</span>],
            ["Nom", order.name],
            ["Téléphone", <span className="num">{order.phone}</span>],
            ["Type", order.type],
            ...(order.type === "Livraison" ? [["Adresse", order.address]] : []),
          ]}/>
          <Card title="Statut" rows={[
            ["Reçue",       <span style={{ color: "var(--ok)", fontWeight: 600 }}>✓ {order.when}</span>],
            ["Préparation", <span className="muted">En attente</span>],
            ["Livraison",   <span className="muted">En attente</span>],
          ]}/>
        </div>

        <div style={{ background: "#fff", border: "1px solid var(--line)", borderRadius: 16, padding: 20 }}>
          <div className="label" style={{ marginBottom: 12 }}>Articles commandés</div>
          {order.items.map((i, idx) => (
            <div key={idx} className="between" style={{ padding: "10px 0", borderBottom: "1px dashed var(--line)" }}>
              <div>
                <div style={{ fontWeight: 500 }}>{i.name}</div>
                <div className="small muted num">× {i.qty}</div>
              </div>
              <div className="num" style={{ fontWeight: 600 }}>{(i.qty * i.price).toFixed(2).replace(".", ",")} €</div>
            </div>
          ))}
          <div className="between" style={{ marginTop: 14, paddingTop: 14, borderTop: "2px solid var(--ink)" }}>
            <span style={{ fontFamily: "Instrument Serif, serif", fontSize: 20 }}>Total payé</span>
            <span className="num" style={{ fontFamily: "Instrument Serif, serif", fontSize: 28 }}>{order.total.toFixed(2).replace(".", ",")} €</span>
          </div>
        </div>

        <div className="row" style={{ marginTop: 28, justifyContent: "center", gap: 12 }}>
          <button className="btn btn-ghost" onClick={() => setRoute("home")}>Retour à l'accueil</button>
          <button className="btn btn-primary" onClick={() => setRoute("menu")}>
            Commander à nouveau <Icon.ArrowRight />
          </button>
        </div>

        <p className="small muted" style={{ textAlign: "center", marginTop: 24 }}>
          Pour toute question : <a style={{ color: "var(--accent)" }}>{RESTAURANT.phone}</a>
        </p>
      </div>
    </main>
  );
}

function Card({ title, rows }) {
  return (
    <div style={{ background: "var(--cream)", borderRadius: 16, padding: 20 }}>
      <div className="label" style={{ marginBottom: 10 }}>{title}</div>
      {rows.map(([k, v], i) => (
        <div key={i} className="between" style={{ padding: "6px 0" }}>
          <span className="small muted">{k}</span>
          <span className="small">{v}</span>
        </div>
      ))}
    </div>
  );
}

window.CartDrawer = CartDrawer;
window.ConfirmCartModal = ConfirmCartModal;
window.PaymentModal = PaymentModal;
window.OrderConfirmation = OrderConfirmation;
