/* Sweet Haven — Checkout flow + order Confirmation */

const { useState: useStateCO } = React;

function fieldList(items) {
  return Object.values(items);
}

// --- Paystack helpers -------------------------------------------------------
// The public key is fetched from our own serverless endpoint so nothing is
// hardcoded and switching test <-> live keys is just a Vercel env change.
async function shFetchPublicKey() {
  const r = await fetch("/api/paystack-config");
  if (!r.ok) throw new Error("config");
  const d = await r.json();
  if (!d || !d.publicKey) throw new Error("config");
  return d.publicKey;
}

// Confirm the payment on the server before we ever show "order placed". We send
// the line items (id + size + qty, NOT the price) and fulfilment method so the
// server can re-price the order itself and reject a tampered/underpaid total.
async function shVerifyPayment(reference, method, entries) {
  const items = entries.map((e) => ({ productId: e.productId, sizeId: e.sizeId, qty: e.qty }));
  const r = await fetch("/api/paystack-verify", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ reference, method, items }),
  });
  return r.json();
}

function Checkout({ items, onBack, onPlace }) {
  const entries = fieldList(items);
  const [method, setMethod] = useStateCO("pickup");
  const [pay, setPay] = useStateCO("card");
  const [email, setEmail] = useStateCO("");
  const [date, setDate] = useStateCO("");
  const [time, setTime] = useStateCO("Morning · 8–11");
  const [dateErr, setDateErr] = useStateCO(false);
  const [busy, setBusy] = useStateCO(false);
  const [payErr, setPayErr] = useStateCO("");
  const subtotal = entries.reduce((s, e) => s + e.price * e.qty, 0);
  const fee = method === "delivery" ? 1500 : 0;
  const total = subtotal + fee;
  const minDate = (() => { const d = new Date(); return d.toISOString().slice(0, 10); })();

  const finish = (extra) =>
    onPlace({ method, pay, total, date, time, email, entries: entries.map((x) => ({ ...x })), ...extra });

  const payWithPaystack = async (publicKey) => {
    const Ctor = window.PaystackPop || window.Paystack;
    if (!Ctor) {
      setBusy(false);
      setPayErr("The payment window didn't load. Please refresh and try again.");
      return;
    }
    const popup = new Ctor();
    popup.newTransaction({
      key: publicKey,
      email: email,
      amount: Math.round(total * 100), // Paystack works in kobo
      currency: "NGN",
      metadata: {
        custom_fields: [
          { display_name: "Fulfilment", variable_name: "fulfilment", value: method },
          { display_name: "When", variable_name: "when", value: date + " · " + time },
        ],
        order: entries.map((x) => ({ name: x.p.name, opt: x.opt, qty: x.qty, price: x.price })),
      },
      onSuccess: async (tx) => {
        try {
          const result = await shVerifyPayment(tx.reference, method, entries);
          if (result && result.status) {
            finish({ ref: tx.reference, paid: true });
          } else {
            setBusy(false);
            setPayErr("We couldn't confirm your payment. If you were charged, contact us with reference " + tx.reference + ".");
          }
        } catch (err) {
          setBusy(false);
          setPayErr("We couldn't confirm your payment. If you were charged, contact us with reference " + tx.reference + ".");
        }
      },
      onCancel: () => {
        setBusy(false);
        setPayErr("Payment cancelled — your card wasn't charged. You can try again when ready.");
      },
      onError: (error) => {
        setBusy(false);
        setPayErr((error && error.message) ? error.message : "Something went wrong starting the payment.");
      },
    });
  };

  const place = async (e) => {
    e.preventDefault();
    if (!date) { setDateErr(true); return; }
    setPayErr("");

    // Bank transfer: place the order now, customer pays on confirmation.
    if (pay !== "card") {
      finish({ paid: false });
      return;
    }

    // Card: pay securely via Paystack, then verify on the server.
    try {
      setBusy(true);
      const publicKey = await shFetchPublicKey();
      await payWithPaystack(publicKey);
    } catch (err) {
      setBusy(false);
      setPayErr("Online card payment isn't set up yet. Please choose Bank transfer, or contact us.");
    }
  };

  if (entries.length === 0) {
    return (
      <div className="sh-page sh-checkout">
        <div className="sh-empty-page">
          <Icon name="shopping-bag" size={34} stroke={1.4} />
          <h2 className="sh-section-title">Your box is empty</h2>
          <p>Add a few bakes and they'll show up here.</p>
          <button className="sh-btn primary" onClick={onBack}>Back to the menu</button>
        </div>
      </div>
    );
  }

  return (
    <div className="sh-page sh-checkout">
      <button className="sh-back" onClick={onBack}><Icon name="arrow-left" size={17} /> Keep browsing</button>
      <div className="sh-overline"><span className="sh-rule" />Almost yours</div>
      <h1 className="sh-page-title">Checkout</h1>

      <div className="sh-checkout-grid">
        <form className="sh-checkout-form" onSubmit={place}>
          <fieldset className="sh-fs">
            <legend>How would you like it?</legend>
            <div className="sh-method-row">
              <button type="button" className={"sh-method" + (method === "pickup" ? " is-active" : "")} onClick={() => setMethod("pickup")}>
                <Icon name="store" size={20} />
                <span className="sh-method-t">Pickup</span>
                <span className="sh-method-s">14 Marlowe Lane · free</span>
              </button>
              <button type="button" className={"sh-method" + (method === "delivery" ? " is-active" : "")} onClick={() => setMethod("delivery")}>
                <Icon name="bike" size={20} />
                <span className="sh-method-t">Local delivery</span>
                <span className="sh-method-s">Within 10km · ₦1,500</span>
              </button>
            </div>
          </fieldset>

          <fieldset className="sh-fs">
            <legend>Your details</legend>
            <div className="sh-field"><label className="sh-option-label">Name</label><input className="sh-input" required placeholder="Sam Baker" /></div>
            <div className="sh-field"><label className="sh-option-label">Email</label><input className="sh-input" type="email" required placeholder="[email protected]" value={email} onChange={(e) => setEmail(e.target.value)} /></div>
            <div className="sh-field"><label className="sh-option-label">Phone / WhatsApp</label><input className="sh-input" type="tel" required placeholder="0703 734 9484" /></div>
            {method === "delivery" && (
              <div className="sh-field"><label className="sh-option-label">Delivery address</label><input className="sh-input" required placeholder="221B Marlowe Lane" /></div>
            )}
            <div className="sh-field-2col">
              <div className="sh-field"><label className="sh-option-label">{method === "delivery" ? "Delivery date" : "Pickup date"}</label><DatePicker value={date} min={minDate} onChange={(v) => { setDate(v); setDateErr(false); }} placeholder="Choose a date" />{dateErr && <span style={{ color: "var(--error)", fontSize: 13, marginTop: 6, display: "block" }}>Please choose a {method === "delivery" ? "delivery" : "pickup"} date.</span>}</div>
              <div className="sh-field">
                <label className="sh-option-label">Time</label>
                <div className="sh-select-wrap">
                  <select className="sh-input" value={time} onChange={(e) => setTime(e.target.value)}>
                    <option>Morning · 8–11</option>
                    <option>Midday · 11–2</option>
                    <option>Afternoon · 2–6</option>
                  </select>
                  <Icon name="chevron-down" size={18} className="sh-select-caret" />
                </div>
              </div>
            </div>
          </fieldset>

          <fieldset className="sh-fs">
            <legend>Payment</legend>
            <div className="sh-method-row" style={{ marginBottom: 18 }}>
              <button type="button" className={"sh-method" + (pay === "card" ? " is-active" : "")} onClick={() => { setPay("card"); setPayErr(""); }}>
                <Icon name="credit-card" size={20} />
                <span className="sh-method-t">Pay online</span>
                <span className="sh-method-s">Card, transfer or USSD</span>
              </button>
              <button type="button" className={"sh-method" + (pay === "transfer" ? " is-active" : "")} onClick={() => { setPay("transfer"); setPayErr(""); }}>
                <Icon name="building-2" size={20} />
                <span className="sh-method-t">Bank transfer</span>
                <span className="sh-method-s">Pay on confirmation</span>
              </button>
            </div>
            {pay === "card" ? (
              <div className="sh-paystack">
                <p className="sh-secure"><Icon name="lock" size={14} /> You'll finish payment in a secure Paystack window — card, bank transfer, or USSD. We never see or store your card details.</p>
                {payErr && <p style={{ color: "var(--error)", fontSize: 13, marginTop: 10 }}>{payErr}</p>}
              </div>
            ) : (
              <div className="sh-transfer">
                <p className="sh-transfer-lead">Place your order, then send a transfer to:</p>
                <div className="sh-transfer-row"><span>Bank</span><span>Sweet Haven · GTBank</span></div>
                <div className="sh-transfer-row"><span>Account</span><span>0703 734 9484</span></div>
                <div className="sh-transfer-row"><span>Reference</span><span>Your phone number</span></div>
                <p className="sh-secure"><Icon name="info" size={14} /> We start baking once payment lands. We'll confirm by WhatsApp.</p>
              </div>
            )}
          </fieldset>

          <button className="sh-btn primary full lg" type="submit" disabled={busy}>
            {busy ? "Processing…" : (pay === "card" ? ("Pay " + money(total) + " securely") : ("Place your order · " + money(total)))}
          </button>
        </form>

        <aside className="sh-order-summary">
          <h3 className="sh-summary-title">Your order</h3>
          <div className="sh-order-lines">
            {entries.map((e) => (
              <div className="sh-order-line" key={e.key}>
                <span className="sh-order-qty">{e.qty}×</span>
                <span className="sh-order-name">{e.p.name}{e.opt && <em>{e.opt}</em>}</span>
                <span className="sh-order-price">{money(e.price * e.qty)}</span>
              </div>
            ))}
          </div>
          <div className="sh-order-totals">
            <div><span>Subtotal</span><span>{money(subtotal)}</span></div>
            <div><span>{method === "delivery" ? "Delivery" : "Pickup"}</span><span>{fee ? money(fee) : "Free"}</span></div>
            <div className="sh-order-grand"><span>Total</span><span className="sh-price">{money(total)}</span></div>
          </div>
          <p className="sh-foot-note">Baked fresh the morning of your order.</p>
        </aside>
      </div>
    </div>
  );
}

