// Reseller portal — Orders. Strictly READ-ONLY (Orders are raised and
// progressed by Solo staff — see routes/admin-orders.ts; the reseller
// equivalent, routes/portal-orders.ts, has no status-mutation route at
// all). Force-scoped server-side to the signed-in reseller's own
// company — no company filter is ever shown here (there's only ever
// one company to see).
//
// Modeled on admin-orders-page.jsx's OrderRow/OrderDetail, minus the
// Xero sync badge (Solo-internal signal) and the build-status change
// buttons (staff-only action) — a reseller sees the current status as
// plain text and the full read-only order detail underneath.

const RESELLER_ORDER_STATUS_LABELS = { ordered: "Ordered", in_build: "In Build", ready_to_ship: "Ready to Ship", shipped: "Shipped", cancelled: "Cancelled" };
const RESELLER_ORDER_STATUS_COLORS = {
  ordered: "var(--pt-fg-dim)",
  in_build: "var(--pt-status-po-requested)",
  ready_to_ship: "var(--pt-link)",
  shipped: "var(--pt-status-accepted)",
  cancelled: "var(--pt-status-rejected)",
};

function ResellerOrdersPage({ onNavigate }) {
  const [state, setState] = useState({ status: "loading", user: null, company: null, isSoloStaff: false });
  const [companies, setCompanies] = useState([]);
  const [orders, setOrders] = useState({ status: "loading", items: [] });
  const [statusFilter, setStatusFilter] = useState("");
  const [openId, setOpenId] = useState(null);

  const loadOrders = (status) => {
    setOrders((o) => ({ ...o, status: "loading" }));
    const params = new URLSearchParams();
    if (status) params.set("status", status);
    fetch(`/api/portal/orders?${params.toString()}`, { credentials: "same-origin" })
      .then((r) => (r.ok ? r.json() : { orders: [] }))
      .then((data) => setOrders({ status: "ready", items: data.orders || [] }))
      .catch(() => setOrders({ status: "ready", items: [] }));
  };

  const loadMe = (onDone) => {
    fetch("/api/portal/me", { credentials: "same-origin" })
      .then(async (r) => {
        if (!r.ok) throw new Error("not signed in");
        return r.json();
      })
      .then((data) => {
        setState({ status: "ready", user: data.user, company: data.company, isSoloStaff: !!data.isSoloStaff });
        if (data.isSoloStaff) {
          fetch("/api/portal/companies", { credentials: "same-origin" })
            .then((r) => (r.ok ? r.json() : { companies: [] }))
            .then((d) => setCompanies(d.companies || []))
            .catch(() => setCompanies([]));
        }
        if (onDone) onDone();
      })
      .catch(() => onNavigate("reseller-login"));
  };

  const handleSwitchCompany = (companyId) => {
    fetch("/api/portal/switch-company", {
      method: "POST", credentials: "same-origin",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ companyId }),
    })
      .then((r) => (r.ok ? r.json() : Promise.reject()))
      .then(() => loadMe(() => loadOrders(statusFilter)))
      .catch(() => { /* switch failed silently */ });
  };

  useEffect(() => { loadMe(); }, []); // eslint-disable-line react-hooks/exhaustive-deps -- mount-only
  useEffect(() => { loadOrders(statusFilter); }, [statusFilter]); // eslint-disable-line react-hooks/exhaustive-deps

  if (state.status === "loading") {
    return <section style={{ background: "var(--pt-bg)", minHeight: "calc(100vh - 88px)" }} />;
  }

  const { user, company, isSoloStaff } = state;

  return (
    <ResellerShell
      page="portal-orders" onNavigate={onNavigate}
      userName={user.name} companyName={company.name}
      isSoloStaff={isSoloStaff} companies={companies}
      currentCompanyId={company.id} onSwitchCompany={handleSwitchCompany}
      subtitle="Reseller portal"
      title="Orders."
    >
      <p style={{
        fontFamily: "var(--font-body)", fontSize: 14,
        color: "var(--pt-fg-dim)", margin: "-16px 0 28px",
      }}>
        Every order raised against your company, tracked from placement through to shipping.
      </p>

      <div style={{ marginBottom: 24, maxWidth: 220 }}>
        <FieldBlock label="Status">
          <select
            value={statusFilter} onChange={(e) => setStatusFilter(e.target.value)}
            data-testid="portal-orders-status-filter"
            style={{
              width: "100%", boxSizing: "border-box", background: "var(--pt-surface-2)",
              border: "1px solid var(--pt-border-strong)", color: "var(--pt-fg)",
              fontFamily: "var(--font-body)", fontSize: 14, padding: "12px 14px", outline: "none",
            }}
          >
            <option value="">All statuses</option>
            {Object.keys(RESELLER_ORDER_STATUS_LABELS).map((s) => (
              <option key={s} value={s}>{RESELLER_ORDER_STATUS_LABELS[s]}</option>
            ))}
          </select>
        </FieldBlock>
      </div>

      <div style={{
        fontFamily: "var(--font-body)", fontSize: 10, letterSpacing: "0.28em",
        textTransform: "uppercase", color: "var(--pt-fg-dimmer)", fontWeight: 500,
        marginBottom: 16,
      }}>
        Orders {orders.status === "ready" && `(${orders.items.length})`}
      </div>

      {orders.status === "loading" ? (
        <div style={{ fontFamily: "var(--font-body)", fontSize: 13.5, color: "var(--pt-fg-faint2)" }}>Loading\u2026</div>
      ) : orders.items.length === 0 ? (
        <div style={{
          background: "var(--pt-surface)", border: "1px solid var(--pt-border)",
          padding: "22px 24px", fontFamily: "var(--font-body)", fontSize: 13.5, color: "var(--pt-fg-dimmer)",
        }}>
          No orders yet — once one of your quotes is accepted, it'll appear here.
        </div>
      ) : (
        <div style={{ display: "flex", flexDirection: "column", gap: 12 }}>
          {orders.items.map((o) => (
            <ResellerOrderRow
              key={o.id} order={o}
              open={openId === o.id}
              onToggle={() => setOpenId(openId === o.id ? null : o.id)}
            />
          ))}
        </div>
      )}
    </ResellerShell>
  );
}

