/* page-orders.jsx — Orders module (reconciled per 03-ui §2 / PO 2026-06-03).
   All roles share one role-parameterised component. Full-page OrderDetail + refund engine
   removed; detail is now a 700px DetailDrawer opened on row click. */
(function(){
const { useState, useMemo } = React;

// ── Data-field bridge ────────────────────────────────────────────────────────
// SB4_ORDERS was authored for the pre-reconciliation model. Field names differ
// from the spec (id→order_code, placed_at→created_at, channel→order_source,
// order_type "now"/"later" is FULFILMENT timing, not Pickup/Dine-in).
// Normalisers live here; mock-data.js is NOT modified (shared with other pages).
//
// NOTE: order_type (Pickup/Dine-in) has no mock data column — see registryDeltas.
// NOTE: device_os, tip_amount, voucher_code are absent from SB4_ORDERS mock data
//       — those fields degrade to "—" where needed (spec marks voucher nullable ✓).
//
// order_source: "consumer_app" → "app", "kiosk" stays "kiosk".
const _toSource = (channel) => channel === "consumer_app" ? "app" : (channel || "kiosk");

// Payment status normaliser: SB4_ORDERS uses "captured"/"authorized"/etc.
// kind='order' StatusPill supports paid/pending/failed/refunded.
const _toPaymentTone = (s) =>
  ({ captured: "paid", authorized: "pending", failed: "failed", refunded: "refunded", pending: "pending" }[s] || "pending");

// Fulfilment timing: order_type "now"/"later" maps to the DERIVED fulfilment field.
const _fulfilment = (order) =>
  order.scheduled_for
    ? "Scheduled @ " + _fmtDateTime(order.scheduled_for, order.country_id)
    : "Now";

// ── GeoScope data (shared across roles, filtered per role) ───────────────────
const _geoData = () => ({
  countries: SB2_COUNTRIES.map(c => ({ value: c.country_id, label: c.country_name })),
  areas:     SB3_AREAS.map(a => ({ value: a.id, label: a.name, country_id: a.country_id })),
  outlets:   SB3_OUTLETS.map(o => ({ value: o.id, label: o.name, area_id: o.area_id })),
});

// ── OrdersList ───────────────────────────────────────────────────────────────
/**
 * @spec GA-043 — Order detail
 * Refunds are read-only here: derived status display + deep-link to the Refunds module per Review 9.
 * No refund action lives on Order detail — the Refunds module owns all refund operations.
 */
function OrdersList({ role = "GA", scope }) {
  if (!["GA","CM","AM","OM"].includes(role)) return _notAuthorised;

  // ── Scope baseline rows ──────────────────────────────────────────────────
  const scopeOutlets = useMemo(() => {
    if (role === "CM") return new Set(SB3_OUTLETS.filter(o => o.country_id === "PH").map(o => o.id));
    if (role === "AM") return new Set(SB3_OUTLETS.filter(o => o.area_id === AM_AREA_ID).map(o => o.id));
    if (role === "OM") return new Set([OM_OUTLET_ID]);
    return null; // GA: all
  }, [role]);

  const baseRows = useMemo(() =>
    SB4_ORDERS.filter(o => !scopeOutlets || scopeOutlets.has(o.store_id)),
  [scopeOutlets]);

  // ── Filter state ─────────────────────────────────────────────────────────
  // primaryFilter array: Status + order_source (cap 2)
  const [primaryValue, setPrimaryValue] = useState({ status: "", order_source: "" });
  // advancedFilters: order_type (Pickup/Dine-in), GeoScope (GA/CM/AM only), date
  const [advancedValues, setAdvancedValues] = useState({ order_type: "", geo: null, dtf: null });
  const [search, setSearch] = useState("");
  const [page, setPage] = useState(1);
  const [pageSize, setPageSize] = useState(20);

  // ── Incoming deep-link + context chip (03-ui §2 / 2C-checklist) ──────────
  const incomingFilter = typeof window !== "undefined" && window.__sixhands_route_payload
    ? window.__sixhands_route_payload.filter : null;
  const incomingId = typeof window !== "undefined" && window.__sixhands_route_payload
    ? window.__sixhands_route_payload.id : null;
  const [ctxChip, setCtxChip] = useState(
    incomingFilter && incomingFilter.outlet_id ? { kind: "Outlet", label: incomingFilter.label }
    : incomingFilter && incomingFilter.customer_id ? { kind: "Customer", label: incomingFilter.label }
    : null);
  const [ctxFilter, setCtxFilter] = useState(
    incomingFilter && incomingFilter.outlet_id ? { outlet_id: incomingFilter.outlet_id }
    : incomingFilter && incomingFilter.customer_id ? { customer_id: incomingFilter.customer_id }
    : {});
  const clearCtx = () => { setCtxChip(null); setCtxFilter({}); };

  // ── Drawer state (also auto-opens on incoming id) ─────────────────────────
  const [drawerOrder, setDrawerOrder] = useState(
    incomingId ? (SB4_ORDER_BY_ID[incomingId] || null) : null
  );
  const openDrawer = (order) => setDrawerOrder(order);
  const closeDrawer = () => setDrawerOrder(null);

  // ── Derived / filtered rows ───────────────────────────────────────────────
  const filteredRows = useMemo(() => {
    const q = search.trim().toLowerCase();
    return baseRows
      .filter(o => !primaryValue.status || _orderDisplayStatus(o) === primaryValue.status)
      .filter(o => !primaryValue.order_source || _toSource(o.order_source) === primaryValue.order_source)
      .filter(o => !advancedValues.order_type || (o.order_type || "") === advancedValues.order_type)
      .filter(o => {
        const g = advancedValues.geo;
        if (!g) return true;
        if (g.countries && g.countries.length && !g.countries.includes(o.country_id)) return false;
        if (g.areas && g.areas.length) {
          const outlet = SB3_OUTLET_BY_ID[o.store_id];
          if (!outlet || !g.areas.includes(outlet.area_id)) return false;
        }
        if (g.outlets && g.outlets.length && !g.outlets.includes(o.store_id)) return false;
        return true;
      })
      .filter(o => !advancedValues.dtf || _dtfMatch(advancedValues.dtf, o.placed_at, o.country_id))
      .filter(o => !ctxFilter.outlet_id || o.store_id === ctxFilter.outlet_id)
      .filter(o => !ctxFilter.customer_id || (o.customer && o.customer.id === ctxFilter.customer_id))
      .filter(o => !q || o.id.toLowerCase().includes(q)
        || (o.customer && o.customer.name && o.customer.name.toLowerCase().includes(q)));
  }, [baseRows, primaryValue, advancedValues, search, ctxFilter]);

  const totalPages = Math.max(1, Math.ceil(filteredRows.length / pageSize));
  const visibleRows = filteredRows.slice((page - 1) * pageSize, page * pageSize);

  // ── FilterBar config ─────────────────────────────────────────────────────
  const statusOptions = [
    { value: "", label: "All statuses" },
    { value: "received",  label: "Received" },
    { value: "preparing", label: "Preparing" },
    { value: "ready",     label: "Ready" },
    { value: "completed", label: "Completed" },
    { value: "cancelled", label: "Cancelled" },
    { value: "refunded",  label: "Refunded" },
  ];
  const sourceOptions = [
    { value: "", label: "All sources" },
    { value: "app",   label: "App" },
    { value: "kiosk", label: "Kiosk" },
  ];
  const orderTypeOptions = [
    { value: "", label: "All types" },
    { value: "pickup",  label: "Pickup" },
    { value: "dine_in", label: "Dine-in" },
  ];
  const primaryFilterArr = [
    { key: "status",       label: "Status",  options: statusOptions },
    { key: "order_source", label: "Source",  options: sourceOptions },
  ];
  const geoData = _geoData();
  const advancedFilters = [
    { key: "order_type", kind: "select", label: "Order type", options: orderTypeOptions },
    ...(role !== "OM" ? [{
      key: "geo", kind: "geoscope", label: "Network scope", role,
      countries: geoData.countries,
      areas: geoData.areas,
      outlets: geoData.outlets,
    }] : []),
    { key: "dtf", kind: "datetime", label: "Date & time", country: role !== "OM" ? (scope && scope.countryId) || "SG" : "PH" },
  ];

  const handleReset = () => {
    setPrimaryValue({ status: "", order_source: "" });
    setAdvancedValues({ order_type: "", geo: null, dtf: null });
    setSearch("");
    setPage(1);
  };

  // ── Columns (role-branched) ───────────────────────────────────────────────
  const showOutletCustomer = role !== "OM";
  const columns = [
    { label: "Order",      sortable: true, sortKey: "order_code",
      render: r => <span style={{ ...T.primary() }}>{r.order_code || r.id}</span> },
    ...(showOutletCustomer ? [
      { label: "Outlet",   sortable: true, sortKey: "store_id",
        render: r => { const o = SB3_OUTLET_BY_ID[r.store_id] || {}; return <span style={{ ...T_MUTED }}>{o.location || o.name || r.store_id}</span>; } },
      { label: "Customer", sortable: true, sortKey: "customer_name",
        render: r => <span style={{ ...T_MUTED }}>{r.customer ? r.customer.name : "—"}</span> },
    ] : []),
    { label: "Source",     width: 86,  sortable: true, sortKey: "order_source",
      render: r => <StatusPill status={_toSource(r.order_source)} kind="source"/> },
    { label: "Type",       width: 84,  sortable: true, sortKey: "order_type",
      render: r => <span style={{ ...T_MUTED }}>{r.order_type ? (r.order_type === "pickup" ? "Pickup" : "Dine-in") : "—"}</span> },
    { label: "Total",      width: 96,  sortable: true, sortKey: "total",
      render: r => <span style={{ ...T.amount }}>{r.currency} {(r.totals.total || 0).toLocaleString()}</span> },
    { label: "Placed",     width: 150, sortable: true, sortKey: "placed_at",
      render: r => <span style={{ ...T_MUTED }}>{_fmtDateTime(r.placed_at, r.country_id)}</span> },
    { label: "Status",     width: 116, sortable: true, sortKey: "status",
      render: r => <StatusPill status={_orderDisplayStatus(r)} kind="orderLifecycle"/> },
  ];

  const pageTitle = role === "GA" ? "Orders" : role === "CM" ? "Orders — Country" : role === "AM" ? "Orders — Area" : "Orders — Outlet";

  return (
    <div className="page-inner">
      <PageHead title={pageTitle} description="POS-sourced order records. Read-only."
        actions={<ExportButton role={role} onClick={() => {}}/>}/>

      <FilterBar
        primaryFilter={primaryFilterArr}
        primaryValue={primaryValue}
        onPrimaryChange={v => { setPrimaryValue(v); setPage(1); }}
        advancedFilters={advancedFilters}
        advancedValues={advancedValues}
        onAdvancedChange={(k, v) => { setAdvancedValues(prev => ({ ...prev, [k]: v })); setPage(1); }}
        onAdvancedReset={() => { setAdvancedValues({ order_type: "", geo: null, dtf: null }); setPage(1); }}
        onReset={handleReset}
        search={search}
        onSearch={v => { setSearch(v); setPage(1); }}
        searchPlaceholder="Search orders…"/>

      {ctxChip && (
        <div style={{ marginBottom: 12 }}>
          <span className="chip on">
            {ctxChip.kind}: {ctxChip.label}
            <button onClick={clearCtx} aria-label={`Clear ${ctxChip.kind.toLowerCase()} filter`}
              style={{ display: "inline-flex", alignItems: "center", background: "none", border: "none", padding: 0, marginLeft: 2, cursor: "pointer", color: "inherit" }}>
              <LIcon name="X" size={14}/>
            </button>
          </span>
        </div>
      )}

      <Table
        columns={columns}
        rows={visibleRows}
        onRow={openDrawer}
        emptyText="No orders match this filter."/>
      <TableFooter
        page={page}
        totalPages={totalPages}
        onPage={setPage}
        count={pageSize}
        onCountChange={c => { setPageSize(c); setPage(1); }}/>

      {drawerOrder && (
        <OrderDetailDrawer
          order={drawerOrder}
          role={role}
          onClose={closeDrawer}/>
      )}
    </div>
  );
}

// ── OrderDetailDrawer ────────────────────────────────────────────────────────
// 700px right-panel DetailDrawer. Read-only per spec. Remarks writable by all roles,
// edit-own-only (currentUser mock = "you").
function OrderDetailDrawer({ order, role, onClose }) {
  const [remarks, addRemark, editRemark, deleteRemark] = _useRemarks("order", order.id, [
    { id: "rem_seed_1", content: "Customer called to confirm pick-up window.", created_by_name: "Anna Cruz (OM)", created_by: "rem_seed_user", created_at: "2026-04-23 12:14" },
  ]);

  const outlet  = SB3_OUTLET_BY_ID[order.store_id] || {};
  const country = SB2_COUNTRY_BY_ID[order.country_id] || {};
  const franchisee = SB3_FRANCHISEE_BY_ID[order.franchise_id || outlet.franchise_id] || {};
  const orderSource = _toSource(order.order_source);
  const displayStatus = _orderDisplayStatus(order);
  const paymentTone = _toPaymentTone(order.payment ? order.payment.status : "pending");
  const fulfilmentLabel = _fulfilment(order);
  // location: opt-in derived from lat/lng presence in mock data
  const hasGeo = order.geolocation_lat != null && order.geolocation_lng != null;

  // Loyalty — derived back-reference: redemptions whose order_id points at THIS order.
  // No stored redemption_id on the order (SSOT: the FK lives on the redemption; computed, not stored).
  const orderRedemptions = ((typeof SB4_REDEMPTIONS !== "undefined" ? SB4_REDEMPTIONS : (window.SB4_REDEMPTIONS || [])) || [])
    .filter(x => x.order_id === order.id);
  const _rewardNm = (id) => {
    const arr = (typeof SB4_REWARDS !== "undefined" ? SB4_REWARDS : (window.SB4_REWARDS || [])) || [];
    const rw = arr.find(x => x.id === id);
    return rw ? rw.name : (id || "—");
  };

  const fmt = (n) => n != null ? `${order.currency || "₱"} ${Number(n).toLocaleString()}` : "—";

  // edit-own-only: current operator. The seed remark (Anna Cruz) is another author → not editable.
  const CURRENT_USER = "you";

  return (
    <DetailDrawer
      open={!!order}
      onClose={onClose}
      title={`Order ${order.order_code || order.id}`}
      subtitle={_fmtDateTime(order.placed_at, order.country_id)}>

      {/* General */}
      <FormSection title="General">
        <KeyValueGrid columns={2} items={[
          { label: "Order code",    value: order.order_code || order.id, mono: true },
          { label: "Order source",  value: <StatusPill status={orderSource} kind="source"/> },
          { label: "Order type",    value: order.order_type ? (order.order_type === "pickup" ? "Pickup" : "Dine-in") : "—" },
          { label: "Status",        value: <StatusPill status={displayStatus} kind="orderLifecycle"/> },
          { label: "Placed",        value: _fmtDateTime(order.placed_at, order.country_id) },
        ]}/>
      </FormSection>

      {/* Scope */}
      <FormSection title="Scope">
        <KeyValueGrid columns={2} items={[
          { label: "Outlet",      value: outlet.name || order.store_id },
          { label: "Country",     value: country.country_name ? `${country.flag || ""} ${country.country_name}`.trim() : (order.country_id || "—") },
          { label: "Franchisee",  value: franchisee.display_name || (order.franchise_id || "—") },
        ]}/>
      </FormSection>

      {/* Customer (OM phone gated) */}
      <FormSection title="Customer">
        <KeyValueGrid columns={2} items={[
          { label: "Customer",  value: order.customer ? order.customer.name : "—" },
          { label: "Email",     value: order.customer && order.customer.email ? _emailLink(order.customer.email) : "—" },
          ...(role !== "OM" ? [{ label: "Phone", value: order.customer && order.customer.phone ? _phoneLink(order.customer.phone) : "—" }] : []),
        ]}/>
      </FormSection>

      {/* Device — App orders only */}
      {orderSource === "app" && (
        <FormSection title="Device">
          <KeyValueGrid columns={2} items={[
            { label: "OS",              value: order.device_os || "—" },
            { label: "Location opt-in", value: hasGeo ? "Yes" : "No" },
            ...(hasGeo ? [
              { label: "Coordinates",
                value: <span style={{ display: "inline-flex", alignItems: "center", gap: 6 }}>
                  <span style={{ ...T.mono, fontSize: 12 }}>{Number(order.geolocation_lat).toFixed(5)}, {Number(order.geolocation_lng).toFixed(5)}</span>
                  <a href={`https://www.google.com/maps?q=${order.geolocation_lat},${order.geolocation_lng}`}
                     target="_blank" rel="noopener noreferrer"
                     style={{ display: "inline-flex", alignItems: "center", color: "var(--forest)", opacity: 0.7 }}
                     title="Open in Google Maps" onClick={e => e.stopPropagation()}>
                    <LIcon name="MapPin" size={14} strokeWidth={1.8}/>
                  </a>
                </span> },
            ] : []),
          ]}/>
        </FormSection>
      )}

      {/* Items */}
      <FormSection title="Items">
        <Table
          emptyText="No items"
          columns={[
            { label: "Item",       render: r => <span style={{ ...T.primary() }}>{r.name}</span> },
            { label: "Qty",        width: 60,  render: r => <span style={{ ...T_MUTED }}>{r.qty}</span> },
            { label: "Unit price", width: 110, render: r => <span style={{ ...T.amount }}>{fmt(r.unit)}</span> },
            { label: "Total",      width: 110, render: r => <span style={{ ...T.amount }}>{fmt(r.subtotal)}</span> },
          ]}
          rows={order.items || []}/>
      </FormSection>

      {/* Fulfilment */}
      <FormSection title="Fulfilment">
        <KeyValueGrid columns={1} items={[
          { label: "Timing", value: fulfilmentLabel },
        ]}/>
      </FormSection>

      {/* Totals */}
      <FormSection title="Totals">
        <KeyValueGrid columns={2} items={[
          { label: "Subtotal",        value: fmt(order.totals && order.totals.subtotal), mono: true },
          { label: "Tax",             value: fmt(order.totals && order.totals.tax), mono: true },
          { label: "Tip",             value: order.tip_amount != null ? fmt(order.tip_amount) : "—", mono: true },
          { label: "Total",           value: fmt(order.totals && order.totals.total), mono: true },
          { label: "Voucher",         value: order.voucher_code || "—", mono: true },
          { label: "Payment method",  value: order.payment && order.payment.method ? order.payment.method : "—" },
          { label: "Payment gateway", value: order.payment && order.payment.provider ? order.payment.provider : "—" },
          { label: "Payment status",  value: <StatusPill status={paymentTone} kind="order"/> },
        ]}/>
      </FormSection>

      {/* Refunds — read-only derived status + deep-link (Review 9 / 03-ui: no refund action here) */}
      <FormSection title="Refunds">
        <KeyValueGrid columns={1} items={[
          { label: "Refund status",
            value: displayStatus === "refunded"
              ? <StatusPill status="refunded" kind="order"/>
              : <span style={{ ...T_MUTED }}>No refunds issued</span> },
        ]}/>
        <div style={{ display: "flex", justifyContent: "flex-end", marginTop: 8 }}>
          <Btn variant="ghost" onClick={() => _go(`${role.toLowerCase()}-refunds`, { order_id: order.id })}>
            <LIcon name="ExternalLink" size={14}/> Open in Refunds
          </Btn>
        </div>
      </FormSection>

      {/* Loyalty — derived back-reference (redemption.order_id → this order; no stored redemption_id) */}
      <FormSection title="Loyalty">
        {orderRedemptions.length === 0
          ? <KeyValueGrid columns={1} items={[
              { label: "Redemption", value: <span style={{ ...T_MUTED }}>No reward redeemed on this order</span> },
            ]}/>
          : <Table
              emptyText="—"
              columns={[
                { label: "Reward",   render: r => <span style={{ ...T.primary() }}>{_rewardNm(r.reward_id)}</span> },
                { label: "Points",   width: 90,  render: r => <span style={{ ...T_MUTED }}>{(r.points_spent || 0).toLocaleString()}</span> },
                { label: "Redeemed", width: 180, render: r => <span style={{ ...T_MUTED }}>{_fmtDateTime(r.redeemed_at, r.country_id)}</span> },
              ]}
              rows={orderRedemptions}/>
        }
      </FormSection>

      {/* Remarks */}
      <RemarksSection
        entityType="order"
        entityId={order.id}
        remarks={remarks}
        onAdd={addRemark}
        role={role}
        currentUser={CURRENT_USER}
        onEdit={editRemark}
        onDelete={deleteRemark}/>
    </DetailDrawer>
  );
}

Object.assign(window, { OrdersList, OrderDetailDrawer });
})();
