// screens/cart.jsx — Cart & checkout

// ─── Order submission ───────────────────────────────────────────────────────
// Orders are emailed to the studio via Web3Forms (free, no backend). Paste your
// access key below — get it at https://web3forms.com (enter formasync3d@gmail.com,
// they email you a key). The customer's STL is attached when it's small enough.
const WEB3FORMS_KEY = "8ad75003-acbb-4b11-8424-6371efb47af6";
const ORDER_EMAIL = "formasync3d@gmail.com";

// Upload an STL to a free, no-account file host and return a public download
// URL. Tries file.io (CORS-enabled, ~2-week retention) then tmpfiles.org.
// Throws only if every host fails, so the caller can fall back to email.
async function uploadOrderFile(file) {
  const f = new File([file.arrayBuffer], file.name, { type: "application/octet-stream" });
  // 1) file.io
  try {
    const fd = new FormData();
    fd.append("file", f);
    const r = await fetch("https://file.io/?expires=2w", { method: "POST", body: fd });
    const j = await r.json();
    if (j && j.success && j.link) return j.link;
  } catch (e) { /* try next */ }
  // 2) tmpfiles.org
  const fd2 = new FormData();
  fd2.append("file", f);
  const r2 = await fetch("https://tmpfiles.org/api/v1/upload", { method: "POST", body: fd2 });
  const j2 = await r2.json();
  if (j2 && j2.data && j2.data.url) return j2.data.url.replace("tmpfiles.org/", "tmpfiles.org/dl/");
  throw new Error("upload failed");
}

const cartInput = {
  border: "1px solid var(--line)", appearance: "none", font: "inherit",
  width: "100%", boxSizing: "border-box", padding: "10px 12px",
  borderRadius: 8, background: "var(--card)", color: "var(--ink)",
  fontSize: 13.5, outline: "none",
};

// Summary row (was previously provided by upload.jsx; owned here now)
const CartRow = ({ k, v, sub, faded }) => (
  <div style={{ display: "flex", justifyContent: "space-between", alignItems: "baseline", gap: 12 }}>
    <div style={{ minWidth: 0 }}>
      <div className="mono" style={{ fontSize: 12, color: faded ? "var(--muted)" : "var(--ink-soft)" }}>{k}</div>
      {sub && <div className="mono" style={{ fontSize: 10, color: "var(--muted)", marginTop: 2 }}>{sub}</div>}
    </div>
    <span className="mono" style={{ fontSize: 13, color: faded ? "var(--muted)" : "var(--ink)", fontVariantNumeric: "tabular-nums" }}>{v}</span>
  </div>
);

