/* page-countries.jsx — Countries module. IIFE-scoped; exports via window. */
(function(){
const { useState, useMemo } = React;


// Read-only Policies / Refund-limit mock — mirrors CountryEdit defaults so
// the detail (read-only) and edit form agree. No SB2 fields for these yet (owned elsewhere).
// Refund limits now sourced from the shared REFUND_LIMITS_BY_COUNTRY map (SSOT, per approved decision #3).
// _refundLimitFor(country_id, tier) is defined in helpers.jsx; fallbacks guard unknown/empty country_id.
const _POLICY_LABELS_RO = { refund: "Refund policy", cancellation: "Cancellation policy", pickup: "Pickup / collection policy" };
const _getPolicyConfig = (cid) => ({
  policies: { refund: "HQ template", cancellation: "HQ template", pickup: "HQ template" },
  refund_limit_cm: (_refundLimitFor && _refundLimitFor(cid, "cm")) || 5000,
  refund_limit_am: (_refundLimitFor && _refundLimitFor(cid, "am")) || 2000,
  refund_limit_om: (_refundLimitFor && _refundLimitFor(cid, "om")) || 500,
});

// Onboarding milestones (5, per spec-05 logic).
const _onboardingSteps = (country) => {
  if (!country) return [];
  const intStatus = _getIntegrationStatus(country.country_id);
  const hasCm   = !!(country.cm_user_id || (country.country_id === "PH" || country.country_id === "SG"));
  const gwOk    = intStatus.payment_gateway_status === "connected";
  const posOk   = intStatus.pos_integration_status === "connected";
  const hasOutlet = (country.country_id === "PH" || country.country_id === "SG" || country.country_id === "ID");
  const hasOrder  = (country.country_id === "PH" || country.country_id === "SG");
  return [
    { id: "m1", label: "Contract + country",        status: "done" },
    { id: "m2", label: "CM assigned",               status: hasCm ? "done" : "todo" },
    { id: "m3", label: "Payment gateway healthy",   status: gwOk ? "done" : posOk ? "active" : "todo" },
    { id: "m4", label: "First outlet",              status: hasOutlet ? "done" : "todo" },
    { id: "m5", label: "First order",               status: hasOrder ? "done" : "todo" },
  ];
};

// Country Manager = User reverse-lookup (convention 11). The CM is the User with
// role_type "country_manager" whose franchise_id scope places them on this country's
// franchisee — NEVER a field on the country. Read-only direction; never duplicated.
const _countryManager = (cid) =>
  SB3_USERS.find(u =>
    u.role_type === "country_manager" &&
    (SB3_FRANCHISEE_BY_ID[u.franchise_id] || {}).country_id === cid
  ) || null;
// Eligible CMs for edit-select: country_manager users scoped to this country (incl. unassigned-to-a-different-country).
const _eligibleCountryManagers = (cid) =>
  SB3_USERS.filter(u =>
    u.role_type === "country_manager" &&
    (SB3_FRANCHISEE_BY_ID[u.franchise_id] || {}).country_id === cid
  );

// ──────────────────────────────────────────────────────────
/**
 * @spec GA-020 — Countries list
 * US-001, US-004, US-005. GA sees all countries; CM/AM land on their own country detail.
 */
function CountriesList({ role = "GA" }) {
  const [filters, setFilters] = useState({});
  const [searchQuery, setSearchQuery] = useState("");
  const [page, setPage] = useState(1);
  const [pageSize, setPageSize] = useState(20);

  const rows = useMemo(() => {
    if (role !== "GA") return [];
    return SB2_COUNTRIES
      .filter(c => {
        if (filters.status && c.status !== filters.status) return false;
        if (searchQuery && !c.country_name.toLowerCase().includes(searchQuery.toLowerCase()) && !c.country_id.toLowerCase().includes(searchQuery.toLowerCase())) return false;
        return true;
      });
  }, [role, filters, searchQuery]);

  // CM/AM land directly on their own country detail (read-only) — no list.
  if (role === "CM" || role === "AM") {
    return <CountryDetail role={role}/>;
  }
  if (role !== "GA") return <EmptyState icon={null} title="Not authorised" body="Countries list is available to Global Admins only."/>;

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

  return (
    <div className="page-inner">
      <PageHead
        title="Countries"
        description="Markets in the network."
        actions={<Btn variant="primary" onClick={() => _go("ga-country-wizard")}>New country</Btn>}
      />

      <FilterBar
        primaryFilter={{ key: "status", label: "Status", options: [
          { value: "draft",    label: "Draft" },
          { value: "active",   label: "Active" },
          { value: "inactive", label: "Inactive" },
        ]}}
        values={filters}
        onChange={(k, v) => setFilters(f => ({ ...f, [k]: v }))}
        onReset={() => { setFilters({}); setSearchQuery(""); }}
        search={searchQuery}
        onSearch={setSearchQuery}
        searchPlaceholder="Search countries…"
      />

      <Table
        columns={[
          { label: "Country", width: 240, sortable: true, sortKey: "country_name", render: r => (
            <span className="row ai-c" style={{ gap: 10 }}>
              <span style={{ fontSize: 20 }}>{r.flag}</span>
              <span style={{ ...T.primary(1) }}>{r.country_name}</span>
              <span style={{ ...T_MUTED }}>{r.country_id}</span>
            </span>
          )},
          { label: "Status",      width: 120, sortable: true, sortKey: "status", render: r => <StatusPill status={r.status} kind="country"/> },
          { label: "Franchisees", width: 110, sortable: true, sortKey: "franchisees",  render: r => <span style={{ ...T_MUTED }}>{r.franchisees}</span> },
          { label: "Last activity", width: 160, sortable: true, sortKey: "last_activity", render: r => <span style={{ ...T_MUTED }}>{r.last_activity}</span> },
          { label: "", width: 48, render: () => <span style={{ color: "var(--forest)" }}>{Ic.chevR(16)}</span> },
        ]}
        rows={visibleRows}
        onRow={r => _go("ga-country-detail", { id: r.country_id })}
        emptyText="No countries match the current filter."
      />

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

    </div>
  );
}

// ──────────────────────────────────────────────────────────
/**
 * @spec GA-022 — Country detail (full-page, tabs; read-only by default)
 * US-001, US-003, US-004. GA sees Edit (Country Update = GA-only) + all 5 tabs.
 * CM/AM land on their own country, read-only, no Edit, tabs = Overview · Integration · Onboarding only
 * (no Performance — own Performance nav page; no Settings — Danger zone is GA-only). 03-ui §2 Table 2.
 */
function CountryDetail({ role = "GA" }) {
  const payloadId = typeof window !== "undefined" && window.__sixhands_route_payload ? window.__sixhands_route_payload.id : null;
  // CM/AM always land on their own country (mock: PH); GA resolves from payload.
  const effectiveId = payloadId || (role === "CM" || role === "AM" ? "PH" : null);
  const country = (effectiveId && SB2_COUNTRY_BY_ID[effectiveId]) || SB2_COUNTRY_BY_ID.PH;
  const cid = country.country_id;
  const isGA = role === "GA";

  // Role-gated tabs (03-ui §2 Table 2): GA = all 5; CM/AM = Overview · Integration · Onboarding only.
  const detailTabs = [
    { id: "overview",    label: "Overview" },
    ...(isGA ? [{ id: "performance", label: "Performance" }] : []),
    { id: "integration", label: "Integration" },
    { id: "onboarding",  label: "Onboarding" },
    ...(isGA ? [{ id: "settings",    label: "Settings" }] : []),
  ];

  const [tab, setTab] = useState("overview");
  const [trialToast, setTrialToast]         = useState(false);
  const [lifecycleToast, setLifecycleToast] = useState(null);

  const intStatus = _getIntegrationStatus(cid);

  // Related-entity counts (deep-link card values).
  const franchiseeCount = SB3_FRANCHISEES.filter(f => f.country_id === cid).length;
  const outletCount     = SB3_OUTLETS.filter(o => o.country_id === cid).length;
  const areaCount       = SB3_AREAS.filter(a => a.country_id === cid).length;
  const userCount       = SB3_USERS.filter(u => u.country_id === cid).length;
  const filterPayload   = { filter: { country_id: cid, label: country.country_name } };

  const flagValues = SB2_FLAG_VALUES[cid] || {};
  const countryManager = _countryManager(cid);  // User reverse-lookup; never a country field (convention 11).

  const backLabel   = isGA ? "Countries" : null;
  const pageTitle   = isGA ? `${country.country_name} · Country` : "My Country";
  const pageDesc    = isGA ? "Markets in the network." : "Your country's configuration.";

  // ── OVERVIEW: full read-only config (Identity · Feature flags · Policies · Refund limits · Related). 03-ui §2 Table 2. ──
  // Editing is behind PageHead Edit → CountryEdit (Table 3); POS/payment commercial values live on the Integration tab.
  const policyCfg = _getPolicyConfig(cid);
  const overview = (
    <>
      <FormSection title="Identity">
        <KeyValueGrid columns={2} items={[
          { label: "Country",  value: `${country.flag} ${country.country_name} · ${cid}` },
          { label: "Timezone", value: country.timezone || "—" },
        ]}/>
      </FormSection>
      <FormSection title="Feature flags" description="Optional features are per-country; all others are always included. Read-only — edit via the form.">
        <div style={{ display: "flex", flexDirection: "column", gap: 12 }}>
          <div>
            <div style={{ ...T.label, marginBottom: 6 }}>Optional</div>
            <div className="row ai-c" style={{ flexWrap: "wrap", gap: 8 }}>
              {SB2_FLAG_DEFS.filter(f => f.optional).map(f => (
                <ChipToggle key={f.key} on={!!flagValues[f.key]} disabled>{f.label}</ChipToggle>
              ))}
            </div>
          </div>
          <div>
            <div style={{ ...T.label, marginBottom: 6 }}>Always included</div>
            <div className="row ai-c" style={{ flexWrap: "wrap", gap: 8 }}>
              {SB2_FLAG_DEFS.filter(f => !f.optional).map(f => (
                <ChipToggle key={f.key} on={!!flagValues[f.key]} disabled>{f.label}</ChipToggle>
              ))}
            </div>
          </div>
        </div>
      </FormSection>
      <FormSection title="Policies" description="Legal policy content. Read-only — edit via the form.">
        <KeyValueGrid columns={2} items={[
          { label: _POLICY_LABELS_RO.refund,        value: policyCfg.policies.refund },
          { label: _POLICY_LABELS_RO.cancellation,  value: policyCfg.policies.cancellation },
          { label: _POLICY_LABELS_RO.pickup,        value: policyCfg.policies.pickup },
        ]}/>
      </FormSection>
      <FormSection title="Refund limits" description="Per-tier caps in local currency. GA-set; read-only here.">
        <KeyValueGrid columns={3} items={[
          { label: "CM limit", value: `${country.currency_code || ""} ${policyCfg.refund_limit_cm.toLocaleString()}`.trim() },
          { label: "AM limit", value: `${country.currency_code || ""} ${policyCfg.refund_limit_am.toLocaleString()}`.trim() },
          { label: "OM limit", value: `${country.currency_code || ""} ${policyCfg.refund_limit_om.toLocaleString()}`.trim() },
        ]}/>
      </FormSection>
      <FormSection title="Country Manager" description="The CM is a User scoped to this country. Read-only here; assign via the form.">
        <ManagerSection
          manager={countryManager}
          mode="read"
          roleType="Country Manager"
          onAddCta={isGA ? () => _go("ga-country-edit", { id: cid }) : undefined}
        />
      </FormSection>
      <FormSection title="Related" description="Open the records that belong to this country.">
        <div className="stat-panel stat-panel-snapshot">
          <div className="stat-panel-grid">
            <StatCard label="Franchisees" value={franchiseeCount} sub="View franchisees in this country"
              icon={<LIcon name="Building2" size={16}/>}
              onClick={() => _go(`${role.toLowerCase()}-franchisees`, filterPayload)}/>
            <StatCard label="Outlets" value={outletCount} sub="View outlets in this country"
              icon={<LIcon name="Store" size={16}/>}
              onClick={() => _go(`${role.toLowerCase()}-outlets`, filterPayload)}/>
            <StatCard label="Areas" value={areaCount} sub="View areas in this country"
              icon={<LIcon name="Map" size={16}/>}
              onClick={() => _go(`${role.toLowerCase()}-areas`, filterPayload)}/>
            <StatCard label="Users" value={userCount} sub="View users in this country"
              icon={<LIcon name="Users" size={16}/>}
              onClick={() => _go(`${role.toLowerCase()}-users`, filterPayload)}/>
          </div>
        </div>
      </FormSection>
    </>
  );

  // ── PERFORMANCE (GA only): reuse the role Dashboard scoped to this country (convention 5). ──
  // PerformanceDashboardContent is the shared scoped-dashboard component (page-dashboards.jsx) — not a recreated panel.
  const performance = <PerformanceDashboardContent scope={{ country_id: cid }} role={role}/>;

  // ── INTEGRATION: read-only POS / gateway status + GA-only trial txn ──
  const integration = (
    <>
      <FormSection title="Integration status" description="POS and payment gateway connectivity. Managed by DX.">
        <IntegrationBlock intStatus={intStatus} posContext={country}/>
        {isGA && (
          <div style={{ marginTop: 16 }}>
            <Btn variant="secondary" size="sm"
              icon={<LIcon name="Zap" size={14}/>}
              onClick={() => { setTrialToast(true); setTimeout(() => setTrialToast(false), 2500); }}>
              Run trial transaction
            </Btn>
          </div>
        )}
      </FormSection>
      <InlineAlert kind="info">
        Go-live requires both POS and payment gateway showing <strong>connected</strong>. Account and outlet creation is not blocked while integrations are pending.
      </InlineAlert>
    </>
  );

  // ── ONBOARDING: 5-milestone checklist (read-only) ──
  const onboarding = (
    <>
      <FormSection title="Go-live milestones" description="Computed from country state. All 5 milestones must be complete to go live.">
        <ChecklistProgress steps={_onboardingSteps(country)}/>
      </FormSection>
      <InlineAlert kind="info">
        Go-live requires both POS integration and payment gateway showing <strong>connected</strong> on the Integration tab.
      </InlineAlert>
    </>
  );

  return (
    <div className="page-inner">
      <PageHead
        title={pageTitle}
        description={pageDesc}
        status={<StatusPill status={country.status} kind="country"/>}
        back={backLabel ? { label: backLabel, onClick: () => _go("ga-countries") } : undefined}
        actions={isGA ? <Btn variant="primary" onClick={() => _go("ga-country-edit", { id: cid })}>Edit</Btn> : undefined}
      />

      <Tabs
        tabs={detailTabs}
        active={tab}
        onChange={setTab}
      />

      {tab === "overview"    && overview}
      {isGA && tab === "performance" && performance}
      {tab === "integration" && integration}
      {tab === "onboarding"  && onboarding}
      {isGA && tab === "settings" && (
        <>
          <InlineAlert kind="info">
            Set this market's status (<strong>draft, active ⇄ inactive</strong>) from <strong>Edit</strong>. Going live from draft requires the go-live gate (POS + payment gateway connected).
          </InlineAlert>
          <DeleteSection
            entityLabel="country"
            soft={country.status !== "draft"}
            note={country.status === "draft"
              ? "Permanently delete this draft market. Nothing is live yet, so the record is removed outright. Blocked if it already has franchisees/outlets."
              : "Decommission this market (soft-delete). Outlets, orders and audit history are retained; reversible by support. GA-only, and blocked while it has franchisees/outlets."}
            gate={_canDelete(role, {
              status: country.status,
              isReferenced: country.franchisees > 0 || outletCount > 0,
            })}
            confirmBody={country.status === "draft"
              ? <div>Permanently delete the draft market <strong>{country.country_name}</strong>? Nothing is live. Writes to <strong>audit_logs</strong>.</div>
              : <div>Decommissioning <strong>{country.country_name}</strong> takes it offline and hides it from the network. Data + audit history are retained. Writes to <strong>audit_logs</strong>.</div>}
            onDelete={() => {
              setLifecycleToast(`${country.country_name} ${country.status === "draft" ? "deleted" : "decommissioned"} · logged to audit_logs`);
              setTimeout(() => { setLifecycleToast(null); _go("ga-countries"); }, 1400);
            }}
          />
        </>
      )}

      <Toast message={trialToast ? "Trial transaction queued — check Integration logs." : (lifecycleToast || "")} show={trialToast || !!lifecycleToast}/>
    </div>
  );
}

// ──────────────────────────────────────────────────────────
/**
 * @spec GA-022 — Country configuration (editable mode of the detail; Table 3 fields)
 * US-001, US-003, US-004. GA-only editable form behind the detail Edit button. Save/Cancel → ga-country-detail.
 */
function CountryEdit({ role = "GA", scope = {} }) {
  if (role !== "GA") return _notAuthorised;  // Country Update = GA-only; CM/AM use CountryDetail (read-only).
  const payloadId = typeof window !== "undefined" && window.__sixhands_route_payload ? window.__sixhands_route_payload.id : null;
  const effectiveId = payloadId || null;
  const existing = effectiveId ? SB2_COUNTRY_BY_ID[effectiveId] : null;
  const isNew = !existing && role === "GA";
  const readOnly = role === "CM" || role === "AM";

  const initial = existing || {
    country_id: "", country_name: "", flag: "",
    currency_code: "", timezone: "",
    tax_type: "exclusive", tax_rate: null,
    service_charge_enabled: false, service_charge_rate: 0,
    default_payment_provider: "stripe", status: "draft",
  };

  const [form, setForm]     = useState({
    country_id:               initial.country_id,
    country_name:             initial.country_name,
    flag:                     initial.flag,
    currency_code:            initial.currency_code,
    timezone:                 initial.timezone,
    tax_type:                 initial.tax_type,
    tax_rate:                 initial.tax_rate,
    service_charge_enabled:   initial.service_charge_enabled,
    service_charge_rate:      initial.service_charge_rate,
    default_payment_provider: initial.default_payment_provider,
    pos_provider:             initial.pos_provider || (_getIntegrations(initial.country_id).pos[0] || {}).id || "",
    status:                   initial.status,
    refund_limit_cm: (_refundLimitFor && _refundLimitFor(initial.country_id, "cm")) || 5000,
    refund_limit_am: (_refundLimitFor && _refundLimitFor(initial.country_id, "am")) || 2000,
    refund_limit_om: (_refundLimitFor && _refundLimitFor(initial.country_id, "om")) || 500,
  });
  const [flagValues, setFlagValues] = useState(() => {
    const fromMock = (initial.country_id && SB2_FLAG_VALUES[initial.country_id]) || {};
    return Object.fromEntries(SB2_FLAG_DEFS.map(f => [f.key, !!fromMock[f.key]]));
  });
  const toggleFlag = (key) => setFlagValues(v => ({ ...v, [key]: !v[key] }));

  // Legal policies — 3 policies, each: "hq" (use template) or "custom" (open editor).
  const [policyMode, setPolicyMode] = useState({ refund: "hq", cancellation: "hq", pickup: "hq" });
  const [policyContent, setPolicyContent] = useState({ refund: "", cancellation: "", pickup: "" });
  const [policyEditorOpen, setPolicyEditorOpen] = useState(null); // key of currently-open editor

  const [savedToast, setSavedToast]       = useState(false);
  // Country Manager (edit-select existing user only — convention 11). Seeded from current assignment.
  const [cmUserId, setCmUserId] = useState(() => (existing ? (_countryManager(existing.country_id) || {}).id || "" : ""));
  const set = (k, v) => setForm(f => ({ ...f, [k]: v }));
  const intData = _getIntegrations(form.country_id);
  const eligibleCMs = form.country_id ? _eligibleCountryManagers(form.country_id) : [];
  const assignedCM  = cmUserId ? (SB3_USERS.find(u => u.id === cmUserId) || null) : null;

  const POLICY_LABELS = { refund: "Refund policy", cancellation: "Cancellation policy", pickup: "Pickup / collection policy" };
  const HQ_TEMPLATES  = {
    refund: "Customers may request a refund within 24 hours of purchase. Refunds are processed within 3–5 business days to the original payment method.",
    cancellation: "Orders may be cancelled within 5 minutes of placement. After this window, cancellations are subject to manager approval.",
    pickup: "Orders must be collected within 30 minutes of the ready notification. Uncollected orders may be disposed after this period.",
  };

  const backTarget   = isNew ? "ga-countries" : "ga-country-detail";
  const backPayload  = isNew ? undefined : { id: form.country_id };
  const pageTitle    = isNew ? "New country" : `${form.country_name} · Edit`;
  const saveAndReturn = () => {
    setSavedToast(true);
    setTimeout(() => _go(backTarget, backPayload), 1100);
  };

  return (
    <div className="page-inner">
      <PageHead
        title={pageTitle}
        description="Markets in the network."
        status={!isNew ? <StatusPill status={form.status} kind="country"/> : undefined}
        back={{ label: isNew ? "Countries" : `${form.country_name} · Country`, onClick: () => _go(backTarget, backPayload) }}
        actions={<>
          <Btn variant="secondary" onClick={() => _go(backTarget, backPayload)}>Cancel</Btn>
          <Btn
            variant="primary"
            icon={<span style={{ color: "var(--lime)" }}>{Ic.check(16)}</span>}
            onClick={saveAndReturn}>
            {isNew ? "Create country" : "Save changes"}
          </Btn>
        </>}
      />

      {/* ── CONFIG FORM (flat — single group, no Tabs per rule 17) ── */}
      <>
          {/* Identity */}
          <FormSection title="Identity" description="country_id is immutable once set.">
            <div className="row" style={{ gap: 16 }}>
              <div style={{ width: 120 }}>
                <Field label="Country code">
                  <Input value={form.country_id} onChange={v => set("country_id", v.toUpperCase().slice(0,2))} disabled={!isNew || readOnly}/>
                </Field>
              </div>
              <div className="grow">
                <Field label="Country name">
                  <Input value={form.country_name} onChange={v => set("country_name", v)} disabled={readOnly}/>
                </Field>
              </div>
              <div style={{ width: 90 }}>
                <Field label="Flag">
                  <Input value={form.flag} onChange={v => set("flag", v)} disabled={readOnly}/>
                </Field>
              </div>
            </div>
          </FormSection>

          {/* Regional */}
          <FormSection title="Regional" description="Timezone is auto-derived from country.">
            <Field label="Timezone">
              <Input value={form.timezone || "—"} onChange={() => {}} disabled/>
            </Field>
          </FormSection>

          {/* POS — editable selection; commercial values sync from POS (read-only on detail) */}
          <FormSection title="POS" description="Select the POS integration; currency, tax and service charge sync from it and show read-only on the detail Integration tab.">
            <Field label="POS provider">
              <Select value={form.pos_provider || ""} onChange={v => set("pos_provider", v)} placeholder="Choose POS (or integrate later)">
                {(intData.pos.length ? intData.pos : SB_POS_PROVIDERS).map(p => <option key={p.id} value={p.id}>{p.label}</option>)}
                <option value="later">Integrate later</option>
              </Select>
            </Field>
          </FormSection>

          {/* Payment Gateway — editable selection */}
          <FormSection title="Payment Gateway" description="Select the payment gateway DX will configure for this country.">
            <Field label="Payment gateway">
              <Select value={form.default_payment_provider || ""} onChange={v => set("default_payment_provider", v)} placeholder="Choose gateway (or integrate later)">
                {intData.gateway.length ? intData.gateway.map(g => <option key={g.id} value={g.id}>{g.label}</option>) : null}
                <option value="stripe">Stripe</option>
                <option value="opn">Opn (formerly Omise)</option>
                <option value="later">Integrate later</option>
              </Select>
            </Field>
          </FormSection>

          {/* Country Manager — edit = select an existing eligible user only (convention 11). Hidden on new (use the wizard). */}
          {!isNew && (
            <FormSection title="Country Manager" description="Assign an existing Country Manager scoped to this country.">
              {assignedCM && (
                <div style={{ marginBottom: 12 }}>
                  <ManagerSection manager={assignedCM} mode="read" roleType="Country Manager"/>
                </div>
              )}
              <ManagerSection
                mode="edit"
                roleType="Country Manager"
                eligibleUsers={eligibleCMs.map(u => ({ id: u.id, full_name: u.full_name, email: u.email }))}
                onAssignExisting={setCmUserId}
              />
            </FormSection>
          )}

          {/* Status — active ⇄ inactive (go-live gated). Only meaningful for an existing market. */}
          {!isNew && (() => {
            const _is = _getIntegrationStatus(form.country_id);
            const goLiveOk = _is.pos_integration_status === "connected" && _is.payment_gateway_status === "connected";
            return (
              <FormSection title="Status" description="Draft markets are being set up (never live). Active markets are live to consumers; inactive markets were live and are now paused. A market goes live from draft only after the go-live gate; once live it toggles active ⇄ inactive and cannot return to draft.">
                <div style={{ maxWidth: 280 }}>
                  <Field label="Status">
                    <Select value={form.status} onChange={v => set("status", v)} disabled={readOnly}>
                      {form.status === "draft"
                        ? <>
                            <option value="draft">Draft</option>
                            <option value="active" disabled={!goLiveOk}>Active</option>
                          </>
                        : <>
                            <option value="active" disabled={!goLiveOk && form.status !== "active"}>Active</option>
                            <option value="inactive">Inactive</option>
                          </>}
                    </Select>
                  </Field>
                </div>
                {!goLiveOk && form.status !== "active" && (
                  <InlineAlert kind="info">Go-live gate: POS + payment gateway must show <strong>connected</strong> (Integration tab) before this market can be set Active.</InlineAlert>
                )}
              </FormSection>
            );
          })()}

          {/* Feature flags — only Gifts/Rewards/Promotions/Partnerships are toggleable (OQ-072); the rest are always-on, Wallet is SG-only */}
          <FormSection title="Feature flags" description="Optional features (Gifts · Rewards · Promotions · Partnerships) are per-country. All other capabilities are always included; Wallet is SG-only.">
            <div style={{ display: "grid", gridTemplateColumns: "repeat(2, minmax(0,1fr))", gap: 12 }}>
              {[...SB2_FLAG_DEFS].sort((a, b) => (a.optional ? 0 : 1) - (b.optional ? 0 : 1)).map(f => {
                const st = _flagState(f, form.country_id);
                const value = st.toggleable ? !!flagValues[f.key] : st.forced;
                const note = st.toggleable ? f.note : (f.lockedTo ? f.note : "Always included");
                return (
                  <div key={f.key} className="row ai-c jc-sb" style={{ padding: "10px 12px", border: "1.5px solid var(--line)", borderRadius: "var(--r)", opacity: st.toggleable ? 1 : 0.6 }}>
                    <div>
                      <div style={{ ...T.primary(1.2) }}>{f.label}</div>
                      {note && <div style={{ ...T_MUTED, fontSize: 12, marginTop: 2 }}>{note}</div>}
                    </div>
                    <Toggle on={value} onToggle={() => st.toggleable && !readOnly && toggleFlag(f.key)} disabled={!st.toggleable || readOnly}/>
                  </div>
                );
              })}
            </div>
          </FormSection>

          {/* Policies */}
          <FormSection title="Policies" description="Start from the HQ template; override per country only where required.">
            {Object.keys(POLICY_LABELS).map(key => {
              const isHq = policyMode[key] === "hq";
              return (
                <div key={key} style={{ borderTop: "1px solid var(--line)", paddingTop: 12 }}>
                  <div className="row ai-c jc-sb">
                    <div style={{ ...T.primary(1.2) }}>{POLICY_LABELS[key]}</div>
                    {!readOnly && (
                      <Toggle
                        on={isHq}
                        onToggle={() => setPolicyMode(m => ({ ...m, [key]: isHq ? "custom" : "hq" }))}
                        label={isHq ? "Use HQ template" : "Custom"}
                      />
                    )}
                    {readOnly && <span style={{ ...T_MUTED }}>{isHq ? "HQ template" : "Custom"}</span>}
                  </div>
                  {!isHq && !readOnly && (
                    <div style={{ marginTop: 8 }}>
                      <Btn variant="secondary" size="sm" onClick={() => setPolicyEditorOpen(key)}>
                        {policyContent[key] ? "Edit policy" : "Write custom policy"}
                      </Btn>
                      {policyContent[key] && <span style={{ ...T_MUTED, fontSize: 12, marginLeft: 10 }}>Custom content saved.</span>}
                    </div>
                  )}
                </div>
              );
            })}
          </FormSection>

          {/* Refund limits */}
          <FormSection title="Refund limits" description="Maximum refund amounts by role. GA-set; CM/AM read-only.">
            {readOnly ? (
              <KeyValueGrid columns={3} items={[
                { label: "CM limit",  value: `${form.refund_limit_cm}` },
                { label: "AM limit",  value: `${form.refund_limit_am}` },
                { label: "OM limit",  value: `${form.refund_limit_om}` },
              ]}/>
            ) : (
              <div className="row" style={{ gap: 16 }}>
                <div className="grow" style={{ minWidth: 0 }}><Field label="CM refund limit"><Input type="number" value={String(form.refund_limit_cm)} onChange={v => set("refund_limit_cm", Number(v))}/></Field></div>
                <div className="grow" style={{ minWidth: 0 }}><Field label="AM refund limit"><Input type="number" value={String(form.refund_limit_am)} onChange={v => set("refund_limit_am", Number(v))}/></Field></div>
                <div className="grow" style={{ minWidth: 0 }}><Field label="OM refund limit"><Input type="number" value={String(form.refund_limit_om)} onChange={v => set("refund_limit_om", Number(v))}/></Field></div>
              </div>
            )}
          </FormSection>

          {/* Bottom save row */}
          <div className="row jc-e" style={{ gap: 8 }}>
            <Btn variant="secondary" onClick={() => _go(backTarget, backPayload)}>Cancel</Btn>
            <Btn variant="primary" icon={<span style={{ color: "var(--lime)" }}>{Ic.check(16)}</span>}
              onClick={saveAndReturn}>
              {isNew ? "Create country" : "Save changes"}
            </Btn>
          </div>
      </>

      {/* Policy editor modal */}
      <PolicyEditorModal
        open={!!policyEditorOpen}
        title={policyEditorOpen ? POLICY_LABELS[policyEditorOpen] : ""}
        template={policyEditorOpen ? HQ_TEMPLATES[policyEditorOpen] : ""}
        value={policyEditorOpen ? (policyContent[policyEditorOpen] || "") : ""}
        onChange={v => policyEditorOpen && setPolicyContent(c => ({ ...c, [policyEditorOpen]: v }))}
        onSave={() => { setPolicyEditorOpen(null); }}
        onCancel={() => setPolicyEditorOpen(null)}
      />

      <Toast message={savedToast ? `${form.country_name || "Country"} saved.` : ""} show={savedToast}/>
    </div>
  );
}

// ──────────────────────────────────────────────────────────
/**
 * @spec GA-022b — Country feature-flag matrix (standalone cross-country GA tool)
 * US-002. Country × flag matrix; wallet_enabled is SG-only. 03-ui §2 Table 4.
 */
function CountryFlags({ role = "GA" }) {
  const [group, setGroup]     = useState("all");
  const [values, setValues]   = useState(SB2_FLAG_VALUES);
  const [savedToast, setSavedToast] = useState(false);

  const visibleFlags = SB2_FLAG_DEFS.filter(f => group === "all" || f.group === group);
  // Only the 4 optional flags are toggleable. Compulsory flags lock ON everywhere (locked: [] →
  // FlagMatrix locks every cell, value stays true); Wallet locks to SG. (OQ-072)
  const flagsForMatrix = visibleFlags.map(f => ({ key: f.key, label: f.label, locked: f.optional ? undefined : (f.lockedTo || []) }));
  const rowsForMatrix  = SB2_COUNTRIES.map(c => ({ key: c.country_id, label: `${c.flag} ${c.country_name}` }));

  const onToggle = (countryId, flagKey, next) => {
    setValues(v => ({ ...v, [countryId]: { ...v[countryId], [flagKey]: next } }));
  };

  if (role !== "GA") return <EmptyState icon={null} title="Not authorised" body="Feature flags are available to Global Admins only."/>;

  return (
    <div className="page-inner">
      <PageHead title="Country feature flags"
        actions={<Btn variant="primary"
          icon={<span style={{ color: "var(--lime)" }}>{Ic.check(16)}</span>}
          onClick={() => { setSavedToast(true); setTimeout(() => setSavedToast(false), 2200); }}>
          Publish changes
        </Btn>}
      />

      <InlineAlert kind="info">
        <strong>Only Gifts, Rewards, Promotions and Partnerships are per-country.</strong> All other capabilities are compulsory — always on for every market (shown locked). <strong>Wallet</strong> is locked to Singapore (Phase 2 SG-only).
      </InlineAlert>

      <Tabs
        tabs={SB2_FLAG_GROUPS.map(g => ({
          id: g.id, label: g.label,
          count: g.id === "all" ? SB2_FLAG_DEFS.length : SB2_FLAG_DEFS.filter(f => f.group === g.id).length,
        }))}
        active={group}
        onChange={setGroup}
      />

      <FlagMatrix
        flags={flagsForMatrix}
        rows={rowsForMatrix}
        values={values}
        onToggle={onToggle}
      />

      <InlineAlert kind="info">
        Flag evaluation is server-side per session. Toggling a flag invalidates cache globally within ~60 seconds.
      </InlineAlert>

      <Toast message="Feature flags published." show={savedToast}/>
    </div>
  );
}

// ──────────────────────────────────────────────────────────
/**
 * @spec GA-024 — Country Setup Wizard
 * 6-step: Country · Integration · Country Manager · Features · Policies · Review.
 */
function CountrySetupWizard({ role = "GA" }) {
  if (role !== "GA") return _notAuthorised;

  const TZ_BY_COUNTRY = { SG: "Asia/Singapore", PH: "Asia/Manila", ID: "Asia/Jakarta", TH: "Asia/Bangkok", MY: "Asia/Kuala_Lumpur", VN: "Asia/Ho_Chi_Minh", JP: "Asia/Tokyo", AU: "Australia/Sydney", NZ: "Pacific/Auckland" };
  const COUNTRY_OPTIONS = [
    { code: "PH", name: "Philippines", flag: "🇵🇭" }, { code: "ID", name: "Indonesia", flag: "🇮🇩" },
    { code: "TH", name: "Thailand",    flag: "🇹🇭" }, { code: "MY", name: "Malaysia",  flag: "🇲🇾" },
    { code: "VN", name: "Vietnam",     flag: "🇻🇳" }, { code: "AU", name: "Australia", flag: "🇦🇺" },
    { code: "JP", name: "Japan",       flag: "🇯🇵" }, { code: "NZ", name: "New Zealand", flag: "🇳🇿" },
  ];

  const [step, setStep]   = useState(1);
  const [countrySearch, setCountrySearch] = useState("");
  const [form, setForm]   = useState({
    country_id: "", country_name: "", flag: "", timezone: "",
    // step 3 — CM (create-inline name+email; empty = assign later)
    cm_name: "", cm_email: "",
    // step 4 — flags (init from defaults; toggled in step)
    flags: Object.fromEntries(SB2_FLAG_DEFS.map(f => [f.key, false])),
    // step 5 — policies
    policy_mode:    { refund: "hq", cancellation: "hq", pickup: "hq" },
    policy_content: { refund: "", cancellation: "", pickup: "" },
    // Wizard starts with no country selected; fallback to canonical defaults (5000/2000/500).
    // Once a country is chosen in step 1, the GA may override these in step 5.
    refund_limit_cm: 5000, refund_limit_am: 2000, refund_limit_om: 500,
  });
  const [policyEditorOpen, setPolicyEditorOpen] = useState(null);
  const [toast, setToast] = useState(null);
  const set = (k, v) => setForm(f => ({ ...f, [k]: v }));

  const intData = _getIntegrations(form.country_id);

  const STEPS = [
    { id: 1, label: "Country" },
    { id: 2, label: "Integration" },
    { id: 3, label: "Country Manager" },
    { id: 4, label: "Features" },
    { id: 5, label: "Policies" },
    { id: 6, label: "Review" },
  ];

  const stepValid = (() => {
    if (step === 1) return !!(form.country_id && form.country_name);
    // Step 3 (Country Manager) is skippable — always valid (convention 11).
    return true;
  })();

  const next = () => stepValid && setStep(s => Math.min(6, s + 1));
  const prev = () => setStep(s => Math.max(1, s - 1));

  const POLICY_LABELS = { refund: "Refund policy", cancellation: "Cancellation policy", pickup: "Pickup / collection policy" };
  const HQ_TEMPLATES  = {
    refund: "Customers may request a refund within 24 hours of purchase.",
    cancellation: "Orders may be cancelled within 5 minutes of placement.",
    pickup: "Orders must be collected within 30 minutes of the ready notification.",
  };

  const Stepper = () => (
    <div className="row ai-c" style={{ gap: 4, flexWrap: "wrap", padding: "16px 4px" }}>
      {STEPS.map((s, i) => {
        const state = s.id < step ? "done" : s.id === step ? "active" : "todo";
        const bg  = state === "done" ? "var(--forest)" : state === "active" ? "var(--lime)" : "transparent";
        const fg  = state === "done" ? "var(--lime)"   : state === "active" ? "var(--forest)" : "var(--ink-2)";
        const bdr = state === "done" ? "var(--forest)" : state === "active" ? "var(--forest)" : "rgba(0,106,86,.2)";
        return (
          <React.Fragment key={s.id}>
            <button onClick={() => s.id < step && setStep(s.id)} disabled={s.id >= step} style={{
              display: "inline-flex", alignItems: "center", gap: 6, padding: "6px 12px",
              borderRadius: "var(--r-pill)", border: `1.5px solid ${bdr}`, background: bg, color: fg,
              font: "600 13px/1 var(--font-ui)", cursor: s.id < step ? "pointer" : "default",
            }}>
              <span style={{ font: "700 12px/1 var(--font-ui)" }}>{s.id}</span>
              <span>{s.label}</span>
            </button>
            {i < STEPS.length - 1 && <span style={{ width: 16, height: 2, background: "rgba(0,106,86,.2)" }}/>}
          </React.Fragment>
        );
      })}
    </div>
  );

  const StepHeader = ({ n, label }) => (
    <div className="row ai-c" style={{ gap: 8, marginBottom: 16 }}>
      <span style={{ display: "inline-flex", alignItems: "center", justifyContent: "center", width: 28, height: 28, borderRadius: "var(--r-pill)", background: "var(--forest)", color: "var(--lime)", font: "700 13px/1 var(--font-ui)" }}>{n}</span>
      <span style={{ font: "700 18px/1.2 var(--font)", color: "var(--forest)" }}>{label}</span>
    </div>
  );

  const filteredCountries = COUNTRY_OPTIONS.filter(c =>
    !countrySearch || c.name.toLowerCase().includes(countrySearch.toLowerCase()) || c.code.toLowerCase().includes(countrySearch.toLowerCase())
  );

  return (
    <div className="page-inner">
      <PageHead title="New country setup"
        back={{ label: "Countries", onClick: () => _go("ga-countries") }}/>

      <Stepper/>

      <Card>
        {/* STEP 1 — Country */}
        {step === 1 && (
          <>
            <StepHeader n={1} label="Country"/>
            <Field label="Search country" hint="Select a country to auto-fill code, flag, and timezone.">
              <Input value={countrySearch} onChange={setCountrySearch} placeholder="Type a country name…"/>
            </Field>
            <div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fill, minmax(180px, 1fr))", gap: 10, marginTop: 12 }}>
              {filteredCountries.map(c => {
                const sel = form.country_id === c.code;
                return (
                  <button key={c.code}
                    onClick={() => { setForm(f => ({ ...f, country_id: c.code, country_name: c.name, flag: c.flag, timezone: TZ_BY_COUNTRY[c.code] || "" })); setCountrySearch(""); }}
                    style={{ textAlign: "left", padding: "12px 14px", borderRadius: "var(--r)", border: `2px solid ${sel ? "var(--forest)" : "var(--line)"}`, background: sel ? "var(--mint-soft)" : "var(--white)", cursor: "pointer", display: "flex", flexDirection: "column", gap: 4 }}>
                    <span style={{ fontSize: 22 }}>{c.flag}</span>
                    <span style={{ ...T.primary(1.2) }}>{c.name}</span>
                    <span style={{ ...T_MUTED, fontSize: 12 }}>{c.code}</span>
                  </button>
                );
              })}
            </div>
            {form.country_id && (
              <div style={{ display: "grid", gridTemplateColumns: "repeat(3, minmax(0,1fr))", gap: 12, marginTop: 16 }}>
                <Field label="Country code"><Input value={form.country_id} onChange={() => {}} disabled/></Field>
                <Field label="Flag"><Input value={form.flag} onChange={() => {}} disabled/></Field>
                <Field label="Timezone"><Input value={form.timezone || "Auto"} onChange={() => {}} disabled/></Field>
              </div>
            )}
          </>
        )}

        {/* STEP 2 — Integration */}
        {step === 2 && (
          <>
            <StepHeader n={2} label="Integration"/>
            <InlineAlert kind="warn">
              POS and Payment Gateways available for {form.country_name || "this country"}. Select which DX will configure. You can continue without selecting and integrate later.
            </InlineAlert>
            <div className="row" style={{ gap: 16, marginTop: 16 }}>
              <div className="grow">
                <Field label="POS provider">
                  <Select value={form.pos_provider || ""} onChange={v => set("pos_provider", v)} placeholder="Choose POS (or integrate later)">
                    {(intData.pos.length ? intData.pos : SB_POS_PROVIDERS).map(p => <option key={p.id} value={p.id}>{p.label}</option>)}
                    <option value="later">Integrate later</option>
                  </Select>
                </Field>
              </div>
              <div className="grow">
                <Field label="Payment gateway">
                  <Select value={form.payment_provider || ""} onChange={v => set("payment_provider", v)} placeholder="Choose gateway (or integrate later)">
                    {intData.gateway.length ? intData.gateway.map(g => <option key={g.id} value={g.id}>{g.label}</option>) : null}
                    <option value="stripe">Stripe</option>
                    <option value="opn">Opn (formerly Omise)</option>
                    <option value="later">Integrate later</option>
                  </Select>
                </Field>
              </div>
            </div>
          </>
        )}

        {/* STEP 3 — Country Manager (create-inline name+email, skippable — convention 11) */}
        {step === 3 && (
          <>
            <StepHeader n={3} label="Country Manager"/>
            {form.cm_name || form.cm_email ? (
              <div>
                <div style={{ ...T.primary(1.3), marginBottom: 4 }}>{form.cm_name || "—"}</div>
                <div style={{ ...T_MUTED, marginBottom: 12 }}>{form.cm_email || "—"}</div>
                <Btn variant="secondary" size="sm" onClick={() => { set("cm_name", ""); set("cm_email", ""); }}>
                  <LIcon name="X" size={14}/> Clear — assign later
                </Btn>
              </div>
            ) : (
              <ManagerSection
                mode="create"
                roleType="Country Manager"
                eligibleUsers={_eligibleCountryManagers(form.country_id).map(u => ({ id: u.id, full_name: u.full_name, email: u.email }))}
                onAssignExisting={(id) => {
                  const u = _eligibleCountryManagers(form.country_id).find(x => x.id === id);
                  if (u) { set("cm_name", u.full_name); set("cm_email", u.email); }
                }}
                onCreateInline={({ name, email }) => { set("cm_name", name); set("cm_email", email); }}
              />
            )}
          </>
        )}

        {/* STEP 4 — Features */}
        {step === 4 && (
          <>
            <StepHeader n={4} label="Features"/>
            <div style={{ ...T_MUTED, fontSize: 13, marginBottom: 4 }}>Choose the optional features for this market. The rest are always included; Wallet is SG-only.</div>
            <div style={{ display: "grid", gridTemplateColumns: "repeat(2, minmax(0,1fr))", gap: 12 }}>
              {[...SB2_FLAG_DEFS].sort((a, b) => (a.optional ? 0 : 1) - (b.optional ? 0 : 1)).map(f => {
                const st = _flagState(f, form.country_id);
                const value = st.toggleable ? !!form.flags[f.key] : st.forced;
                const note = st.toggleable ? f.note : (f.lockedTo ? f.note : "Always included");
                return (
                  <div key={f.key} className="row ai-c jc-sb" style={{ padding: "10px 12px", border: "1.5px solid var(--line)", borderRadius: "var(--r)", opacity: st.toggleable ? 1 : 0.6 }}>
                    <div>
                      <div style={{ ...T.primary(1.2) }}>{f.label}</div>
                      {note && <div style={{ ...T_MUTED, fontSize: 12, marginTop: 2 }}>{note}</div>}
                    </div>
                    <Toggle on={value} onToggle={() => st.toggleable && setForm(fm => ({ ...fm, flags: { ...fm.flags, [f.key]: !fm.flags[f.key] } }))} disabled={!st.toggleable}/>
                  </div>
                );
              })}
            </div>
          </>
        )}

        {/* STEP 5 — Policies */}
        {step === 5 && (
          <div style={{ display: "flex", flexDirection: "column", gap: 24 }}>
            <StepHeader n={5} label="Policies"/>
            <FormSection title="Legal policies" description="Start from the HQ template; override per country only where required.">
              {Object.keys(POLICY_LABELS).map(key => {
                const isHq = form.policy_mode[key] === "hq";
                return (
                  <div key={key} style={{ borderTop: "1px solid var(--line)", paddingTop: 12 }}>
                    <div className="row ai-c jc-sb">
                      <div style={{ ...T.primary(1.2) }}>{POLICY_LABELS[key]}</div>
                      <Toggle on={isHq} onToggle={() => setForm(fm => ({ ...fm, policy_mode: { ...fm.policy_mode, [key]: isHq ? "custom" : "hq" } }))} label={isHq ? "Use HQ template" : "Custom"}/>
                    </div>
                    {!isHq && (
                      <div style={{ marginTop: 8 }}>
                        <Btn variant="secondary" size="sm" onClick={() => setPolicyEditorOpen(key)}>
                          {form.policy_content[key] ? "Edit policy" : "Write custom policy"}
                        </Btn>
                      </div>
                    )}
                  </div>
                );
              })}
            </FormSection>
            <FormSection title="Refund limits" description="Maximum refund amounts by role.">
              <div style={{ display: "grid", gridTemplateColumns: "repeat(3, minmax(0,1fr))", gap: 16, width: "100%" }}>
                <Field label="CM limit"><Input type="number" value={String(form.refund_limit_cm)} onChange={v => set("refund_limit_cm", Number(v))}/></Field>
                <Field label="AM limit"><Input type="number" value={String(form.refund_limit_am)} onChange={v => set("refund_limit_am", Number(v))}/></Field>
                <Field label="OM limit"><Input type="number" value={String(form.refund_limit_om)} onChange={v => set("refund_limit_om", Number(v))}/></Field>
              </div>
            </FormSection>
          </div>
        )}

        {/* STEP 6 — Review */}
        {step === 6 && (
          <div style={{ display: "flex", flexDirection: "column", gap: 24 }}>
            <StepHeader n={6} label="Review"/>
            <FormSection title="Country">
              <KeyValueGrid columns={2} items={[
                { label: "Country", value: `${form.flag} ${form.country_name} · ${form.country_id}` },
                { label: "Timezone", value: form.timezone || "—" },
              ]}/>
            </FormSection>
            <FormSection title="Integration">
              <KeyValueGrid columns={2} items={[
                { label: "POS provider",    value: form.pos_provider || "Integrate later" },
                { label: "Payment gateway", value: form.payment_provider || "Integrate later" },
              ]}/>
            </FormSection>
            <FormSection title="Country Manager">
              <KeyValueGrid columns={1} items={[
                { label: "Country Manager", value: form.cm_name ? `${form.cm_name} (${form.cm_email})` : "Assign later" },
              ]}/>
            </FormSection>
            <FormSection title="Features">
              <KeyValueGrid columns={1} items={[
                { label: "Features enabled", value: (() => { const rf = _resolveFlags(form.flags, form.country_id); return SB2_FLAG_DEFS.filter(f => rf[f.key]).map(f => f.label).join(", ") || "None"; })() },
              ]}/>
            </FormSection>
            <FormSection title="Policies">
              <KeyValueGrid columns={2} items={[
                { label: "Refund policy",       value: form.policy_mode.refund       === "hq" ? "HQ template" : "Custom" },
                { label: "Cancellation policy", value: form.policy_mode.cancellation === "hq" ? "HQ template" : "Custom" },
                { label: "Pickup policy",       value: form.policy_mode.pickup       === "hq" ? "HQ template" : "Custom" },
                { label: "Refund limits",       value: `CM ${form.refund_limit_cm} · AM ${form.refund_limit_am} · OM ${form.refund_limit_om}` },
              ]}/>
            </FormSection>
          </div>
        )}
      </Card>

      <PolicyEditorModal
        open={!!policyEditorOpen}
        title={policyEditorOpen ? POLICY_LABELS[policyEditorOpen] : ""}
        template={policyEditorOpen ? HQ_TEMPLATES[policyEditorOpen] : ""}
        value={policyEditorOpen ? (form.policy_content[policyEditorOpen] || "") : ""}
        onChange={v => policyEditorOpen && setForm(fm => ({ ...fm, policy_content: { ...fm.policy_content, [policyEditorOpen]: v } }))}
        onSave={() => setPolicyEditorOpen(null)}
        onCancel={() => setPolicyEditorOpen(null)}
      />

      <div className="row jc-sb" style={{ gap: 8 }}>
        <Btn variant="secondary" onClick={prev} disabled={step === 1}>Back</Btn>
        <div className="row" style={{ gap: 8 }}>
          <Btn variant="secondary" onClick={() => _go("ga-countries")}>Cancel</Btn>
          {step < 6 ? (
            <Btn variant="primary" onClick={next} disabled={!stepValid}>Next</Btn>
          ) : (
            <Btn variant="primary" onClick={() => {
              setToast(`${form.country_name} created in draft.`);
              setTimeout(() => _go("ga-country-detail", { id: form.country_id }), 1200);
            }}>Create country</Btn>
          )}
        </div>
      </div>
      <Toast message={toast || ""} show={!!toast}/>
    </div>
  );
}

Object.assign(window, { CountriesList, CountryDetail, CountryEdit, CountryFlags, CountrySetupWizard });
})();
