/* =============================================================
   CoreIQ Office — Payments (Pay by link)
   Collect a payment from a customer by sending them a Stripe
   checkout link (SMS or email); watch it go from Awaiting → Paid
   in real time; refund from the history. Funds route to THIS
   store's Stripe Connect account — the API resolves the pharmacy
   from the signed-in tenant, the browser never names it.
   No-fake-data: every number comes from /payments/* (the Connect
   service). If payments aren't set up, we show the onboarding card.
   ============================================================= */
const { useState: payUseState, useEffect: payUseEffect, useRef: payUseRef } = React;

const payMoney = (n) =>
  n == null ? "—" : "$" + Number(n).toLocaleString("en-AU", { minimumFractionDigits: 2, maximumFractionDigits: 2 });

const PAY_STATUS_STYLE = {
  paid: { bg: "#e6f6ec", fg: "#137333", label: "Paid" },
  pending: { bg: "#fef7e0", fg: "#8a6d00", label: "Awaiting" },
  cancelled: { bg: "#f1f3f4", fg: "#5f6368", label: "Cancelled" },
  expired: { bg: "#f1f3f4", fg: "#5f6368", label: "Expired" },
  refunded: { bg: "#e8eaed", fg: "#3c4043", label: "Refunded" },
};

function PayStatusPill({ status }) {
  const s = PAY_STATUS_STYLE[status] || { bg: "#f1f3f4", fg: "#5f6368", label: status || "—" };
  return (
    <span style={{ background: s.bg, color: s.fg, padding: "2px 10px", borderRadius: 999, fontSize: 12, fontWeight: 600 }}>
      {s.label}
    </span>
  );
}

