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

// Area status: SB3_AREAS has no `status` field yet (other-pages adds it). Default "active"
// so the StatusPill / filter resolve until the mock + STATUS_TONES.area land.
const _areaStatus = (a) => (a && a.status) || "active";

// Area Manager = User reverse-lookup (convention 11). The AM is the User with
// role_type "area_manager" whose area_id scope equals this area — NEVER a field on the area.
const _areaManager = (areaId) =>
  SB3_USERS.find(u => u.role_type === "area_manager" && u.area_id === areaId) || null;
// Eligible AMs for assign/edit: area_manager users scoped to this area's country.
const _eligibleAreaManagers = (countryId) =>
  SB3_USERS.filter(u => u.role_type === "area_manager" && u.country_id === countryId);

// CM/AM mock home country (CM lists own-country areas; AM lands on own area).
const _AREAS_CM_COUNTRY = "PH";
const _AREAS_AM_AREA_ID = "ar_03";

// ──────────────────────────────────────────────────────────
/**
 * @spec B-16 — Areas list
 * GA sees all areas (+ GeoScope country-only); CM sees own-country areas (no GeoScope);
 * AM lands on own area detail (read-only); OM has no access. 03-ui §2 Table 1.
 */
function AreasList({ role = "GA" }) {
  const [status, setStatus]           = useState("");
  const [geo, setGeo]                 = useState({ countries: [] });
  const [searchQuery, setSearchQuery] = useState("");
  const [page, setPage]               = useState(1);
  const [pageSize, setPageSize]       = useState(20);

  const isGA = role === "GA";

  // Derived rows: precompute outlet-count + AM name so sortable columns read plain values.
  const rows = useMemo(() => {
    if (role !== "GA" && role !== "CM") return [];
    const q = searchQuery.trim().toLowerCase();
    const scopedCountries = isGA ? (geo.countries || []) : [_AREAS_CM_COUNTRY];
    return SB3_AREAS
      .filter(a => isGA ? true : a.country_id === _AREAS_CM_COUNTRY)
      .filter(a => isGA && scopedCountries.length ? scopedCountries.includes(a.country_id) : true)
      .filter(a => !status || _areaStatus(a) === status)
      .filter(a => !q || a.name.toLowerCase().includes(q))
      .map(a => {
        const am = _areaManager(a.id);
        return {
          ...a,
          status:       _areaStatus(a),
          outlet_count: SB3_OUTLETS.filter(o => o.area_id === a.id).length,
          am_name:      am ? am.full_name : "—",
          franchisee:   _franchiseeLabel(a.franchise_id),
        };
      });
  }, [role, isGA, status, geo, searchQuery]);

  // AM → own area detail (read-only). OM → not authorised.
  if (role === "AM") return <AreaDetail role="AM"/>;
  if (role !== "GA" && role !== "CM") return _notAuthorised;

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

  const statusOptions = [
    { value: "", label: "All statuses" },
    { value: "draft",    label: "Draft" },
    { value: "active",   label: "Active" },
    { value: "inactive", label: "Inactive" },
  ];

  // GA columns: flag · ★name · franchisee · outlet-count · AM · status.
  // CM columns: ★name · outlet-count · AM · status (no flag/franchisee — single country).
  const columns = [
    ...(isGA ? [{ label: "", width: 40, render: r => <span style={{ fontSize: 20 }}>{(SB2_COUNTRY_BY_ID[r.country_id] || {}).flag}</span> }] : []),
    { label: "Area", sortable: true, sortKey: "name", render: r => (
      <span style={{ ...T.primary(1) }}>{r.name}</span>
    )},
    ...(isGA ? [{ label: "Franchisee", width: 140, sortable: true, sortKey: "franchisee", render: r => <span style={{ ...T_MUTED }}>{r.franchisee}</span> }] : []),
    { label: "Outlets", width: 76, sortable: true, sortKey: "outlet_count", render: r => <span style={{ ...T_MUTED }}>{r.outlet_count}</span> },
    { label: "Area Manager", width: 140, sortable: true, sortKey: "am_name", render: r => <span style={{ ...T_MUTED }}>{r.am_name}</span> },
    { label: "Status", width: 110, sortable: true, sortKey: "status", render: r => <StatusPill status={r.status} kind="area"/> },
    { label: "", width: 44, render: () => <span style={{ color: "var(--forest)" }}>{Ic.chevR(16)}</span> },
  ];

  return (
    <div className="page-inner">
      <PageHead
        title={isGA ? "Areas" : "My Areas"}
        description={isGA ? "Operational areas across the network." : "Operational areas in your country."}
        actions={<Btn variant="primary" onClick={() => _go(`${role.toLowerCase()}-area-edit`)}>New area</Btn>}
      />

      <FilterBar
        primaryFilter={{ key: "status", label: "Status", options: statusOptions }}
        primaryValue={status}
        onPrimaryChange={setStatus}
        advancedFilters={isGA ? [
          { key: "geo", kind: "geoscope", label: "Network scope", role: "GA",
            countries: SB2_COUNTRIES.map(c => ({ value: c.country_id, label: `${c.flag} ${c.country_name}` })) },
        ] : []}
        advancedValues={isGA ? { geo } : {}}
        onAdvancedChange={(k, v) => { if (k === "geo") setGeo(v); }}
        onAdvancedReset={() => setGeo({ countries: [] })}
        onReset={() => { setStatus(""); setGeo({ countries: [] }); setSearchQuery(""); }}
        search={searchQuery}
        onSearch={setSearchQuery}
        searchPlaceholder="Search areas…"
      />

      <Table
        columns={columns}
        rows={visibleRows}
        onRow={r => _go(`${role.toLowerCase()}-area-detail`, { id: r.id })}
        emptyText="No areas match the current filter."
      />

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

// ──────────────────────────────────────────────────────────
/**
 * @spec B-16 — Area detail (full-page, tabs; read-only by default)
 * GA = Overview · Performance · Settings (+Edit). CM = Overview · Performance (+Edit; no Settings).
 * AM = Overview only (read-only; no Edit / Performance / Settings). 03-ui §2 Table 2.
 */
function AreaDetail({ role = "GA" }) {
  const payloadId  = typeof window !== "undefined" && window.__sixhands_route_payload ? window.__sixhands_route_payload.id : null;
  const effectiveId = payloadId || (role === "AM" ? _AREAS_AM_AREA_ID : null);
  const area = (effectiveId && SB3_AREA_BY_ID[effectiveId]) || SB3_AREAS[0];
  const aid  = area.id;
  const cid  = area.country_id;
  const country = SB2_COUNTRY_BY_ID[cid] || {};
  const isGA = role === "GA";
  const isAM = role === "AM";
  const status = _areaStatus(area);

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

  const [tab, setTab]               = useState("overview");
  const [toast, setToast]           = useState(null);

  const areaManager = _areaManager(aid);  // User reverse-lookup; never an area field (convention 11).
  const outletCount = SB3_OUTLETS.filter(o => o.area_id === aid).length;
  const filterPayload = { filter: { area_id: aid, label: area.name } };

  const backLabel = isAM ? null : (isGA ? "Areas" : "Areas");
  const pageTitle = isAM ? "My Area" : `${area.name} · Area`;
  const pageDesc  = isAM ? "Your area's configuration." : "Operational area configuration.";

  // ── OVERVIEW: full read-only Identity + Manager + Related. ──
  const overview = (
    <>
      <FormSection title="Identity">
        <KeyValueGrid columns={2} items={[
          { label: "Area",       value: area.name },
          { label: "Country",    value: `${country.flag || ""} ${country.country_name || cid}`.trim() },
          { label: "Franchisee", value: _franchiseeLabel(area.franchise_id) },
        ]}/>
      </FormSection>
      <FormSection title="Area Manager" description="The AM is a User scoped to this area. Read-only here; assign via the form.">
        <ManagerSection
          manager={areaManager}
          mode="read"
          roleType="Area Manager"
          onAddCta={!isAM ? () => _go(`${role.toLowerCase()}-area-edit`, { id: aid }) : undefined}
        />
      </FormSection>
      <FormSection title="Related" description="Open the records that belong to this area.">
        <div className="stat-panel stat-panel-snapshot">
          <div className="stat-panel-grid">
            <StatCard label="Outlets" value={outletCount} sub="View outlets in this area"
              icon={<LIcon name="Store" size={16}/>}
              onClick={() => _go(`${role.toLowerCase()}-outlets`, filterPayload)}/>
          </div>
        </div>
      </FormSection>
    </>
  );

  // ── PERFORMANCE (GA/CM only): reuse the scoped dashboard. Passing area_id forces the area view. ──
  const performance = <PerformanceDashboardContent scope={{ area_id: aid }} role={role}/>;

  return (
    <div className="page-inner">
      <PageHead
        title={pageTitle}
        description={pageDesc}
        status={<StatusPill status={status} kind="area"/>}
        back={backLabel ? { label: backLabel, onClick: () => _go(`${role.toLowerCase()}-areas`) } : undefined}
        actions={!isAM ? <Btn variant="primary" onClick={() => _go(`${role.toLowerCase()}-area-edit`, { id: aid })}>Edit</Btn> : undefined}
      />

      {detailTabs.length > 1 && <Tabs tabs={detailTabs} active={tab} onChange={setTab}/>}

      {tab === "overview" && overview}
      {!isAM && tab === "performance" && performance}
      {isGA && tab === "settings" && (
        <>
          <InlineAlert kind="info">
            Set this area's status (<strong>draft, active ⇄ inactive</strong>) from <strong>Edit</strong>.
          </InlineAlert>
          <DeleteSection
            entityLabel="area"
            soft={status !== "draft"}
            note={status === "draft"
              ? "Permanently delete this draft area. Nothing is live yet. Blocked if it already has outlets."
              : "Decommission this area (soft-delete). Retained + reversible by support. GA-only, and blocked while it has outlets."}
            gate={_canDelete(role, { status, isReferenced: outletCount > 0 })}
            confirmBody={status === "draft"
              ? <div>Permanently delete the draft area <strong>{area.name}</strong>? Writes to <strong>audit_logs</strong>.</div>
              : <div>Decommissioning <strong>{area.name}</strong> hides it from new assignments. Data + audit retained. Writes to <strong>audit_logs</strong>.</div>}
            onDelete={() => {
              setToast(`${area.name} ${status === "draft" ? "deleted" : "decommissioned"}.`);
              setTimeout(() => { setToast(null); _go(`${role.toLowerCase()}-areas`); }, 1400);
            }}
          />
        </>
      )}

      <Toast message={toast || ""} show={!!toast}/>
    </div>
  );
}

// ──────────────────────────────────────────────────────────
/**
 * @spec B-16 — Area create / edit (one inline page; GA + CM only)
 * Sections mirror tabs: Identity · Manager · Status. Cancel/Save at top AND bottom.
 * Manager write is additive (User.area_id) — non-destructive. 03-ui §2 Table 3.
 */
function AreaEdit({ role = "GA" }) {
  if (role !== "GA" && role !== "CM") return _notAuthorised;
  const payloadId   = typeof window !== "undefined" && window.__sixhands_route_payload ? window.__sixhands_route_payload.id : null;
  const existing    = payloadId ? SB3_AREA_BY_ID[payloadId] : null;
  const isNew       = !existing;

  const initial = existing || {
    id: "", name: "", country_id: role === "CM" ? _AREAS_CM_COUNTRY : "", franchise_id: "", status: "draft",
  };

  const [form, setForm] = useState({
    name:         initial.name,
    country_id:   initial.country_id,
    franchise_id: initial.franchise_id,
    status:       _areaStatus(initial),
  });
  const set = (k, v) => setForm(f => ({ ...f, [k]: v }));

  const [toast, setToast] = useState(false);

  // Franchisees filtered to the selected country.
  const franchiseeOptions = SB3_FRANCHISEES.filter(f => !form.country_id || f.country_id === form.country_id);
  const eligibleAMs = form.country_id
    ? _eligibleAreaManagers(form.country_id).map(u => ({ id: u.id, full_name: u.full_name, email: u.email }))
    : [];
  const assignedAM = existing ? _areaManager(existing.id) : null;

  const backTarget  = isNew ? `${role.toLowerCase()}-areas` : `${role.toLowerCase()}-area-detail`;
  const backPayload = isNew ? undefined : { id: existing.id };
  const pageTitle   = isNew ? "New area" : `${form.name || "Area"} · Edit`;

  const saveAndReturn = () => {
    setToast(true);
    setTimeout(() => _go(backTarget, backPayload), 1100);
  };

  const SaveRow = ({ bottom }) => (
    <div className={`row ${bottom ? "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 area" : "Save changes"}
      </Btn>
    </div>
  );

  return (
    <div className="page-inner">
      <PageHead
        title={pageTitle}
        description="Operational area configuration."
        status={!isNew ? <StatusPill status={form.status} kind="area"/> : undefined}
        back={{ label: isNew ? "Areas" : `${form.name || "Area"} · Area`, 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 area" : "Save changes"}
          </Btn>
        </>}
      />

      {/* Identity */}
      <FormSection title="Identity" description="Country is fixed once the area is created.">
        <div className="row" style={{ gap: 16 }}>
          <div className="grow">
            <Field label="Area name">
              <Input value={form.name} onChange={v => set("name", v)} placeholder="e.g. Metro Manila"/>
            </Field>
          </div>
          <div style={{ width: 200 }}>
            <Field label="Country">
              <Select value={form.country_id} onChange={v => { set("country_id", v); set("franchise_id", ""); }} disabled={!isNew || role === "CM"} placeholder="Choose country">
                {SB2_COUNTRIES.map(c => <option key={c.country_id} value={c.country_id}>{c.flag} {c.country_name}</option>)}
              </Select>
            </Field>
          </div>
        </div>
        <div style={{ marginTop: 12 }}>
          <Field label="Franchisee">
            <Select value={form.franchise_id} onChange={v => set("franchise_id", v)} placeholder="Choose franchisee">
              {franchiseeOptions.map(f => <option key={f.id} value={f.id}>{f.display_name}</option>)}
            </Select>
          </Field>
        </div>
      </FormSection>

      {/* Manager — create = SegToggle (Choose-user / Quick-add); edit = Choose-user only (convention 11). */}
      <FormSection title="Area Manager" description={isNew ? "Choose an existing user or quick-add one — or assign later." : "Reassign to an existing eligible user."}>
        {assignedAM && (
          <div style={{ marginBottom: 12 }}>
            <ManagerSection manager={assignedAM} mode="read" roleType="Area Manager"/>
          </div>
        )}
        <ManagerSection
          mode={isNew ? "create" : "edit"}
          roleType="Area Manager"
          eligibleUsers={eligibleAMs}
          onAssignExisting={(id) => {}}
          onCreateInline={isNew ? ({ name, email }) => {} : undefined}
        />
      </FormSection>

      {/* Status — draft → active ⇄ inactive (no go-live gate for areas) */}
      <FormSection title="Status" description="Draft areas are being set up. Active areas are available for outlet + manager assignment; inactive areas are hidden from new assignments. Once active, an area toggles active ⇄ inactive and cannot return to draft.">
        <div style={{ width: 240 }}>
          <Field label="Status">
            <Select value={form.status} onChange={v => set("status", v)}>
              {form.status === "draft" && <option value="draft">Draft</option>}
              <option value="active">Active</option>
              <option value="inactive">Inactive</option>
            </Select>
          </Field>
        </div>
      </FormSection>

      {/* Bottom save row */}
      <SaveRow bottom/>

      <Toast message={toast ? `${form.name || "Area"} saved.` : ""} show={toast}/>
    </div>
  );
}

Object.assign(window, { AreasList, AreaDetail, AreaEdit });
})();
