// Public · Guest order tracking
// ---------------------------------------------------------------------------
// Reached at #/guest?token=RAW — the destination of the secure links Joy mints
// on the Tracking links screen. No account needed: the token resolves to one
// order plus that customer's receipts/invoices, and stays live for 30 days
// after the order is finished. All read-only; everything is fetched fresh from
// /api/guest so nothing sensitive is baked into the page.
// ---------------------------------------------------------------------------

// Mirror the five customer-facing stages used elsewhere in the app.
const GUEST_STAGES = [
  { key: "placed", label: "Placed" },
  { key: "digitizing", label: "Digitizing" },
  { key: "stitching", label: "In production" },
  { key: "qc", label: "QC & finishing" },
  { key: "finished", label: "Finished" },
];
const GUEST_STATUS_ALIAS = { new: "placed", progress: "stitching", done: "finished" };

function guestStageIndex(status) {
  const norm = GUEST_STATUS_ALIAS[status] || status;
  const i = GUEST_STAGES.findIndex(s => s.key === norm);
  return i < 0 ? 0 : i;
}

function money(n, ccy) {
  const c = (ccy || "USD").toUpperCase();
  try { return new Intl.NumberFormat(undefined, { style: "currency", currency: c }).format(Number(n) || 0); }
  catch { return `$${(Number(n) || 0).toFixed(2)}`; }
}

function GuestTrackPage() {
  const token = (() => {
    // token lives in the hash query: #/guest?token=...
    const h = location.hash || "";
    const m = h.match(/[?&]token=([^&]+)/);
    return m ? decodeURIComponent(m[1]) : "";
  })();

  const [state, setState] = useState("loading"); // loading | ok | expired | bad
  const [data, setData] = useState(null);
  const [message, setMessage] = useState("");
  const [invoice, setInvoice] = useState(null);   // opened receipt
  const [invBusy, setInvBusy] = useState(false);

  useEffect(() => {
    if (!token) { setState("bad"); return; }
    (async () => {
      try {
        const r = await api.guestResolve(token);
        setData(r); setState("ok");
      } catch (e) {
        if (e.message === "expired" || /expired/i.test(e.message)) { setState("expired"); setMessage(e.message); }
        else setState("bad");
      }
    })();
  }, [token]);

  const openInvoice = async (id) => {
    setInvBusy(true);
    try { setInvoice(await api.guestInvoice(token, id)); }
    catch (e) { setInvoice(null); }
    finally { setInvBusy(false); }
  };

  return (
    <main className="page section">
      <div style={{ maxWidth: 760, margin: "0 auto" }}>
        <div style={{ textAlign: "center", marginBottom: 22 }}>
          <div className="script" style={{ fontSize: 40, color: "var(--rose-deep)", lineHeight: 1 }}>Your order</div>
          <div className="smallcaps" style={{ color: "var(--ink-2)" }}>Hazelbelle Embroidery &amp; Print</div>
        </div>

        {state === "loading" && <div className="stitched" style={{ padding: 28, textAlign: "center", color: "var(--ink-3)" }}>Looking up your order…</div>}

        {state === "bad" && (
          <div className="stitched stitched-ink" style={{ padding: 28, textAlign: "center" }}>
            <h3 style={{ marginTop: 0 }}>This link isn't valid</h3>
            <p style={{ color: "var(--ink-2)" }}>The tracking link looks incomplete or has been revoked. Email <a href="mailto:hazelbelleemb@gmail.com">hazelbelleemb@gmail.com</a> and Joy will send a fresh one.</p>
          </div>
        )}

        {state === "expired" && (
          <div className="stitched stitched-ink" style={{ padding: 28, textAlign: "center" }}>
            <h3 style={{ marginTop: 0 }}>This link has expired</h3>
            <p style={{ color: "var(--ink-2)" }}>Tracking links stay open for 30 days after an order is finished. Yours has passed that window — message Joy at <a href="mailto:hazelbelleemb@gmail.com">hazelbelleemb@gmail.com</a> for a new one or a copy of your receipt.</p>
          </div>
        )}

        {state === "ok" && data && (
          <>
            <GuestOrderCard order={data.order} expiresAt={data.expiresAt} daysLeft={data.daysLeft} deliveredAt={data.deliveredAt} />
            <GuestReceipts invoices={data.invoices} onOpen={openInvoice} busyId={invBusy} />
            {invoice && <GuestInvoiceModal invoice={invoice} onClose={() => setInvoice(null)} />}
          </>
        )}
      </div>
    </main>
  );
}