function PaymentsScreen() {
  const { pushToast } = window.useOffice();

  // Onboarding status: null = loading, {chargesEnabled,...} once known.
  const [connect, setConnect] = payUseState(null);
  const [connectErr, setConnectErr] = payUseState(null);

  // Collect-payment form.
  const [amount, setAmount] = payUseState("");
  const [description, setDescription] = payUseState("");
  const [name, setName] = payUseState("");
  const [method, setMethod] = payUseState("sms"); // 'sms' | 'email'
  const [contact, setContact] = payUseState("");
  const [sending, setSending] = payUseState(false);

  // The link we just created (so we can show its live status).
  const [active, setActive] = payUseState(null); // {sessionId, paymentUrl, status}

  // Transaction history.
  const [txns, setTxns] = payUseState(null); // null = loading
  const pollRef = payUseRef(null);

  const loadConnect = () => {
    setConnect(null);
    setConnectErr(null);
    window.OfficeAPI.paymentConnectStatus()
      .then(setConnect)
      .catch((e) => setConnectErr((e && e.message) || String(e)));
  };

  const loadTxns = () =>
    window.OfficeAPI.listPaymentTransactions({ limit: 25 })
      .then((r) => setTxns((r && r.transactions) || []))
      .catch(() => setTxns([]));

  payUseEffect(() => {
    loadConnect();
    loadTxns();
    return () => { if (pollRef.current) clearInterval(pollRef.current); };
  }, []);

  const isActive = connect && connect.stripeOnboardingStatus === "active" && connect.chargesEnabled;

  // Business details are filled server-side from the store's own records;
  // the click just fetches a fresh Stripe-hosted onboarding link. Stripe links
  // are single-use and short-lived, so open it immediately.
  const startOnboarding = () => {
    window.OfficeAPI.startPaymentOnboarding({})
      .then((r) => {
        if (r && r.onboardingUrl) {
          window.open(r.onboardingUrl, "_blank", "noopener");
          pushToast && pushToast("Complete onboarding in the new tab, then click Refresh.");
        }
      })
      .catch((e) => pushToast && pushToast("Onboarding failed: " + ((e && e.message) || e)));
  };

  const startPolling = (sessionId) => {
    if (pollRef.current) clearInterval(pollRef.current);
    pollRef.current = setInterval(() => {
      window.OfficeAPI.listPaymentTransactions({ limit: 25 })
        .then((r) => {
          const list = (r && r.transactions) || [];
          setTxns(list);
          const t = list.find((x) => x.sessionId === sessionId);
          if (t && t.status !== "pending") {
            setActive((prev) => (prev ? { ...prev, status: t.status } : prev));
            if (["paid", "cancelled", "expired", "refunded"].includes(t.status)) {
              clearInterval(pollRef.current);
              pollRef.current = null;
              if (t.status === "paid") pushToast && pushToast("Payment received — " + payMoney(t.amount));
            }
          }
        })
        .catch(() => {});
    }, 5000);
  };

  const send = () => {
    const amt = Number(amount);
    if (!amt || amt <= 0) return pushToast && pushToast("Enter a positive amount.");
    if (!name.trim()) return pushToast && pushToast("Enter the customer's name.");
    if (!contact.trim()) return pushToast && pushToast(method === "sms" ? "Enter a mobile number." : "Enter an email.");
    setSending(true);
    setActive(null);
    window.OfficeAPI.createPaymentLink({
      amount: amt,
      description: description.trim() || undefined,
      patientName: name.trim(),
      deliveryMethod: method,
      patientPhone: method === "sms" ? contact.trim() : undefined,
      patientEmail: method === "email" ? contact.trim() : undefined,
    })
      .then((r) => {
        setActive({ sessionId: r.sessionId, paymentUrl: r.paymentUrl, status: "pending", amount: amt, name: name.trim() });
        startPolling(r.sessionId);
        loadTxns();
        pushToast && pushToast(method === "sms" ? "Payment link sent by SMS." : "Payment link sent by email.");
      })
      .catch((e) => pushToast && pushToast("Couldn't send: " + ((e && e.message) || e)))
      .finally(() => setSending(false));
  };

  const clearForm = () => {
    setAmount(""); setDescription(""); setName(""); setContact(""); setActive(null);
    if (pollRef.current) { clearInterval(pollRef.current); pollRef.current = null; }
  };

  const refund = (t) => {
    if (!window.confirm("Refund " + payMoney(t.amount) + " to " + (t.patientName || "the customer") + "?")) return;
    window.OfficeAPI.refundPayment(t.sessionId, undefined, "requested_by_customer")
      .then(() => { pushToast && pushToast("Refund issued."); loadTxns(); })
      .catch((e) => pushToast && pushToast("Refund failed: " + ((e && e.message) || e)));
  };

  const input = { width: "100%", padding: "9px 11px", border: "1px solid #dadce0", borderRadius: 8, fontSize: 14, boxSizing: "border-box" };
  const label = { fontSize: 12, fontWeight: 600, color: "#5f6368", marginBottom: 4, display: "block" };

  return (
    <div className="off-screen">
      <div className="off-screen-header">
        <div>
          <h1 style={{ margin: 0 }}>Payments</h1>
          <div style={{ color: "#5f6368", fontSize: 13 }}>Collect a payment by sending the customer a secure link.</div>
        </div>
        <button onClick={() => { loadConnect(); loadTxns(); }} style={{ padding: "8px 14px", border: "1px solid #dadce0", borderRadius: 8, background: "#fff", cursor: "pointer" }}>
          Refresh
        </button>
      </div>

      <div className="off-screen-body" style={{ display: "flex", flexDirection: "column", gap: 16 }}>
        {connectErr && (
          <div style={{ background: "#fce8e6", color: "#c5221f", padding: 12, borderRadius: 8 }}>
            Couldn't load payment status: {connectErr}
          </div>
        )}

        {connect === null && !connectErr && <div style={{ color: "#5f6368" }}>Loading…</div>}

        {connect !== null && !isActive && (
          <div style={{ background: "#fff", border: "1px solid #e8eaed", borderRadius: 12, padding: 20 }}>
            <h3 style={{ marginTop: 0 }}>Set up payments</h3>
            <p style={{ color: "#5f6368" }}>
              This store isn't set up to collect card payments yet. Complete a one-time Stripe onboarding
              (bank account + ID) to start sending payment links.
              {connect.stripeOnboardingStatus === "pending" || connect.stripeOnboardingStatus === "incomplete"
                ? " Onboarding was started but isn't finished."
                : ""}
            </p>
            <button onClick={startOnboarding} style={{ padding: "10px 18px", background: "#1a73e8", color: "#fff", border: "none", borderRadius: 8, fontWeight: 600, cursor: "pointer" }}>
              {connect.stripeConnectedAccountId ? "Resume onboarding" : "Set up payments"}
            </button>
          </div>
        )}

        {isActive && (
          <div style={{ display: "grid", gridTemplateColumns: "minmax(320px, 420px) 1fr", gap: 16, alignItems: "start" }}>
            {/* Collect payment */}
            <div style={{ background: "#fff", border: "1px solid #e8eaed", borderRadius: 12, padding: 20 }}>
              <h3 style={{ marginTop: 0 }}>Collect payment</h3>
              <div style={{ marginBottom: 12 }}>
                <label style={label}>Amount (AUD)</label>
                <input style={input} inputMode="decimal" placeholder="0.00" value={amount} onChange={(e) => setAmount(e.target.value.replace(/[^0-9.]/g, ""))} />
              </div>
              <div style={{ marginBottom: 12 }}>
                <label style={label}>Description (optional)</label>
                <input style={input} placeholder="e.g. Consultation" value={description} onChange={(e) => setDescription(e.target.value)} />
              </div>
              <div style={{ marginBottom: 12 }}>
                <label style={label}>Customer name</label>
                <input style={input} value={name} onChange={(e) => setName(e.target.value)} />
              </div>
              <div style={{ marginBottom: 12 }}>
                <label style={label}>Send via</label>
                <div style={{ display: "flex", gap: 8 }}>
                  {["sms", "email"].map((m) => (
                    <button key={m} onClick={() => { setMethod(m); setContact(""); }}
                      style={{ flex: 1, padding: "8px 0", borderRadius: 8, border: "1px solid " + (method === m ? "#1a73e8" : "#dadce0"),
                        background: method === m ? "#e8f0fe" : "#fff", color: method === m ? "#1a73e8" : "#3c4043", fontWeight: 600, cursor: "pointer" }}>
                      {m === "sms" ? "SMS" : "Email"}
                    </button>
                  ))}
                </div>
              </div>
              <div style={{ marginBottom: 16 }}>
                <label style={label}>{method === "sms" ? "Mobile number" : "Email address"}</label>
                <input style={input} value={contact} onChange={(e) => setContact(e.target.value)}
                  placeholder={method === "sms" ? "04xx xxx xxx" : "name@example.com"} />
              </div>
              <button onClick={send} disabled={sending}
                style={{ width: "100%", padding: "11px 0", background: sending ? "#8ab4f8" : "#1a73e8", color: "#fff", border: "none", borderRadius: 8, fontWeight: 600, cursor: sending ? "default" : "pointer" }}>
                {sending ? "Sending…" : "Send payment link"}
              </button>

              {active && (
                <div style={{ marginTop: 16, padding: 14, borderRadius: 10, background: "#f8f9fa", border: "1px solid #e8eaed" }}>
                  <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 8 }}>
                    <strong>{payMoney(active.amount)} → {active.name}</strong>
                    <PayStatusPill status={active.status} />
                  </div>
                  <div style={{ fontSize: 12, color: "#5f6368", marginBottom: 8, wordBreak: "break-all" }}>{active.paymentUrl}</div>
                  <div style={{ display: "flex", gap: 8 }}>
                    <button onClick={() => { navigator.clipboard && navigator.clipboard.writeText(active.paymentUrl); pushToast && pushToast("Link copied."); }}
                      style={{ padding: "6px 12px", border: "1px solid #dadce0", borderRadius: 8, background: "#fff", cursor: "pointer", fontSize: 13 }}>Copy link</button>
                    {active.status === "pending" && (
                      <button onClick={() => { window.OfficeAPI.cancelPayment(active.sessionId).then(() => { setActive({ ...active, status: "cancelled" }); loadTxns(); }); }}
                        style={{ padding: "6px 12px", border: "1px solid #dadce0", borderRadius: 8, background: "#fff", cursor: "pointer", fontSize: 13 }}>Cancel</button>
                    )}
                    <button onClick={clearForm} style={{ padding: "6px 12px", border: "1px solid #dadce0", borderRadius: 8, background: "#fff", cursor: "pointer", fontSize: 13, marginLeft: "auto" }}>New</button>
                  </div>
                </div>
              )}
            </div>

            {/* History */}
            <div style={{ background: "#fff", border: "1px solid #e8eaed", borderRadius: 12, padding: 20, minWidth: 0 }}>
              <h3 style={{ marginTop: 0 }}>Recent payments</h3>
              {txns === null && <div style={{ color: "#5f6368" }}>Loading…</div>}
              {txns && txns.length === 0 && <div style={{ color: "#5f6368" }}>No payments yet.</div>}
              {txns && txns.length > 0 && (
                <table style={{ width: "100%", borderCollapse: "collapse", fontSize: 13 }}>
                  <thead>
                    <tr style={{ textAlign: "left", color: "#5f6368" }}>
                      <th style={{ padding: "6px 8px" }}>When</th>
                      <th style={{ padding: "6px 8px" }}>Customer</th>
                      <th style={{ padding: "6px 8px", textAlign: "right" }}>Amount</th>
                      <th style={{ padding: "6px 8px" }}>Status</th>
                      <th style={{ padding: "6px 8px" }}></th>
                    </tr>
                  </thead>
                  <tbody>
                    {txns.map((t) => (
                      <tr key={t.sessionId} style={{ borderTop: "1px solid #f1f3f4" }}>
                        <td style={{ padding: "8px", color: "#5f6368", whiteSpace: "nowrap" }}>
                          {t.createdAt ? new Date(t.createdAt).toLocaleString("en-AU", { day: "2-digit", month: "short", hour: "2-digit", minute: "2-digit" }) : "—"}
                        </td>
                        <td style={{ padding: "8px" }}>{t.patientName || "—"}</td>
                        <td style={{ padding: "8px", textAlign: "right", fontWeight: 600 }}>{payMoney(t.amount)}</td>
                        <td style={{ padding: "8px" }}><PayStatusPill status={t.status} /></td>
                        <td style={{ padding: "8px", textAlign: "right" }}>
                          {t.status === "paid" && (
                            <button onClick={() => refund(t)} style={{ padding: "4px 10px", border: "1px solid #dadce0", borderRadius: 6, background: "#fff", cursor: "pointer", fontSize: 12 }}>Refund</button>
                          )}
                        </td>
                      </tr>
                    ))}
                  </tbody>
                </table>
              )}
            </div>
          </div>
        )}
      </div>
    </div>
  );
}

window.OFFICE_SCREENS = Object.assign(window.OFFICE_SCREENS || {}, {
  payments: PaymentsScreen,
});
