/* page-exchanges.jsx — Exchanges (issued-gift ledger). Gifts module, all roles (GA/CM/AM/OM).
 * Mirrors Rewards↔Redemptions pattern. Read-only log; no Add-new.
 * Routes: *-purchases → ExchangesList (nav key 'purchases').
 * Data: USER_GIFTS / USER_GIFT_BY_ID / GIFT_ITEMS / GIFT_ITEM_BY_ID (landed by Agent C).
 */
(function () {
  const { useState, useMemo, useEffect } = React;

  // ── Gift item lookup helpers ──────────────────────────────────────────────────
  const _giftItem = (id) => {
    const map = typeof GIFT_ITEM_BY_ID !== "undefined" ? GIFT_ITEM_BY_ID : {};
    return map[id] || null;
  };
  const _giftItemName = (id) => {
    const item = _giftItem(id);
    return item ? item.name : (id || "—");
  };
  const _giftTypeName = (item) => {
    if (!item) return "—";
    const opts = typeof CUSTOM_OPTIONS !== "undefined" ? CUSTOM_OPTIONS : [];
    const opt = opts.find(o => o.id === item.gift_type_id || o.option_type === "gift_type");
    // Search specifically for this gift_type_id
    const byId = opts.find(o => o.id === item.gift_type_id);
    return byId ? byId.label : (item.gift_type_id || "—");
  };

  // ── Sender/recipient customer lookup ─────────────────────────────────────────
  const _custBy = (id) => {
    if (!id) return { name: "—", email: null, phone: null };
    const map = typeof CM_CUSTOMER_BY_ID !== "undefined" ? CM_CUSTOMER_BY_ID : {};
    const c = map[id];
    if (!c) return { name: id, email: null, phone: null };
    return { name: c.name, email: c.email || null, phone: c.phone || null };
  };

  // ── Currency format (no _money helper per spec) ───────────────────────────────
  const _fmt = (n, country_id) => {
    const country = typeof SB2_COUNTRY_BY_ID !== "undefined" ? SB2_COUNTRY_BY_ID[country_id] : null;
    const code = country ? country.currency_code : "USD";
    return `${code} ${Number(n || 0).toLocaleString()}`;
  };

  // ── Tax label — inclusive (PH/SG) vs exclusive (ID/TH) ───────────────────────
  const _taxLabel = (country_id) => {
    const country = typeof SB2_COUNTRY_BY_ID !== "undefined" ? SB2_COUNTRY_BY_ID[country_id] : null;
    if (!country) return "Tax";
    return country.tax_type === "inclusive" ? "Tax (incl.)" : "Tax (excl.)";
  };

  // ── Status filter options ─────────────────────────────────────────────────────
  const STATUS_OPTS = [
    { value: "",          label: "All statuses" },
    { value: "active",    label: "Active" },
    { value: "redeemed",  label: "Redeemed" },
    { value: "expired",   label: "Expired" },
  ];

  // Country filter options (GA primaryFilter)
  const COUNTRY_OPTS = [
    { value: "", label: "All countries" },
    ...(typeof SB2_COUNTRIES !== "undefined" ? SB2_COUNTRIES : [])
      .map(c => ({ value: c.country_id, label: `${c.flag} ${c.country_name}` })),
  ];

  // ── Remarks sub-component (hook at stable top level, not inside drawer JSX) ──
  function ExchangeRemarks({ exchangeId, seed }) {
    const [remarks, addRemark, editRemark, deleteRemark] = _useRemarks("exchange", exchangeId, seed || []);
    return (
      <RemarksSection
        entityType="exchange"
        entityId={exchangeId}
        remarks={remarks}
        onAdd={addRemark}
        currentUser="you"
        onEdit={editRemark}
        onDelete={deleteRemark}
      />
    );
  }

  /** @spec GA-/CM-/AM-/OM-purchases */
  function ExchangesList({ role }) {
    if (!["GA", "CM", "AM", "OM"].includes(role)) return _notAuthorised;

    // ── Deep-link context chip (gift_item_id) ─────────────────────────────────
    const incoming = (typeof window !== "undefined" && window.__sixhands_route_payload)
      ? window.__sixhands_route_payload.gift_item_id : null;
    const [ctxGiftItemId, setCtxGiftItemId] = useState(incoming || null);

    const clearCtx = () => { setCtxGiftItemId(null); setPage(1); };

    // ── Scope baseline ────────────────────────────────────────────────────────
    // An exchange is a VIRTUAL gift send — the entity has only country_id (no outlet/area;
    // 01-modules §Exchanges). So every sub-GA tier (CM/AM/OM) is scoped to its OWN COUNTRY,
    // not an outlet/area. (Ratified 2026-06-08; supersedes 02-rbac L71 'own area'/'own outlet'.)
    const scopeCountry = useMemo(() => {
      if (role === "CM") return "PH"; // prototype CM is the PH country manager
      if (role === "AM") {
        const areaId = typeof AM_AREA_ID !== "undefined" ? AM_AREA_ID : "ar_03";
        const a = (typeof SB3_AREAS !== "undefined" ? SB3_AREAS : []).find(x => x.id === areaId);
        return a ? a.country_id : "PH";
      }
      if (role === "OM") {
        const oid = typeof OM_OUTLET_ID !== "undefined" ? OM_OUTLET_ID : "SH-PH-001";
        const o = (typeof SB3_OUTLETS !== "undefined" ? SB3_OUTLETS : []).find(x => x.id === oid);
        return o ? o.country_id : "PH";
      }
      return null; // GA: all countries
    }, [role]);

    const allGifts = useMemo(
      () => typeof USER_GIFTS !== "undefined" ? USER_GIFTS : [],
      []
    );

    const baseRows = useMemo(
      () => allGifts.filter(r => !scopeCountry || r.country_id === scopeCountry),
      [allGifts, scopeCountry]
    );

    // ── Filter state ──────────────────────────────────────────────────────────
    const [search, setSearch] = useState("");
    const [statusFilter, setStatusFilter] = useState("");
    const [countryFilter, setCountryFilter] = useState("");
    const [giftType, setGiftType] = useState("");
    const [dtf, setDtf] = useState(null);
    const [page, setPage] = useState(1);
    const [pageSize, setPageSize] = useState(25);
    const [drawerRow, setDrawerRow] = useState(null);
    const [drawerOpen, setDrawerOpen] = useState(false);

    // ── toast ──
    const [toast, setToast] = useState(null);
    const fireToast = (msg) => { setToast(msg); setTimeout(() => setToast(null), 2400); };

    // ── Filtered rows ─────────────────────────────────────────────────────────
    const rows = useMemo(() => {
      let r = [...baseRows];

      // Context chip filter (deep-link)
      if (ctxGiftItemId) r = r.filter(x => x.gift_item_id === ctxGiftItemId);

      // GA country inline filter
      if (role === "GA" && countryFilter) r = r.filter(x => x.country_id === countryFilter);

      // Status filter
      if (statusFilter) r = r.filter(x => x.status === statusFilter);

      // Gift type filter — joins through gift_item_id → catalog (gift_type_id is not stored on the exchange row)
      if (giftType) r = r.filter(x => { const it = _giftItem(x.gift_item_id); return it && it.gift_type_id === giftType; });

      // DateTimeFilter (created_at) — no filter set ⇒ show all (guard like page-orders/page-messenger;
      // unguarded _dtfMatch(null,…) defaults to "today only" and empties an aged ledger)
      if (dtf) r = r.filter(x => _dtfMatch(dtf, x.created_at, x.country_id || "SG"));

      // Search (gift_item_id name, voucher_code, sender name)
      if (search) {
        const q = search.toLowerCase();
        r = r.filter(x =>
          x.id.toLowerCase().includes(q) ||
          _giftItemName(x.gift_item_id).toLowerCase().includes(q) ||
          (x.voucher_code && x.voucher_code.toLowerCase().includes(q)) ||
          _custBy(x.sender_id).name.toLowerCase().includes(q)
        );
      }

      return r;
    }, [baseRows, role, ctxGiftItemId, countryFilter, statusFilter, giftType, dtf, search]);

    // Gift-type filter options — computed from the catalog items actually referenced (no stored registry)
    const GIFT_TYPE_OPTS = useMemo(() => {
      const items = typeof GIFT_ITEMS !== "undefined" ? GIFT_ITEMS : [];
      const opts = typeof CUSTOM_OPTIONS !== "undefined" ? CUSTOM_OPTIONS : [];
      const seen = new Set();
      const out = [{ value: "", label: "All gift types" }];
      items.forEach(it => {
        if (it.gift_type_id && !seen.has(it.gift_type_id)) {
          seen.add(it.gift_type_id);
          const o = opts.find(x => x.id === it.gift_type_id);
          out.push({ value: it.gift_type_id, label: o ? o.label : it.gift_type_id });
        }
      });
      return out;
    }, []);

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

    // ── FilterBar config ──────────────────────────────────────────────────────
    // GA: status + country as 2 inline primaryFilters (capped at 2)
    // CM/AM/OM: status only as inline primaryFilter
    const primaryFilterArr = role === "GA"
      ? [
          { key: "status",     label: "Status",  options: STATUS_OPTS },
          { key: "country_id", label: "Country", options: COUNTRY_OPTS },
        ]
      : [
          { key: "status", label: "Status", options: STATUS_OPTS },
        ];

    const primaryValue = role === "GA"
      ? { status: statusFilter, country_id: countryFilter }
      : { status: statusFilter };

    // FilterBar (array primaryFilter) calls onPrimaryChange with ONE merged object, not (k,v)
    const onPrimaryChange = (next) => {
      if (next.status !== undefined)     setStatusFilter(next.status || "");
      if (next.country_id !== undefined) setCountryFilter(next.country_id || "");
      setPage(1);
    };

    const advancedFilters = [
      { key: "gift_type", kind: "select", label: "Gift type", options: GIFT_TYPE_OPTS },
      { key: "dtf", kind: "datetime", label: "Date & time", country: "SG" },
    ];

    const advancedValues = {
      gift_type: giftType,
      dtf,
    };

    const onAdvancedChange = (k, v) => {
      if (k === "gift_type") { setGiftType(v); setPage(1); }
      else if (k === "dtf")  { setDtf(v); setPage(1); }
    };

    const onAdvancedReset = () => {
      setGiftType("");
      setDtf(null);
      setPage(1);
    };

    const onReset = () => {
      setSearch("");
      setStatusFilter("");
      setCountryFilter("");
      setGiftType("");
      setDtf(null);
      setPage(1);
    };

    // ── Columns — base (all roles) + extended (GA/CM/AM only) ────────────────
    const giftItemCol = {
      key: "gift_item_id", label: "Gift item", sortable: true, sortKey: "gift_item_id",
      render: r => <span style={{ ...T.primary() }}>{_giftItemName(r.gift_item_id)}</span>,
    };
    const giftTypeCol = {
      key: "gift_type", label: "Gift type", sortable: true, sortKey: "gift_type",
      render: r => {
        const item = _giftItem(r.gift_item_id);
        return <span style={{ ...T_MUTED }}>{_giftTypeName(item)}</span>;
      },
    };
    const valueCol = {
      key: "value", label: "Value", sortable: true, sortKey: "value",
      render: r => <span style={{ ...T_MUTED, whiteSpace: "nowrap" }}>{_fmt(r.value, r.country_id)}</span>,
    };
    const statusCol = {
      key: "status", label: "Status", sortable: false,
      render: r => <StatusPill status={r.status} kind="exchange"/>,
    };
    const createdAtCol = {
      key: "created_at", label: "Date", sortable: true, sortKey: "created_at",
      render: r => <span style={{ ...T_MUTED, whiteSpace: "nowrap" }}>{_fmtDateTime(r.created_at, r.country_id)}</span>,
    };
    // Extended: GA/CM/AM only
    const senderCol = {
      key: "sender_id", label: "Sender", sortable: true, sortKey: "sender_id",
      render: r => {
        const c = _custBy(r.sender_id);
        return (
          <span>
            <span style={{ ...T.primary() }}>{c.name}</span>
            {c.email && <span style={{ marginLeft: 4 }}>{_emailLink(c.email, { muted: true })}</span>}
          </span>
        );
      },
    };
    const recipientCol = {
      key: "recipient_user_id", label: "Recipient", sortable: true, sortKey: "recipient_user_id",
      render: r => {
        const c = _custBy(r.recipient_user_id);
        return (
          <span>
            <span style={{ ...T.primary() }}>{c.name}</span>
            {c.email && <span style={{ marginLeft: 4 }}>{_emailLink(c.email, { muted: true })}</span>}
            {c.phone && <span style={{ marginLeft: 4 }}>{_phoneLink(c.phone, { muted: true })}</span>}
          </span>
        );
      },
    };
    const voucherCol = {
      key: "voucher_code", label: "Voucher code", sortable: true, sortKey: "voucher_code",
      render: r => r.voucher_code
        ? <span style={{ ..._MONO }}>{r.voucher_code}</span>
        : <span style={{ ...T_MUTED }}>—</span>,
    };

    // All roles see the full column set incl. Sender/Recipient/Voucher, scoped to the role's data.
    // OM-A+ restore (ratified 2026-06-03; voucher shown per 2026-06-08): OM sees parties + voucher for own outlet.
    const columns = [giftItemCol, giftTypeCol, valueCol, statusCol, createdAtCol, senderCol, recipientCol, voucherCol];

    // ── Descriptions ──────────────────────────────────────────────────────────
    const descriptions = {
      GA: "Gifts sent across markets.",
      CM: "Your country's gift exchanges.",
      AM: "Your area's gift exchanges.",
      OM: "Your outlet's gift exchanges.",
    };

    // ── Active drawer row ─────────────────────────────────────────────────────
    const r = drawerRow;

    return (
      <div className="page-inner">
        <PageHead
          title="Exchanges"
          description={descriptions[role] || "Gift exchange ledger."}
          actions={<ExportButton role={role} variant="primary" onClick={() => fireToast("Exporting exchanges…")}/>}
        />

        {/* Context chip — deep-link filter to a specific gift item */}
        {ctxGiftItemId && (
          <div style={{ display: "flex", alignItems: "center", gap: 8, marginBottom: 12 }}>
            <span style={{ ...T_MUTED, fontSize: 12 }}>Filtered by gift item:</span>
            <span style={{ display: "inline-flex", alignItems: "center", gap: 6,
              background: "var(--mint-soft)", border: "1px solid var(--mint)", borderRadius: "var(--r-pill)",
              padding: "3px 10px", fontSize: 12, color: "var(--forest)", fontFamily: "var(--font-ui)" }}>
              {_giftItemName(ctxGiftItemId)}
              <button
                onClick={clearCtx}
                style={{ background: "none", border: "none", cursor: "pointer", padding: 0, lineHeight: 1,
                  color: "var(--forest)", display: "inline-flex", alignItems: "center" }}
                aria-label="Clear gift item filter"
              >
                <LIcon name="X" size={12} strokeWidth={2.5}/>
              </button>
            </span>
          </div>
        )}

        <FilterBar
          search={search}
          onSearch={q => { setSearch(q); setPage(1); }}
          searchPlaceholder="Search exchanges…"
          primaryFilter={primaryFilterArr}
          primaryValue={primaryValue}
          onPrimaryChange={onPrimaryChange}
          advancedFilters={advancedFilters}
          advancedValues={advancedValues}
          onAdvancedChange={onAdvancedChange}
          onAdvancedReset={onAdvancedReset}
          onReset={onReset}
        />

        <Table
          dense
          columns={columns}
          rows={visibleRows}
          emptyText="No exchanges match your filters."
          onRow={row => {
            setDrawerRow(row);
            setDrawerOpen(true);
          }}
        />

        <TableFooter
          page={page}
          totalPages={totalPages}
          onPage={p => setPage(p)}
          count={pageSize}
          onCountChange={c => { setPageSize(c); setPage(1); }}
        />

        {r && (
          <DetailDrawer
            open={drawerOpen}
            onClose={() => setDrawerOpen(false)}
            title={r.id}
            subtitle={_giftItemName(r.gift_item_id)}
            actions={[
              <Btn key="close" variant="secondary" onClick={() => setDrawerOpen(false)}>Close</Btn>,
            ]}
          >
            {/* Section 1: General */}
            <FormSection title="General">
              <KeyValueGrid items={[
                { label: "Gift item",  value: _giftItemName(r.gift_item_id) },
                { label: "Gift type",  value: _giftTypeName(_giftItem(r.gift_item_id)) },
                { label: "Value",      value: _fmt(r.value, r.country_id) },
                ...(r.voucher_code ? [{ label: "Voucher code", value: <span style={{ ..._MONO }}>{r.voucher_code}</span> }] : []),
              ]}/>
            </FormSection>

            {/* Section 2: Parties — all roles (OM-A+ restore, scoped to role's data) */}
            <FormSection title="Parties">
                <KeyValueGrid items={[
                  {
                    label: "Sender",
                    value: (() => {
                      const c = _custBy(r.sender_id);
                      return (
                        <span>
                          {c.name}
                          {c.email && <span style={{ marginLeft: 6 }}>{_emailLink(c.email)}</span>}
                          {c.phone && <span style={{ marginLeft: 6 }}>{_phoneLink(c.phone)}</span>}
                        </span>
                      );
                    })(),
                  },
                  {
                    label: "Recipient",
                    value: (() => {
                      const c = _custBy(r.recipient_user_id);
                      return (
                        <span>
                          {c.name}
                          {c.email && <span style={{ marginLeft: 6 }}>{_emailLink(c.email)}</span>}
                          {c.phone && <span style={{ marginLeft: 6 }}>{_phoneLink(c.phone)}</span>}
                        </span>
                      );
                    })(),
                  },
                ]}/>
            </FormSection>

            {/* Section 3: Money — value + tip_amount; tax label branches on tax_type */}
            <FormSection title="Money">
              <KeyValueGrid items={[
                { label: "Value",           value: _fmt(r.value, r.country_id) },
                { label: "Tip",             value: r.tip_amount != null && r.tip_amount > 0
                    ? _fmt(r.tip_amount, r.country_id) : "—" },
                { label: _taxLabel(r.country_id), value: (() => {
                    const country = typeof SB2_COUNTRY_BY_ID !== "undefined" ? SB2_COUNTRY_BY_ID[r.country_id] : null;
                    if (!country || !country.tax_rate) return "—";
                    return `${country.tax_rate}%`;
                  })() },
              ]}/>
            </FormSection>

            {/* Section 4: Note (message, conditional) */}
            {r.message && (
              <FormSection title="Note">
                <KeyValueGrid items={[
                  { label: "Message", value: <span style={{ ...T_MUTED }}>{r.message}</span> },
                ]}/>
              </FormSection>
            )}

            {/* Section 5: Status */}
            <FormSection title="Status">
              <KeyValueGrid items={[
                { label: "Status",     value: <StatusPill status={r.status} kind="exchange"/> },
                { label: "Country",    value: _countryLabel(r.country_id) },
                { label: "Created",    value: _fmtDateTime(r.created_at, r.country_id) },
              ]}/>
            </FormSection>

            {/* Section 6: Remarks */}
            <ExchangeRemarks key={r.id} exchangeId={r.id} seed={r.exchange_remarks}/>
          </DetailDrawer>
        )}
      {toast && <Toast message={toast}/>}
      </div>
    );
  }

  Object.assign(window, { ExchangesList });
})();
