// Checkout — contact, address (Biteship autocomplete), courier rates, Midtrans Snap pay.

// Lazy-load Midtrans Snap.js once, using keys configured in index.html.
function loadSnap() {
  return new Promise((resolve, reject) => {
    if (window.snap) return resolve(window.snap);
    const isProd = window.MIDTRANS_IS_PRODUCTION === true || window.MIDTRANS_IS_PRODUCTION === "true";
    const src = isProd
      ? "https://app.midtrans.com/snap/snap.js"
      : "https://app.sandbox.midtrans.com/snap/snap.js";
    const s = document.createElement("script");
    s.src = src;
    s.setAttribute("data-client-key", window.MIDTRANS_CLIENT_KEY || "");
    s.onload = () => resolve(window.snap);
    s.onerror = () => reject(new Error("Failed to load payment script"));
    document.head.appendChild(s);
  });
}

const Field = ({ label, ...props }) => (
  <label style={{ display: "block", marginBottom: 18 }}>
    <span className="mono" style={{ fontSize: 10, letterSpacing: ".14em", textTransform: "uppercase", color: "var(--ink-mute)", display: "block", marginBottom: 8 }}>{label}</span>
    <input
      {...props}
      style={{
        width: "100%", padding: "12px 14px", background: "transparent",
        border: "1px solid var(--hair-strong)", borderRadius: 0,
        fontFamily: "var(--sans)", fontSize: 15, color: "var(--ink)",
      }}
    />
  </label>
);