function ResellerOrderRow({ order, open, onToggle }) {
  return (
    <div data-testid={`portal-order-row-${order.id}`} style={{
      background: "var(--pt-surface)", border: "1px solid var(--pt-border-2)",
    }}>
      <button
        type="button" onClick={onToggle} data-testid={`portal-order-toggle-${order.id}`}
        style={{
          width: "100%", background: "none", border: "none", cursor: "pointer",
          padding: "16px 20px", display: "flex", justifyContent: "space-between",
          alignItems: "center", flexWrap: "wrap", gap: 12, textAlign: "left",
        }}>
        <div>
          <div style={{ fontFamily: "var(--font-display)", fontWeight: 700, fontSize: 15, textTransform: "uppercase", color: "var(--pt-fg)" }}>
            Order #{order.id}
          </div>
          <div style={{ fontFamily: "var(--font-body)", fontSize: 12, color: "var(--pt-fg-dim)", marginTop: 4 }}>
            <span style={{ color: RESELLER_ORDER_STATUS_COLORS[order.status] || "var(--pt-fg-dim)", textTransform: "uppercase", letterSpacing: "0.08em", fontSize: 11 }}>
              {RESELLER_ORDER_STATUS_LABELS[order.status] || order.status}
            </span>
            {" \u00b7 "}{order.item_count} item{order.item_count === 1 ? "" : "s"} \u00b7 {portalMoney(order.total, order.currency)}
            {order.purchase_order_number && <> \u00b7 PO {order.purchase_order_number}</>}
          </div>
        </div>
        <span style={{ fontFamily: "var(--font-body)", fontSize: 11, letterSpacing: "0.14em", textTransform: "uppercase", color: "var(--pt-fg-dimmer)" }}>
          {open ? "Close \u2191" : "View \u2192"}
        </span>
      </button>
      {open && <ResellerOrderDetail orderId={order.id} />}
    </div>
  );
}