function Confirmation({ order, onHome, onMenu }) {
  const ref = order.paid ? order.ref : ("SH-" + (order.ref || "0000"));
  const when = order.date ? dpLabel(dpParse(order.date)) : null;
  return (
    <div className="sh-page sh-confirm">
      <div className="sh-confirm-card">
        <span className="sh-confirm-check"><Icon name="check" size={30} stroke={2.2} /></span>
        <div className="sh-overline" style={{ justifyContent: "center" }}><span className="sh-rule" />Order placed</div>
        <h1 className="sh-confirm-title">Thank you — it's in the oven.</h1>
        <p className="sh-confirm-sub">We've got your order. We'll call or WhatsApp you on the number you gave us the moment your box is ready{order.method === "delivery" ? " for delivery" : " to collect"}.{order.pay === "transfer" ? " Please send your transfer to complete the order." : ""}</p>

        <div className="sh-confirm-meta">
          <div><span className="sh-confirm-k">Order</span><span className="sh-confirm-v">{ref}</span></div>
          <div><span className="sh-confirm-k">{order.method === "delivery" ? "Delivery" : "Pickup"}</span><span className="sh-confirm-v">{order.method === "delivery" ? "To your door" : "14 Marlowe Lane"}</span></div>
          {when && <div><span className="sh-confirm-k">When</span><span className="sh-confirm-v">{when}</span>{order.time && <span className="sh-confirm-v" style={{ fontSize: 14, fontWeight: 400, color: "var(--ink-muted)" }}>{order.time}</span>}</div>}
          <div><span className="sh-confirm-k">Payment</span><span className="sh-confirm-v">{order.pay === "transfer" ? "Transfer" : (order.paid ? "Paid · Card" : "Card")}</span></div>
          <div><span className="sh-confirm-k">Total</span><span className="sh-confirm-v">{money(order.total)}</span></div>
        </div>

        <div className="sh-confirm-lines">
          {order.entries.map((e) => (
            <div className="sh-order-line" key={e.key}>
              <span className="sh-order-qty">{e.qty}×</span>
              <span className="sh-order-name">{e.p.name}{e.opt && <em>{e.opt}</em>}</span>
              <span className="sh-order-price">{money(e.price * e.qty)}</span>
            </div>
          ))}
        </div>

        <div className="sh-confirm-btns">
          <button className="sh-btn primary" onClick={onMenu}>Order something else</button>
          <button className="sh-btn secondary" onClick={onHome}>Back home</button>
        </div>
      </div>
    </div>
  );
}

Object.assign(window, { Checkout, Confirmation });