const Checkout = ({ navigate }) => {
  const { items, subtotal, clear } = useCart();
  const { user, email: authEmail, configured: authConfigured } = useAuth();
  const { addresses, save: saveAddress } = useAddresses(user);

  const [contact, setContact] = React.useState({ name: "", phone: "", email: "" });
  const [address, setAddress] = React.useState("");
  const [note, setNote] = React.useState("");
  const [selectedAddrId, setSelectedAddrId] = React.useState(null); // saved address chosen, or null = new/guest
  const [saveToAccount, setSaveToAccount] = React.useState(false);

  // Prefill email from the logged-in account.
  React.useEffect(() => { if (authEmail && !contact.email) setContact((c) => ({ ...c, email: authEmail })); }, [authEmail]);

  // address area autocomplete
  const [areaQuery, setAreaQuery] = React.useState("");
  const [areaResults, setAreaResults] = React.useState([]);
  const [area, setArea] = React.useState(null); // {id, name, postal_code}
  const [searching, setSearching] = React.useState(false);

  // courier rates
  const [rates, setRates] = React.useState([]);
  const [courier, setCourier] = React.useState(null);
  const [ratesLoading, setRatesLoading] = React.useState(false);

  const [submitting, setSubmitting] = React.useState(false);
  const [error, setError] = React.useState("");

  // Redirect away from an empty cart.
  React.useEffect(() => {
    if (items.length === 0 && !submitting) navigate("/products");
  }, [items.length]);

  // Debounced area search.
  React.useEffect(() => {
    if (area && areaQuery === area.name) return; // already chosen
    if (areaQuery.length < 3) { setAreaResults([]); return; }
    const t = setTimeout(async () => {
      setSearching(true);
      try {
        const r = await fetch(`/api/shipping?action=areas&q=${encodeURIComponent(areaQuery)}`);
        const j = await r.json();
        setAreaResults(j.areas || []);
      } catch { setAreaResults([]); }
      finally { setSearching(false); }
    }, 350);
    return () => clearTimeout(t);
  }, [areaQuery]);

  const fetchRates = async (areaObj) => {
    setCourier(null);
    setRatesLoading(true);
    setRates([]);
    try {
      const r = await fetch("/api/shipping", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          action: "rates",
          area_id: areaObj.id,
          postal_code: areaObj.postal_code,
          items: items.map((it) => ({ id: it.id, qty: it.qty })),
        }),
      });
      const j = await r.json();
      if (j.error) throw new Error(j.error);
      setRates(j.rates || []);
    } catch (e) {
      setError("Couldn't load shipping options: " + e.message);
    } finally {
      setRatesLoading(false);
    }
  };

  const pickArea = async (a) => {
    setArea(a);
    setAreaQuery(a.name);
    setAreaResults([]);
    fetchRates(a);
  };

  // Apply a saved address → fill contact + destination + load rates.
  const useSavedAddress = (a) => {
    setSelectedAddrId(a.id);
    setContact((c) => ({ ...c, name: a.recipient_name, phone: a.phone }));
    setAddress(a.address);
    setNote("");
    const areaObj = { id: a.area_id, name: a.area_label, postal_code: a.postal_code };
    setArea(areaObj);
    setAreaQuery(a.area_label || "");
    fetchRates(areaObj);
  };

  const useNewAddress = () => {
    setSelectedAddrId(null);
    setContact((c) => ({ ...c, name: "", phone: "" }));
    setAddress(""); setArea(null); setAreaQuery(""); setRates([]); setCourier(null);
  };

  const shippingCost = courier ? courier.price : 0;
  const total = subtotal + shippingCost;

  const canPay = contact.name && contact.phone && address && area && courier && !submitting;

  const pay = async () => {
    setError("");
    setSubmitting(true);
    try {
      const token = await sbAccessToken();
      const headers = { "Content-Type": "application/json" };
      if (token) headers.Authorization = "Bearer " + token;
      const r = await fetch("/api/checkout", {
        method: "POST",
        headers,
        body: JSON.stringify({
          customer: contact,
          destination: {
            address,
            area_id: area.id,
            area_label: area.name,
            postal_code: area.postal_code,
            note,
          },
          courier: {
            code: courier.courier_code,
            service: courier.courier_service_code,
            name: `${courier.courier_name} · ${courier.courier_service_name}`,
            price: courier.price,
            etd: courier.duration || courier.shipment_duration_range,
          },
          items: items.map((it) => ({ id: it.id, qty: it.qty })),
        }),
      });
      const j = await r.json();
      if (!r.ok || j.error) throw new Error(j.error || "Checkout failed");

      // Optionally save this address to the account for next time.
      if (user && saveToAccount && !selectedAddrId) {
        try {
          await saveAddress({
            label: "", recipient_name: contact.name, phone: contact.phone,
            address, area_id: area.id, area_label: area.name, postal_code: area.postal_code,
            is_default: addresses.length === 0,
          });
        } catch { /* non-blocking */ }
      }

      const snap = await loadSnap();
      snap.pay(j.token, {
        onSuccess: () => { clear(); navigate("/order/" + j.order_id); },
        onPending: () => { clear(); navigate("/order/" + j.order_id); },
        onError: () => { setError("Payment failed. Please try again."); setSubmitting(false); },
        onClose: () => { setSubmitting(false); },
      });
    } catch (e) {
      setError(e.message);
      setSubmitting(false);
    }
  };

  if (items.length === 0) return null;

  return (
    <main>
      <section style={{ padding: "60px var(--pad-x) 120px", maxWidth: 1080, margin: "0 auto" }}>
        <button className="lnk" style={{ borderBottom: 0, opacity: 0.6 }} onClick={() => navigate("/products")}>← Continue shopping</button>
        <h1 className="d-l" style={{ fontStyle: "italic", margin: "24px 0 48px" }}>Checkout</h1>

        <div className="grid12" style={{ rowGap: 48 }}>
          {/* Left: form */}
          <div className="col-span-7" style={{ paddingRight: 24 }}>
            {/* Guest banner / sign-in nudge */}
            {authConfigured && !user && (
              <div style={{ border: "1px solid var(--hair)", padding: "16px 18px", marginBottom: 32, display: "flex", justifyContent: "space-between", alignItems: "center", gap: 16, flexWrap: "wrap" }}>
                <span className="mono" style={{ fontSize: 11, letterSpacing: ".06em", lineHeight: 1.6 }}>Have an account? Sign in to autofill your address — or just continue as guest below.</span>
                <button className="lnk" style={{ flex: "0 0 auto" }} onClick={() => navigate("/account")}>Sign in →</button>
              </div>
            )}

            {/* Saved address picker (logged in) */}
            {user && addresses.length > 0 && (
              <div style={{ marginBottom: 40 }}>
                <SectionTag index="01" total="03" label="Your addresses" />
                <div style={{ display: "flex", flexDirection: "column" }}>
                  {addresses.map((a) => {
                    const active = selectedAddrId === a.id;
                    return (
                      <button key={a.id} onClick={() => useSavedAddress(a)} style={{ textAlign: "left", display: "flex", gap: 14, alignItems: "flex-start", padding: "16px 0", borderTop: "1px solid var(--hair)" }}>
                        <span style={{ width: 14, height: 14, borderRadius: "50%", border: "1px solid var(--ink)", background: active ? "var(--ink)" : "transparent", flex: "0 0 14px", marginTop: 4 }} />
                        <span>
                          <span style={{ fontFamily: "var(--serif)", fontStyle: "italic", fontSize: 20 }}>{a.label || a.recipient_name} {a.is_default && <span className="mono" style={{ fontSize: 9, letterSpacing: ".14em", textTransform: "uppercase", opacity: 0.5 }}>· default</span>}</span>
                          <span className="mono" style={{ display: "block", fontSize: 11, color: "var(--ink-mute)", marginTop: 4, lineHeight: 1.5 }}>{a.recipient_name} · {a.phone} · {a.area_label}</span>
                        </span>
                      </button>
                    );
                  })}
                  <button onClick={useNewAddress} style={{ textAlign: "left", display: "flex", gap: 14, alignItems: "center", padding: "16px 0", borderTop: "1px solid var(--hair)", borderBottom: "1px solid var(--hair)" }}>
                    <span style={{ width: 14, height: 14, borderRadius: "50%", border: "1px solid var(--ink)", background: selectedAddrId === null ? "var(--ink)" : "transparent", flex: "0 0 14px" }} />
                    <span className="mono" style={{ fontSize: 12, letterSpacing: ".06em" }}>Use a new address</span>
                  </button>
                </div>
              </div>
            )}

            <SectionTag index="01" total="03" label="Contact" />
            <Field label="Full name" value={contact.name} onChange={(e) => setContact({ ...contact, name: e.target.value })} placeholder="Jane Doe" />
            <Field label="WhatsApp / phone" value={contact.phone} onChange={(e) => setContact({ ...contact, phone: e.target.value })} placeholder="08xxxxxxxxxx" />
            <Field label="Email (for receipt)" type="email" value={contact.email} onChange={(e) => setContact({ ...contact, email: e.target.value })} placeholder="you@email.com" />

            <div style={{ marginTop: 40 }}><SectionTag index="02" total="03" label="Shipping address" /></div>

            {/* Area autocomplete */}
            <label style={{ display: "block", marginBottom: 18, position: "relative" }}>
              <span className="mono" style={{ fontSize: 10, letterSpacing: ".14em", textTransform: "uppercase", color: "var(--ink-mute)", display: "block", marginBottom: 4 }}>City / district / postal code</span>
              <span className="mono" style={{ fontSize: 10, color: "var(--ink-mute)", display: "block", marginBottom: 8, opacity: 0.7 }}>Type to search — min. 3 characters</span>
              <input
                value={areaQuery}
                onChange={(e) => { setAreaQuery(e.target.value); setArea(null); }}
                placeholder="e.g. Kebayoran Baru, Jakarta Selatan"
                style={{ width: "100%", padding: "12px 14px", background: "transparent", border: "1px solid var(--hair-strong)", borderRadius: 0, fontFamily: "var(--sans)", fontSize: 15, color: "var(--ink)" }}
              />
              {searching && <span className="mono" style={{ fontSize: 10, position: "absolute", right: 12, top: 36, opacity: 0.5 }}>…</span>}
              {areaResults.length > 0 && (
                <div style={{ position: "absolute", left: 0, right: 0, top: "100%", zIndex: 5, background: "var(--cream)", border: "1px solid var(--hair-strong)", borderTop: 0, maxHeight: 260, overflowY: "auto" }}>
                  {areaResults.map((a) => (
                    <button key={a.id} onClick={() => pickArea(a)} style={{ display: "block", width: "100%", textAlign: "left", padding: "12px 14px", borderBottom: "1px solid var(--hair)", fontSize: 13, lineHeight: 1.4 }}>
                      {a.name}
                    </button>
                  ))}
                </div>
              )}
            </label>

            <Field label="Full street address" value={address} onChange={(e) => setAddress(e.target.value)} placeholder="Street, building, house no., RT/RW" />
            <Field label="Note for courier (optional)" value={note} onChange={(e) => setNote(e.target.value)} placeholder="Landmark, delivery instructions" />

            {user && !selectedAddrId && (
              <label style={{ display: "flex", alignItems: "center", gap: 10, marginBottom: 8, cursor: "pointer" }}>
                <input type="checkbox" checked={saveToAccount} onChange={(e) => setSaveToAccount(e.target.checked)} />
                <span className="mono" style={{ fontSize: 11, letterSpacing: ".08em", textTransform: "uppercase" }}>Save this address to my account</span>
              </label>
            )}

            {/* Courier rates */}
            <div style={{ marginTop: 40 }}><SectionTag index="03" total="03" label="Shipping method" /></div>
            {!area && <p className="mono" style={{ fontSize: 11, letterSpacing: ".1em", textTransform: "uppercase", color: "var(--ink-mute)" }}>Choose your area above to see couriers.</p>}
            {ratesLoading && <p className="mono" style={{ fontSize: 11, letterSpacing: ".1em", textTransform: "uppercase", color: "var(--ink-mute)" }}>Loading couriers…</p>}
            {!ratesLoading && area && rates.length === 0 && <p className="mono" style={{ fontSize: 11, letterSpacing: ".1em", textTransform: "uppercase", color: "var(--ink-mute)" }}>No couriers available for this destination.</p>}
            <div style={{ display: "flex", flexDirection: "column", gap: 0 }}>
              {rates.map((rt, i) => {
                const active = courier === rt;
                return (
                  <button key={i} onClick={() => setCourier(rt)} style={{
                    display: "flex", justifyContent: "space-between", alignItems: "center", gap: 16,
                    textAlign: "left", padding: "16px 0", borderTop: "1px solid var(--hair)",
                    borderBottom: i === rates.length - 1 ? "1px solid var(--hair)" : "none",
                  }}>
                    <span style={{ display: "flex", alignItems: "center", gap: 14 }}>
                      <span style={{ width: 14, height: 14, borderRadius: "50%", border: "1px solid var(--ink)", background: active ? "var(--ink)" : "transparent", flex: "0 0 14px" }} />
                      <span>
                        <span style={{ fontFamily: "var(--serif)", fontStyle: "italic", fontSize: 20 }}>{rt.courier_name} · {rt.courier_service_name}</span>
                        <span className="mono" style={{ display: "block", fontSize: 10, letterSpacing: ".12em", textTransform: "uppercase", color: "var(--ink-mute)", marginTop: 4 }}>{rt.duration || rt.shipment_duration_range || "—"}</span>
                      </span>
                    </span>
                    <span className="mono" style={{ fontSize: 13 }}>{formatIDR(rt.price)}</span>
                  </button>
                );
              })}
            </div>
          </div>

          {/* Right: summary */}
          <div className="col-span-5">
            <div style={{ border: "1px solid var(--hair-strong)", padding: "28px var(--pad-x)", position: "sticky", top: 90 }}>
              <span className="mono" style={{ fontSize: 11, letterSpacing: ".18em", textTransform: "uppercase" }}>Order summary</span>
              <div style={{ margin: "24px 0", display: "flex", flexDirection: "column", gap: 16 }}>
                {items.map((it) => (
                  <div key={it.id} style={{ display: "flex", justifyContent: "space-between", gap: 12, alignItems: "baseline" }}>
                    <span style={{ fontFamily: "var(--serif)", fontStyle: "italic", fontSize: 18 }}>{it.name} <span className="mono" style={{ fontSize: 11, fontStyle: "normal", color: "var(--ink-mute)" }}>×{it.qty}</span></span>
                    <span className="mono" style={{ fontSize: 12 }}>{formatIDR(it.price * it.qty)}</span>
                  </div>
                ))}
              </div>
              <div style={{ borderTop: "1px solid var(--hair)", paddingTop: 16, display: "flex", flexDirection: "column", gap: 10 }}>
                <Row label="Subtotal" value={formatIDR(subtotal)} />
                <Row label="Shipping" value={courier ? formatIDR(shippingCost) : "—"} />
              </div>
              <div style={{ borderTop: "1px solid var(--hair-strong)", marginTop: 16, paddingTop: 16, display: "flex", justifyContent: "space-between", alignItems: "baseline" }}>
                <span className="mono" style={{ fontSize: 11, letterSpacing: ".14em", textTransform: "uppercase" }}>Total</span>
                <span style={{ fontFamily: "var(--serif)", fontStyle: "italic", fontSize: 32 }}>{formatIDR(total)}</span>
              </div>

              {error && <p className="mono" style={{ fontSize: 11, letterSpacing: ".06em", color: "#a23", marginTop: 18, lineHeight: 1.5 }}>{error}</p>}

              <button className="btn solid" style={{ width: "100%", justifyContent: "center", marginTop: 24, opacity: canPay ? 1 : 0.4, pointerEvents: canPay ? "auto" : "none" }} onClick={pay}>
                {submitting ? "Processing…" : "Pay now"} <span className="arr">→</span>
              </button>
              <p className="mono" style={{ fontSize: 10, letterSpacing: ".1em", textTransform: "uppercase", color: "var(--ink-mute)", marginTop: 16, lineHeight: 1.6, textAlign: "center" }}>
                Secured by Midtrans · QRIS, VA, e-wallet, card
              </p>
            </div>
          </div>
        </div>
      </section>
    </main>
  );
};

const Row = ({ label, value }) => (
  <div style={{ display: "flex", justifyContent: "space-between", alignItems: "baseline" }}>
    <span className="mono" style={{ fontSize: 11, letterSpacing: ".12em", textTransform: "uppercase", color: "var(--ink-mute)" }}>{label}</span>
    <span className="mono" style={{ fontSize: 12 }}>{value}</span>
  </div>
);

window.Checkout = Checkout;