function CartScreen({ items, removeItem, onContinue, onCheckout, onBrowse, onNav, brand }) {
  const [shipping, setShipping] = React.useState("tracked");
  const subtotal = items.reduce((a, b) => a + b.subtotal, 0);
  const shippingCost = items.length === 0 ? 0 : shipping === "tracked" ? 3.95 : shipping === "express" ? 7.95 : 0;
  const total = subtotal + shippingCost;
  const [placed, setPlaced] = React.useState(false);
  const [orderRef, setOrderRef] = React.useState("");
  const [cust, setCust] = React.useState({ name: "", email: "", phone: "", address: "", notes: "" });
  const [submitting, setSubmitting] = React.useState(false);
  const [error, setError] = React.useState("");
  const setC = (k, v) => setCust(c => ({ ...c, [k]: v }));

  async function submitOrder() {
    if (!cust.email || !cust.address) { setError("Email and delivery address are required."); return; }
    setError(""); setSubmitting(true);
    const ref = "SYNC-" + Math.floor(Math.random() * 8000 + 1000);
    const shipLabel = shipping === "tracked" ? "Royal Mail Tracked 48 (£3.95)" : shipping === "express" ? "Royal Mail Special (£7.95)" : "Collect in person (free)";
    try {
      const fd = new FormData();
      fd.append("access_key", WEB3FORMS_KEY);
      fd.append("subject", `New order ${ref} — £${total.toFixed(2)}`);
      fd.append("from_name", cust.name || "Sync customer");
      fd.append("email", cust.email);
      fd.append("Reference", ref);
      fd.append("Customer", `${cust.name || "—"} · ${cust.email} · ${cust.phone || "no phone"}`);
      fd.append("Delivery address", cust.address);
      fd.append("Shipping", shipLabel);
      fd.append("Notes", cust.notes || "—");
      const lines = items.map((it, i) =>
        `${i + 1}. ${it.file.name} — ${it.material?.code || "PLA"}, ${it.filament?.name || ""}, ${it.layer}mm layer, ${it.infill}% infill, qty ${it.quantity}, ${it.file.dims.join("×")}mm, ${(it.file.volCm3 || 0).toFixed(1)}cm³, ${(it.file.triangles || 0).toLocaleString()} tris — £${it.subtotal.toFixed(2)}`
      ).join("\n");
      fd.append("Order", `${lines}\n\nSubtotal £${subtotal.toFixed(2)}\nShipping £${shippingCost.toFixed(2)}\nTOTAL £${total.toFixed(2)} (no VAT)`);
      // Upload each STL to a free host and include the download links.
      const links = await Promise.all(items.map(async (it) => {
        if (!it.file?.arrayBuffer) return `${it.file.name}: (no file)`;
        try { return `${it.file.name}: ${await uploadOrderFile(it.file)}`; }
        catch (e) { return `${it.file.name}: (upload failed — reply to this email with the file)`; }
      }));
      fd.append("Download files", links.join("\n"));
      const res = await fetch("https://api.web3forms.com/submit", { method: "POST", body: fd });
      const j = await res.json().catch(() => ({}));
      if (res.ok && j.success) { setOrderRef(ref); setPlaced(true); }
      else setError(j.message || "Couldn't submit — please email us at " + ORDER_EMAIL);
    } catch (e) {
      setError("Network error. Please try again, or email " + ORDER_EMAIL);
    } finally {
      setSubmitting(false);
    }
  }

  if (placed) {
    return (
      <main style={{ padding: "var(--pad-y) var(--pad-x)", minHeight: "calc(100vh - 60px)" }}>
        <div className="mono upper" style={{ color: "var(--muted)", marginBottom: 24 }}>Order placed</div>
        <h1 className="serif" style={{
          fontSize: "clamp(56px, 8vw, 132px)", lineHeight: 0.92, margin: 0, letterSpacing: "-0.035em", maxWidth: 1000,
        }}>
          Thank you. We're on it.
        </h1>
        <p style={{ maxWidth: 520, fontSize: 17, color: "var(--ink-soft)", marginTop: 32 }}>
          Order <span className="mono" style={{ background: "color-mix(in srgb, var(--ink) 8%, transparent)", padding: "2px 8px", borderRadius: 4 }}>{orderRef || "SYNC-0000"}</span> has been received.
          We'll review your file and email you a secure <b>Stripe payment link</b> shortly. Nothing is charged until you pay.
        </p>
        <div className="r-cards" style={{ marginTop: 40, display: "grid", gridTemplateColumns: "repeat(3, 1fr)", maxWidth: 700, borderTop: "1px solid var(--line)" }}>
          {[
            ["Today",     "We review your file"],
            ["Next",      "Stripe payment link emailed"],
            ["+ 2 days",  "Printed & dispatched"],
          ].map(([k, v], i) => (
            <div key={i} style={{
              padding: "20px 0 20px 0", paddingRight: 18,
              borderRight: i < 2 ? "1px solid var(--line)" : "none",
              paddingLeft: i === 0 ? 0 : 18,
              borderBottom: "1px solid var(--line)",
            }}>
              <div className="mono upper" style={{ color: "var(--muted)" }}>{k}</div>
              <div className="serif" style={{ fontSize: 24, letterSpacing: "-0.015em", marginTop: 4 }}>{v}</div>
            </div>
          ))}
        </div>
        <button onClick={onContinue} className="mono" style={{
          all: "unset", cursor: "pointer", marginTop: 40,
          padding: "14px 22px", borderRadius: 999, border: "1px solid var(--ink)",
          fontSize: 13,
        }}>Back to homepage →</button>
        <Footer brand={brand} onNav={onNav} />
        <FloatingCTA onUpload={() => onNav && onNav("upload")} />
      </main>
    );
  }

  if (items.length === 0) {
    return (
      <main style={{ padding: "var(--pad-y) var(--pad-x)", minHeight: "calc(100vh - 60px)" }}>
        <div className="mono upper" style={{ color: "var(--muted)" }}>Cart</div>
        <h1 className="serif" style={{
          fontSize: "clamp(48px, 7vw, 96px)", lineHeight: 1, margin: "8px 0 32px", letterSpacing: "-0.03em",
        }}>Nothing in here yet.</h1>
        <p style={{ maxWidth: 480, color: "var(--ink-soft)", fontSize: 16 }}>
          The cart is patiently waiting. Upload a model and we'll print it.
        </p>
        <button onClick={onBrowse} style={{
          all: "unset", cursor: "pointer", marginTop: 24,
          padding: "16px 26px", borderRadius: 999,
          background: "var(--ink)", color: "var(--bg)", fontSize: 15,
        }}>Upload an STL →</button>
        <Footer brand={brand} onNav={onNav} />
        <FloatingCTA onUpload={() => onNav && onNav("upload")} />
      </main>
    );
  }

  return (
    <main style={{ padding: "var(--pad-y) var(--pad-x)" }}>
      <div style={{ display: "grid", gridTemplateColumns: "1fr 2.2fr", gap: 48, alignItems: "start", marginBottom: 36 }}>
        <div className="mono upper" style={{ color: "var(--muted)" }}>Cart · {items.length} {items.length === 1 ? "item" : "items"}</div>
        <h1 className="serif" style={{
          fontSize: "clamp(40px, 5.4vw, 80px)", lineHeight: 1, margin: 0, letterSpacing: "-0.03em",
        }}>Almost <span style={{ fontStyle: "italic" }}>on the bed.</span></h1>
      </div>

      <div style={{ display: "grid", gridTemplateColumns: "1.8fr 1fr", gap: 36, alignItems: "start" }}>
        <div>
          {items.map((it, i) => (
            <article key={i} style={{
              display: "grid", gridTemplateColumns: "140px 1fr auto", gap: 22, alignItems: "center",
              padding: "20px 0",
              borderTop: i === 0 ? "1px solid var(--line)" : "none",
              borderBottom: "1px solid var(--line)",
            }}>
              <div style={{ aspectRatio: "1", borderRadius: 6, overflow: "hidden", background: "color-mix(in srgb, var(--ink) 4%, transparent)", border: "1px solid var(--line)" }}>
                {it.file.arrayBuffer
                  ? <SyncSTL.Viewer arrayBuffer={it.file.arrayBuffer} color={it.filament.hex} interactive={false} />
                  : <Viewer variant={it.file.variant || "impeller"} color={it.filament.hex} interactive={false} />}
              </div>
              <div>
                <div className="serif" style={{ fontSize: 26, letterSpacing: "-0.02em", lineHeight: 1 }}>{it.file.name}</div>
                <div className="mono" style={{ marginTop: 6, color: "var(--ink-soft)", fontSize: 12 }}>
                  {it.filament.name} · {it.material?.code || "PLA"} · {it.layer}mm · {it.infill}% infill · qty {it.quantity}
                </div>
                <div className="mono" style={{ marginTop: 4, color: "var(--muted)", fontSize: 11 }}>
                  {it.file.dims.join(" × ")}mm
                </div>
              </div>
              <div style={{ display: "flex", flexDirection: "column", alignItems: "flex-end", gap: 6 }}>
                <div className="serif" style={{ fontSize: 30, letterSpacing: "-0.02em" }}>£{it.subtotal.toFixed(2)}</div>
                <button onClick={() => removeItem(i)} className="mono" style={{
                  all: "unset", cursor: "pointer", fontSize: 11, color: "var(--muted)",
                  textDecoration: "underline",
                }}>Remove</button>
              </div>
            </article>
          ))}

          <button onClick={onBrowse} className="mono" style={{
            all: "unset", cursor: "pointer", marginTop: 16,
            padding: "10px 16px", borderRadius: 999, border: "1px solid var(--line)",
            fontSize: 12, color: "var(--ink-soft)",
          }}>+ Add another part</button>
        </div>

        <aside className="card" style={{
          padding: "26px",
          display: "flex", flexDirection: "column", gap: 18,
          position: "sticky", top: 80,
        }}>
          <div className="mono upper" style={{ color: "var(--muted)" }}>Summary</div>

          <div>
            <div className="mono upper" style={{ color: "var(--ink-soft)", marginBottom: 10 }}>Shipping</div>
            {[
              { id: "tracked", l: "Royal Mail Tracked 48", sub: "2–3 working days", p: 3.95 },
              { id: "express", l: "Royal Mail Special",    sub: "Next working day",   p: 7.95 },
            ].map(o => {
              const active = shipping === o.id;
              return (
                <button key={o.id} onClick={() => setShipping(o.id)} style={{
                  all: "unset", cursor: "pointer", display: "flex", width: "100%",
                  padding: "12px 14px", marginBottom: 6,
                  border: active ? "1.5px solid var(--primary)" : "1px solid var(--line)",
                  background: active ? "var(--primary-soft)" : "transparent",
                  borderRadius: 6,
                  justifyContent: "space-between", alignItems: "center", gap: 12,
                }}>
                  <div>
                    <div style={{ fontSize: 14 }}>{o.l}</div>
                    <div className="mono" style={{ fontSize: 10.5, color: "var(--muted)", marginTop: 2 }}>{o.sub}</div>
                  </div>
                  <div className="mono" style={{ fontSize: 13, fontVariantNumeric: "tabular-nums" }}>
                    {o.p === 0 ? "Free" : `£${o.p.toFixed(2)}`}
                  </div>
                </button>
              );
            })}
          </div>

          <div style={{ display: "flex", flexDirection: "column", gap: 6, paddingTop: 8, borderTop: "1px solid var(--line)" }}>
            <CartRow k="Subtotal" v={`£${subtotal.toFixed(2)}`} />
            <CartRow k="Shipping" v={shippingCost === 0 ? "Free" : `£${shippingCost.toFixed(2)}`} />
          </div>

          <div style={{ display: "flex", justifyContent: "space-between", alignItems: "baseline", paddingTop: 12, borderTop: "1px solid var(--line)" }}>
            <div className="mono upper" style={{ color: "var(--muted)" }}>Total</div>
            <div className="serif" style={{ fontSize: 48, letterSpacing: "-0.025em", lineHeight: 1 }}>£{total.toFixed(2)}</div>
          </div>

          <div className="mono" style={{
            padding: "10px 12px", borderRadius: 8, fontSize: 12, fontWeight: 600,
            background: "color-mix(in srgb, var(--success) 10%, transparent)", color: "var(--success)",
          }}>
            Launch offer — write LAUNCH20 in your notes for 20% off your first order, applied to your payment link.
          </div>

          <div style={{ display: "flex", flexDirection: "column", gap: 8, paddingTop: 4 }}>
            <div className="mono upper" style={{ color: "var(--ink-soft)" }}>Your details</div>
            <input style={cartInput} placeholder="Full name" value={cust.name} onChange={(e) => setC("name", e.target.value)} />
            <input style={cartInput} type="email" placeholder="Email · required" value={cust.email} onChange={(e) => setC("email", e.target.value)} />
            <input style={cartInput} placeholder="Phone (optional)" value={cust.phone} onChange={(e) => setC("phone", e.target.value)} />
            <textarea style={{ ...cartInput, resize: "vertical", lineHeight: 1.5 }} rows={3} placeholder="Delivery address · required" value={cust.address} onChange={(e) => setC("address", e.target.value)} />
            <textarea style={{ ...cartInput, resize: "vertical", lineHeight: 1.5 }} rows={2} placeholder="Notes (optional) — finish, deadline, colour…" value={cust.notes} onChange={(e) => setC("notes", e.target.value)} />
          </div>

          <button onClick={submitOrder} disabled={submitting} className="btn-primary" data-track="checkout_place_order" style={{
            padding: "16px 22px",
            fontSize: 15, justifyContent: "space-between",
            opacity: submitting ? 0.6 : 1,
          }}>
            <span>{submitting ? "Uploading & sending…" : "Place order"}</span>
            <span>→</span>
          </button>
          {error && <div className="mono" style={{ fontSize: 11, color: "#c0392b", textAlign: "center" }}>{error}</div>}
          <div className="mono" style={{ fontSize: 10.5, color: "var(--muted)", textAlign: "center" }}>
            We review every order, then email you a Stripe payment link. No charge until you pay.
          </div>
        </aside>
      </div>
      <Footer brand={brand} onNav={onNav} />
      <FloatingCTA onUpload={() => onNav && onNav("upload")} />
    </main>
  );
}

window.CartScreen = CartScreen;