function GuestOrderCard({ order, expiresAt, daysLeft, deliveredAt }) {
  const idx = guestStageIndex(order.status);
  return (
    <div className="stitched" style={{ padding: 24, marginBottom: 18 }}>
      <div style={{ display: "flex", justifyContent: "space-between", alignItems: "baseline", flexWrap: "wrap", gap: 8 }}>
        <h2 style={{ margin: 0 }}>Order {order.ref}</h2>
        <span className="mono" style={{ color: "var(--ink-3)", fontSize: 13 }}>{order.itemType || order.service}</span>
      </div>
      {order.name && <div style={{ color: "var(--ink-2)", marginTop: 2 }}>For {order.name}{order.qty ? ` · ${order.qty} piece${order.qty === 1 ? "" : "s"}` : ""}</div>}

      {/* Stage stepper */}
      <div style={{ display: "flex", marginTop: 22, marginBottom: 6 }}>
        {GUEST_STAGES.map((s, i) => (
          <div key={s.key} style={{ flex: 1, textAlign: "center", position: "relative" }}>
            <div style={{
              width: 18, height: 18, borderRadius: 999, margin: "0 auto",
              background: i <= idx ? "var(--sage)" : "var(--line)",
              border: i === idx ? "3px solid var(--sage-deep)" : "none", boxSizing: "content-box",
            }} />
            {i < GUEST_STAGES.length - 1 && (
              <div style={{ position: "absolute", top: 9, left: "50%", width: "100%", height: 3, background: i < idx ? "var(--sage)" : "var(--line)", zIndex: -1 }} />
            )}
            <div style={{ fontSize: 11, marginTop: 6, color: i <= idx ? "var(--ink)" : "var(--ink-3)", fontWeight: i === idx ? 600 : 400 }}>{s.label}</div>
          </div>
        ))}
      </div>

      <div style={{ textAlign: "center", marginTop: 14, color: "var(--sage-deep)", fontWeight: 600 }}>{order.stageLabel}</div>

      <div style={{ borderTop: "1px dashed var(--line)", marginTop: 18, paddingTop: 12, display: "flex", justifyContent: "space-between", flexWrap: "wrap", gap: 8, fontSize: 13, color: "var(--ink-3)" }}>
        {order.deadline && <span>Target: {order.deadline}</span>}
        {deliveredAt
          ? <span>Finished — receipts available for {daysLeft} more day{daysLeft === 1 ? "" : "s"}</span>
          : <span>Link stays open while your order is in progress</span>}
      </div>
    </div>
  );
}

function GuestReceipts({ invoices, onOpen }) {
  if (!invoices || !invoices.length) {
    return <div className="stitched" style={{ padding: 20, color: "var(--ink-3)", fontSize: 14 }}>No receipts or invoices on file yet. They'll appear here once Joy issues them.</div>;
  }
  return (
    <div className="stitched" style={{ padding: 20 }}>
      <h3 style={{ marginTop: 0 }}>Receipts &amp; invoices</h3>
      {invoices.map(inv => (
        <div key={inv.id} style={{ display: "flex", justifyContent: "space-between", alignItems: "center", padding: "10px 0", borderTop: "1px solid var(--line)", flexWrap: "wrap", gap: 8 }}>
          <div>
            <div style={{ fontWeight: 600 }}>{inv.number}</div>
            <div style={{ fontSize: 13, color: "var(--ink-3)" }}>{new Date(inv.issuedAt).toLocaleDateString()} · {inv.status}</div>
          </div>
          <div style={{ display: "flex", alignItems: "center", gap: 12 }}>
            <span style={{ fontWeight: 600 }}>{money(inv.total, inv.currency)}</span>
            <button className="btn btn-ghost btn-small" onClick={() => onOpen(inv.id)}>View</button>
          </div>
        </div>
      ))}
    </div>
  );
}

