/* page-partnerships.jsx — Partnerships module (03-ui §2). IIFE-scoped; exports via window. */
/* PO 2026-06-05: multi-select + BulkBar removed; approval/status transitions via edit-mode only;
   Export relocated to PageHead (GA); per-row GA Delete via drawer danger button + ConfirmModal. */
(function(){
const { useState, useMemo } = React;

// Country flag + label map (matches SB2_COUNTRIES ids)
const COUNTRY_OPTS = [
  { value: "PH", label: "🇵🇭 Philippines" },
  { value: "SG", label: "🇸🇬 Singapore" },
  { value: "ID", label: "🇮🇩 Indonesia" },
  { value: "TH", label: "🇹🇭 Thailand" },
];
const COUNTRY_LABEL = Object.fromEntries(COUNTRY_OPTS.map(c => [c.value, c.label]));

const APPROVAL_STATUS_OPTS = [
  { value: "",         label: "All statuses"  },
  { value: "draft",    label: "Draft"         },
  { value: "pending",  label: "Pending"       },
  { value: "approved", label: "Approved"      },
  { value: "rejected", label: "Rejected"      },
];
const STATUS_OPTS = [
  { value: "",         label: "All"      },
  { value: "active",   label: "Active"   },
  { value: "inactive", label: "Inactive" },
];

// Acting operator per role tier (drives RemarksSection own-remark gate).
const CURRENT_USER = {
  GA: { id: "u_ga_01", name: "Ju Hu" },
  CM: { id: "u_cm_ph", name: "Maria Santos" },
  AM: { id: "u_am_ph", name: "Rafael Cruz" },
  OM: { id: "u_om_ph", name: "Ana Reyes" },
};

// Operators read product language, not internal enums/ids (prototype-standards §13).
const APPROVAL_LABEL = { draft: "Draft", pending: "Pending", approved: "Approved", rejected: "Rejected" };
const _partnerApprovalLabel = s => APPROVAL_LABEL[s] || s || "—";
const _partnerUserName = id => {
  if (!id) return "—";
  const u = (typeof SB3_USERS !== "undefined" ? SB3_USERS : []).find(x => x.id === id);
  return u ? u.full_name : id;
};

// ──────────────────────────────────────────────────────────────────────────────
/**
 * @spec 03-ui §Partnerships (Tables 1–2) · 02-rbac §3 — Partnerships list (GA/CM author; AM/OM read-only)
 */
function PartnershipsList({ role = "GA" }) {
  if (!["GA", "CM", "AM", "OM"].includes(role)) return _notAuthorised;

  const isGA  = role === "GA";
  const isCM  = role === "CM";
  const isAM  = role === "AM";
  const isOM  = role === "OM";
  const canAuthor = isGA || isCM;

  // ── state ──
  // Mutable brands store — drawer create/edit applies drafts here so the read view
  // re-derives live (SB4_BRANDS is the immutable canonical seed). Mirrors Customers.
  const [brands, setBrands]           = useState(() => SB4_BRANDS.map(b => ({ ...b })));
  const [searchQuery, setSearchQuery] = useState("");
  const [filters, setFilters]         = useState({});
  const [advFilters, setAdvFilters]   = useState({});
  const [page, setPage]               = useState(1);
  const [pageSize, setPageSize]       = useState(20);
  const [drawerFor, setDrawerFor]     = useState(null);
  const [mode, setMode]               = useState("read"); // read | edit | create
  const [draft, setDraft]             = useState(null);
  const [toast, setToast]             = useState(null);
  const [confirmDelete, setConfirmDelete] = useState(false);

  const fireToast = (msg) => { setToast(msg); setTimeout(() => setToast(null), 2400); };

  // ── row scope ──
  const allBrands = useMemo(() => {
    if (isGA)  return brands;
    if (isCM)  return brands.filter(b => b.country_id === "PH" || b.country_id === null
                       ? (b.approval_status === "pending" || b.approval_status === "draft" || b.approval_status === "approved" || b.approval_status === "rejected")
                       : false)
                    .filter(b => b.country_id === "PH" || (b.country_id === null && b.approval_status === "approved"));
    if (isAM)  return brands.filter(b => b.approval_status === "approved");
    /* OM */   return brands.filter(b => b.approval_status === "approved");
  }, [role, brands]);

  // ── filtering ──
  const rows = useMemo(() => {
    let r = allBrands;
    if (searchQuery) {
      const q = searchQuery.toLowerCase();
      r = r.filter(b => b.name.toLowerCase().includes(q) || (b.city || "").toLowerCase().includes(q));
    }
    if (isOM) {
      if (filters.status) r = r.filter(b => b.status === filters.status);
    } else {
      if (filters.approval_status) r = r.filter(b => b.approval_status === filters.approval_status);
      if (filters.status)          r = r.filter(b => b.status === filters.status);
    }
    if (isGA && advFilters.country) {
      r = r.filter(b => advFilters.country === "global" ? b.country_id === null : b.country_id === advFilters.country);
    }
    return r;
  }, [allBrands, searchQuery, filters, advFilters, role]);

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

  // ── drawer record (live, derived by id) + mode helpers ──
  const drawerRow = drawerFor ? brands.find(b => b.id === drawerFor) : null;
  const isCreate  = mode === "create";
  const isEdit    = mode === "edit";
  const isForm    = isEdit || isCreate;

  const openRead   = (row) => { setDrawerFor(row.id); setMode("read"); setDraft(null); };
  const closeDrawer = () => { setDrawerFor(null); setMode("read"); setDraft(null); };
  const startEdit  = () => { setDraft({ ...drawerRow }); setMode("edit"); };
  const startCreate = () => {
    setDrawerFor(null);
    setDraft({
      id: null, name: "", logo_url: "", street_address: "", city: "", postal_code: "",
      hours_text: "", phone_country_code: "+63", phone_number: "",
      country_id: isCM ? "PH" : null,
      approval_status: "draft", status: "inactive",
      submitted_by_user_id: null, approved_by: null, approved_at: null, rejection_reason: null,
    });
    setMode("create");
  };
  const setD = (k, v) => setDraft(d => ({ ...d, [k]: v }));

  // ── save (create / edit) — applies draft to the brands store, stays mounted ──
  // CM saves on a draft/rejected row resubmit → approval_status='pending'.
  const cmResubmits = isCM && draft && (draft.approval_status === "draft" || draft.approval_status === "rejected");
  const rejectionRequired = isGA && draft && draft.approval_status === "rejected" && !(draft.rejection_reason || "").trim();
  const saveLabel = isCreate
    ? (isGA ? "Create" : "Submit for approval")
    : (cmResubmits ? "Submit for approval" : "Save");

  const saveForm = () => {
    if (rejectionRequired) return;
    const rec = { ...draft };
    if (isCM) rec.approval_status = cmResubmits ? "pending" : rec.approval_status;
    if (isGA && rec.approval_status === "approved" && !rec.approved_by) {
      rec.approved_by = "u_ga_01";
      rec.approved_at = rec.approved_at || new Date().toISOString().slice(0, 10);
    }

    if (isCreate) {
      const id = `brand_NEW_${Date.now()}`;
      const created = { ...rec, id, created_at: new Date().toISOString().slice(0, 10), partner_remarks: [] };
      setBrands(bs => [created, ...bs]);
      setDrawerFor(id);
      fireToast(isGA ? "Partner created" : "Submitted to GA for approval");
    } else {
      setBrands(bs => bs.map(b => b.id === rec.id ? { ...b, ...rec } : b));
      const prev = brands.find(b => b.id === rec.id) || {};
      // Single toast — precedence: CM resubmit > approval change > status change > generic.
      let msg = "Partner saved";
      if (cmResubmits) msg = "Submitted to GA for approval";
      else if (isGA && rec.approval_status !== prev.approval_status) msg = "Approval updated";
      else if (isGA && rec.status !== prev.status) msg = `Partner set ${rec.status}`;
      fireToast(msg);
    }
    setMode("read");
    setDraft(null);
  };

  // ── per-row delete (GA + unreferenced) ──
  const deletePartner = () => {
    const id = drawerFor;
    setConfirmDelete(false);
    closeDrawer();
    setBrands(bs => bs.filter(b => b.id !== id));
    fireToast("Partner deleted");
  };

  // ── page descriptions ──
  const titleDesc = isGA  ? "Partner brands across markets."
                  : isCM  ? "Your country's partners."
                  : isAM  ? "Your area's partners."
                  : /* OM */ "Partners at your outlet.";

  // ── filters config ──
  // GA/CM/AM: primaryFilter = [approval_status, status] (max 2 inline)
  // OM:       primaryFilter = status only
  // GA advanced: country filter
  const primaryFilter = isOM
    ? [{ key: "status", label: "Status", options: STATUS_OPTS }]
    : [
        { key: "approval_status", label: "Approval", options: APPROVAL_STATUS_OPTS },
        { key: "status",          label: "Status",   options: STATUS_OPTS },
      ];

  const advancedFilters = isGA
    ? [{ key: "country", kind: "select", label: "Market",
         options: [
           { value: "",       label: "All markets"   },
           { value: "global", label: "🌐 Global"      },
           ...COUNTRY_OPTS,
         ] }]
    : [];

  // ── columns ──
  const colName = {
    label: "Partner", sortable: true, sortKey: "name",
    render: r => (
      <div className="row" style={{ gap: 10, alignItems: "center", minWidth: 0 }}>
        <Avatar src={r.logo_url || undefined} label={r.name} size="sm"/>
        <span style={{ ...T.primary() }}>{r.name}</span>
      </div>
    ),
  };
  const colCity    = { label: "City",     width: 140, sortable: true, sortKey: "city",     render: r => <span style={T_MUTED}>{r.city || "—"}</span> };
  const colPhone   = { label: "Phone",    width: 180, sortable: true, sortKey: "phone_number", render: r => r.phone_number ? _phoneLink(r.phone_number, { muted: true }) : <span style={T_MUTED}>—</span> };
  const colCountry = { label: "Market",   width: 140, sortable: true, sortKey: "country_id", render: r => <span style={T_MUTED}>{r.country_id ? (COUNTRY_LABEL[r.country_id] || r.country_id) : "🌐 Global"}</span> };
  const colApproval = { label: "Approval", width: 120, sortable: true, sortKey: "approval_status", render: r => <StatusPill status={r.approval_status} kind="partner"/> };
  const colStatus  = { label: "Status",   width: 110, sortable: true, sortKey: "status",   render: r => <StatusPill status={r.status} kind="partner"/> };
  const colCreated = { label: "Created",  width: 110, sortable: true, sortKey: "created_at", render: r => <span style={T_MUTED}>{_fmtDate ? _fmtDate(r.created_at, r.country_id || "SG") : r.created_at}</span> };
  const colChevron = { label: "", width: 36, render: () => <span style={{ color: "var(--forest)" }}>{Ic.chevR(16)}</span> };

  const columns = isOM
    ? [colName, colCity, colStatus, colChevron]
    : [colName, colCity, colPhone, colCountry, colApproval, colStatus, colCreated, colChevron];

  // ── drawer actions ──
  // read: [Delete?][Close][Edit] — Delete is GA-only when unreferenced (leftmost per §9 danger rule)
  // form: [Cancel][Save]
  const canEditRow = drawerRow && (isGA || (isCM && drawerRow.country_id === "PH"));
  const drawerActions = isForm
    ? (<>
        <Btn variant="secondary" onClick={() => { if (isCreate) closeDrawer(); else { setMode("read"); setDraft(null); } }}>Cancel</Btn>
        <Btn variant="primary" onClick={saveForm} disabled={rejectionRequired}>{saveLabel}</Btn>
      </>)
    : (<>
        <Btn variant="secondary" onClick={closeDrawer}>Close</Btn>
        {canEditRow && <Btn variant="primary" onClick={startEdit}>Edit</Btn>}
      </>);

  const drawerTitle = isCreate ? "New partner" : (drawerRow ? drawerRow.name : "");
  const drawerSubtitle = isCreate ? "" : (drawerRow ? (drawerRow.city || "") : "");

  // Form fields shared by edit + create.
  const formFields = draft && (
    <>
      <FormSection title="General">
        <Field label="Name" required>
          <Input value={draft.name} onChange={v => setD("name", v)} placeholder="e.g. Matcha Monde"/>
        </Field>
        <Field label="Logo">
          <FileUpload value={draft.logo_url} onChange={v => setD("logo_url", v)} label="Partner logo" accept="image/*"/>
        </Field>
      </FormSection>

      {isGA && (
        <FormSection title="Approval">
          <Field label="Approval status">
            <Select value={draft.approval_status} onChange={v => setD("approval_status", v)} options={[
              { value: "draft",    label: "Draft"    },
              { value: "pending",  label: "Pending"  },
              { value: "approved", label: "Approved" },
              { value: "rejected", label: "Rejected" },
            ]}/>
          </Field>
          {draft.approval_status === "rejected" && (
            <Field label="Rejection reason" required>
              <Textarea value={draft.rejection_reason || ""} onChange={v => setD("rejection_reason", v)} rows={3} placeholder="Reason recorded on the partner record…"/>
            </Field>
          )}
        </FormSection>
      )}

      {isGA && (
        <FormSection title="Status">
          <Field label="Lifecycle status">
            <Select value={draft.status} onChange={v => setD("status", v)} options={[
              { value: "active",   label: "Active"   },
              { value: "inactive", label: "Inactive" },
            ]}/>
          </Field>
        </FormSection>
      )}

      <FormSection title="Location">
        <Field label="Street address" required>
          <Input value={draft.street_address} onChange={v => setD("street_address", v)} placeholder="e.g. 22 Orchard Blvd"/>
        </Field>
        <Field label="City" required>
          <Input value={draft.city} onChange={v => setD("city", v)} placeholder="e.g. Manila"/>
        </Field>
        <Field label="Postal code">
          <Input value={draft.postal_code || ""} onChange={v => setD("postal_code", v)} placeholder="Optional"/>
        </Field>
        <Field label="Opening hours">
          <Input value={draft.hours_text} onChange={v => setD("hours_text", v)} placeholder="e.g. Mon–Sat 09:00–21:00"/>
        </Field>
      </FormSection>

      <FormSection title="Contact">
        <Field label="Phone country code">
          <Select value={draft.phone_country_code} onChange={v => setD("phone_country_code", v)} options={[
            { value: "+63", label: "+63 Philippines" },
            { value: "+65", label: "+65 Singapore" },
            { value: "+62", label: "+62 Indonesia" },
            { value: "+66", label: "+66 Thailand" },
          ]}/>
        </Field>
        <Field label="Phone number">
          <Input value={draft.phone_number} onChange={v => setD("phone_number", v)} placeholder="e.g. 917 555 0088"/>
        </Field>
      </FormSection>

      <FormSection title="Scope">
        <Field label="Market">
          <Select value={draft.country_id || ""} onChange={v => setD("country_id", v || null)} disabled={isCM} options={[
            { value: "", label: "🌐 Global (no country restriction)" },
            ...COUNTRY_OPTS,
          ]}/>
        </Field>
      </FormSection>
    </>
  );

  // ── PageHead actions ──
  // GA: [Export (secondary)] [New partner (primary)] · canAuthor-only
  const pageActions = !canAuthor ? null : (
    <>
      <ExportButton role={role} variant="secondary" onClick={() => fireToast("Exporting partners…")}/>
      <Btn variant="primary" onClick={startCreate}>New partner</Btn>
    </>
  );

  return (
    <div className="page-inner">
      <PageHead
        title="Partnerships"
        description={titleDesc}
        actions={pageActions}
      />

      <FilterBar
        primaryFilter={primaryFilter}
        primaryValue={filters}
        onPrimaryChange={next => { setFilters(f => ({ ...f, ...next })); setPage(1); }}
        advancedFilters={advancedFilters}
        advancedValues={advFilters}
        onAdvancedChange={(k, v) => { setAdvFilters(f => ({ ...f, [k]: v })); setPage(1); }}
        onAdvancedReset={() => { setAdvFilters({}); setPage(1); }}
        onReset={() => { setFilters({}); setAdvFilters({}); setSearchQuery(""); setPage(1); }}
        search={searchQuery}
        onSearch={q => { setSearchQuery(q); setPage(1); }}
        searchPlaceholder="Search partners…"
      />

      <Table
        columns={columns}
        rows={visibleRows}
        onRow={openRead}
        emptyText="No partners match these filters."
      />

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

      {/* ── Detail Drawer (read | edit | create) ── */}
      <DetailDrawer
        open={isCreate || !!drawerFor}
        onClose={closeDrawer}
        title={drawerTitle}
        subtitle={drawerSubtitle}
        actions={drawerActions}
        width={700}
      >
        {isForm && formFields}

        {!isForm && drawerRow && (() => {
          const r = drawerRow;
          return (
            <>
              <ApprovalCard
                status={r.approval_status}
                kind="partner"
                message={
                  r.approval_status === "pending"   ? "Awaiting Global Admin approval."
                  : r.approval_status === "approved" ? "Approved"
                  : r.approval_status === "rejected" ? "Rejected: " + (r.rejection_reason || "No reason provided.")
                  : /* draft */                        "Draft — not yet submitted."
                }
                canApprove={isGA && r.approval_status === "pending"}
                canWithdraw={isCM && r.approval_status === "pending" && r.submitted_by_user_id === CURRENT_USER[role].id}
                onApprove={() => {
                  setBrands(bs => bs.map(b => b.id === r.id
                    ? { ...b, approval_status: "approved", approved_by: CURRENT_USER[role].id, approved_at: new Date().toISOString().slice(0, 10) }
                    : b));
                  fireToast("Partner approved");
                }}
                onReject={(reason) => {
                  setBrands(bs => bs.map(b => b.id === r.id
                    ? { ...b, approval_status: "rejected", rejection_reason: reason }
                    : b));
                  fireToast("Partner rejected");
                }}
                onWithdraw={() => {
                  setBrands(bs => bs.map(b => b.id === r.id
                    ? { ...b, approval_status: "draft", submitted_by_user_id: null }
                    : b));
                  fireToast("Submission withdrawn");
                }}
              />

              <FormSection title="General">
                <KeyValueGrid items={[
                  { label: "Name",     value: r.name },
                  { label: "Logo",     value: <Avatar src={r.logo_url || undefined} label={r.name} size="md"/> },
                  { label: "Status",   value: <StatusPill status={r.status} kind="partner"/> },
                  { label: "Approval", value: <StatusPill status={r.approval_status} kind="partner"/> },
                ]}/>
              </FormSection>

              <FormSection title="Approval · Workflow">
                <KeyValueGrid items={[
                  { label: "Approval status",  value: _partnerApprovalLabel(r.approval_status) },
                  { label: "Submitted by",     value: _partnerUserName(r.submitted_by_user_id) },
                  { label: "Approved by",      value: _partnerUserName(r.approved_by) },
                  { label: "Approved on",      value: r.approved_at || "—" },
                  ...(r.approval_status === "rejected"
                    ? [{ label: "Rejection reason", value: r.rejection_reason || "—" }]
                    : []),
                ]}/>
              </FormSection>

              <FormSection title="Location · Address">
                <KeyValueGrid items={[
                  { label: "Street",      value: r.street_address || "—" },
                  { label: "City",        value: r.city || "—" },
                  { label: "Postal code", value: r.postal_code || "—" },
                  { label: "Hours",       value: r.hours_text || "—" },
                ]}/>
              </FormSection>

              <FormSection title="Contact · Phone">
                <KeyValueGrid items={[
                  { label: "Phone", value: r.phone_number ? _phoneLink(r.phone_number) : "—" },
                ]}/>
              </FormSection>

              <FormSection title="Scope · Market">
                <KeyValueGrid items={[
                  { label: "Market",  value: r.country_id ? (COUNTRY_LABEL[r.country_id] || r.country_id) : "🌐 Global" },
                  { label: "Created", value: r.created_at || "—" },
                ]}/>
              </FormSection>

              <RemarksSection
                entityType="partner"
                entityId={r.id}
                remarks={r.partner_remarks || []}
                role={role}
                currentUser={CURRENT_USER[role].id}
                onAdd={() => fireToast("Remark added")}
                onEdit={() => fireToast("Remark updated")}
                onDelete={() => fireToast("Remark deleted")}
              />

              {(isGA || isCM) && (
                <DeleteSection
                  entityLabel="partner"
                  soft={r.status !== "draft"}
                  note={r.status === "draft"
                    ? "Permanently delete this draft partner. Blocked if it has linked rewards."
                    : "Decommission (soft-delete) this partner. GA-only; blocked if it has linked rewards."}
                  gate={_canDelete(role, {
                    status: r.status,
                    isReferenced: (typeof SB4_REWARDS !== "undefined" ? SB4_REWARDS : []).some(rw => rw.partner_id === r.id),
                    rbacOk: isGA || (isCM && r.country_id === "PH"),
                  })}
                  confirmBody={<div>{r.status === "draft" ? "Permanently delete" : "Decommission"} <strong>{r.name}</strong>? Writes to <strong>audit_logs</strong>.</div>}
                  onDelete={() => deletePartner()}
                />
              )}
            </>
          );
        })()}
      </DetailDrawer>


      {toast && <Toast message={toast}/>}
    </div>
  );
}


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