function ResellerOrderDetail({ orderId }) {
  const [data, setData] = useState(null);
  const [error, setError] = useState("");

  useEffect(() => {
    fetch(`/api/portal/orders/${orderId}`, { credentials: "same-origin" })
      .then((r) => (r.ok ? r.json() : Promise.reject()))
      .then((d) => setData(d))
      .catch(() => setError("Couldn't load this order."));
  }, [orderId]);

  if (!data) {
    return (
      <div style={{ borderTop: "1px solid var(--pt-border-2)", padding: "20px", fontFamily: "var(--font-body)", fontSize: 13, color: "var(--pt-fg-dimmer)" }}>
        {error || "Loading\u2026"}
      </div>
    );
  }

  const { order, items, history, total } = data;
  const subtotal = items.reduce((sum, it) => sum + it.unit_price * it.quantity * (1 - (it.discount_percent || 0) / 100), 0);

  return (
    <div style={{ borderTop: "1px solid var(--pt-border-2)", padding: "20px" }}>
      <div style={{ fontFamily: "var(--font-body)", fontSize: 10, letterSpacing: "0.24em", textTransform: "uppercase", color: "var(--pt-fg-dim)", fontWeight: 500, marginBottom: 12 }}>
        Line items ({items.length})
      </div>
      <div style={{ display: "flex", flexDirection: "column", gap: 8, marginBottom: 18 }}>
        {items.map((it) => (
          <div key={it.id} style={{
            display: "flex", justifyContent: "space-between", alignItems: "center", gap: 10, flexWrap: "wrap",
            padding: "8px 12px", background: "var(--pt-surface-2)", border: "1px solid var(--pt-border)",
          }}>
            <div style={{ fontFamily: "var(--font-body)", fontSize: 13, color: "var(--pt-fg-3)" }}>
              {it.product_name} \u00d7 {it.quantity} @ {portalMoney(it.unit_price, order.currency)}
              {it.discount_percent ? ` (-${it.discount_percent}%)` : ""}
            </div>
            <div style={{ fontFamily: "var(--font-body)", fontSize: 13, color: "var(--pt-fg-3)", fontWeight: 600 }}>
              {portalMoney(it.unit_price * it.quantity * (1 - (it.discount_percent || 0) / 100), order.currency)}
            </div>
          </div>
        ))}
      </div>

      {(order.discount_percent > 0 || order.notes || order.purchase_order_number) && (
        <div style={{ display: "grid", gap: 14, gridTemplateColumns: "repeat(auto-fit, minmax(180px, 1fr))", marginBottom: 18 }}>
          {order.discount_percent > 0 && <MiniDetail label="Order discount" value={`${order.discount_percent}%`} />}
          {order.purchase_order_number && <MiniDetail label="PO reference" value={order.purchase_order_number} />}
          {order.notes && <MiniDetail label="Notes" value={order.notes} />}
        </div>
      )}

      <div style={{ fontFamily: "var(--font-body)", fontSize: 13.5, color: "var(--pt-fg-2)", marginBottom: 22 }}>
        Subtotal {portalMoney(subtotal, order.currency)} \u2192 Total <strong>{portalMoney(total, order.currency)}</strong>
      </div>

      <div style={{ height: 1, background: "var(--pt-border)", margin: "18px 0" }} />
      <div style={{ fontFamily: "var(--font-body)", fontSize: 10, letterSpacing: "0.24em", textTransform: "uppercase", color: "var(--pt-fg-dim)", fontWeight: 500, marginBottom: 12 }}>
        Status history
      </div>
      <div style={{ display: "flex", flexDirection: "column", gap: 6 }}>
        {history.map((h, i) => (
          <div key={i} style={{ fontFamily: "var(--font-body)", fontSize: 12, color: "var(--pt-fg-dimmer)" }}>
            {String(h.changed_at).slice(0, 10)} \u2014 <span style={{ color: "var(--pt-fg-2)" }}>{RESELLER_ORDER_STATUS_LABELS[h.status] || h.status}</span>
            {h.notes && <> \u2014 {h.notes}</>}
          </div>
        ))}
      </div>
    </div>
  );
}

function MiniDetail({ label, value }) {
  return (
    <div>
      <div style={{ fontFamily: "var(--font-body)", fontSize: 10, letterSpacing: "0.16em", textTransform: "uppercase", color: "var(--pt-fg-faint)", marginBottom: 4 }}>{label}</div>
      <div style={{ fontFamily: "var(--font-body)", fontSize: 13.5, color: "var(--pt-fg-2)" }}>{value}</div>
    </div>
  );
}

Object.assign(window, { ResellerOrdersPage });