function GuestInvoiceModal({ invoice, onClose }) {
  const print = () => window.print();
  return (
    <div onClick={onClose} style={{ position: "fixed", inset: 0, background: "rgba(58,42,38,0.45)", display: "flex", alignItems: "flex-start", justifyContent: "center", padding: 20, overflow: "auto", zIndex: 1000 }}>
      <div onClick={e => e.stopPropagation()} className="stitched" style={{ background: "var(--card)", maxWidth: 620, width: "100%", padding: 28, marginTop: 30 }}>
        <div style={{ display: "flex", justifyContent: "space-between", alignItems: "baseline", marginBottom: 12 }}>
          <h2 style={{ margin: 0 }}>{invoice.number}</h2>
          <button className="btn btn-ghost btn-small" onClick={onClose}>Close</button>
        </div>
        <div style={{ fontSize: 13, color: "var(--ink-3)", marginBottom: 16 }}>
          {invoice.customerName} · {invoice.customerEmail}<br />
          Issued {new Date(invoice.issuedAt).toLocaleDateString()}{invoice.paidAt ? ` · Paid ${new Date(invoice.paidAt).toLocaleDateString()}` : ""} · {invoice.status}
        </div>
        {invoice.shipTo && (
          <div style={{ fontSize: 13, color: "var(--ink-2)", marginBottom: 16, whiteSpace: "pre-line" }}>
            <span className="smallcaps" style={{ color: "var(--ink-3)" }}>Ship to</span><br />{invoice.shipTo}
          </div>
        )}
        <table style={{ width: "100%", borderCollapse: "collapse", fontSize: 14 }}>
          <thead><tr style={{ textAlign: "left", color: "var(--ink-3)" }}>
            <th style={{ padding: "6px 4px" }}>Item</th><th style={{ padding: "6px 4px", textAlign: "right" }}>Qty</th><th style={{ padding: "6px 4px", textAlign: "right" }}>Price</th><th style={{ padding: "6px 4px", textAlign: "right" }}>Amount</th>
          </tr></thead>
          <tbody>
            {invoice.items.map((it, i) => (
              <tr key={i} style={{ borderTop: "1px solid var(--line)" }}>
                <td style={{ padding: "6px 4px" }}>{it.description}</td>
                <td style={{ padding: "6px 4px", textAlign: "right" }}>{it.qty}</td>
                <td style={{ padding: "6px 4px", textAlign: "right" }}>{money(it.unitPrice, invoice.currency)}</td>
                <td style={{ padding: "6px 4px", textAlign: "right" }}>{money(it.amount, invoice.currency)}</td>
              </tr>
            ))}
          </tbody>
        </table>
        <div style={{ marginTop: 14, marginLeft: "auto", maxWidth: 240 }}>
          <Row k="Subtotal" v={money(invoice.subtotal, invoice.currency)} />
          {invoice.tax > 0 && <Row k="Tax" v={money(invoice.tax, invoice.currency)} />}
          <Row k="Total" v={money(invoice.total, invoice.currency)} strong />
          {invoice.amountPaid > 0 && <Row k="Paid" v={money(invoice.amountPaid, invoice.currency)} />}
        </div>
        {invoice.notes && <div style={{ marginTop: 14, fontSize: 13, color: "var(--ink-2)" }}>{invoice.notes}</div>}
        <div style={{ marginTop: 18, textAlign: "right" }}><button className="btn btn-small" onClick={print}>Print / save PDF</button></div>
      </div>
    </div>
  );
}
function Row({ k, v, strong }) {
  return (
    <div style={{ display: "flex", justifyContent: "space-between", padding: "3px 0", borderTop: strong ? "1px solid var(--line)" : "none", fontWeight: strong ? 700 : 400 }}>
      <span style={{ color: "var(--ink-3)" }}>{k}</span><span>{v}</span>
    </div>
  );
}

Object.assign(window, { GuestTrackPage });
