/* CommChannels & Marketplace page — Falcon picker + cards/list view */

const { useState: useStateCM, useMemo: useMemoCM, useEffect: useEffectCM, useRef: useRefCM } = React;

// ===== Per-row metadata: icon + description key =====
const CM_META = {
  // commChannels
  c1: { icon: 'sms',      descKey: 'cmDescSms',      displayName: 'SMS\n(Short Message Service)' },
  c2: { icon: 'whatsapp', descKey: 'cmDescWhatsapp', displayName: 'WhatsApp Business\nMessaging' },
  c3: { icon: 'email',    descKey: 'cmDescEmail',    displayName: 'Email Relay' },
  c4: { icon: 'voice',    descKey: 'cmDescVoice',    displayName: 'Voice Service' },
  c5: { icon: 'bell',     descKey: 'cmDescPush',     displayName: 'Push Notifications' },
  c6: { icon: 'ai',       descKey: 'cmDescAi',       displayName: 'AI' },
  c7: { icon: 'rcs',      descKey: 'cmDescRcs',      displayName: 'RCS Messaging' },
  c8: { icon: 'telegram', descKey: 'cmDescTelegram', displayName: 'Telegram Bot' },
  c9: { icon: 'apple',    descKey: 'cmDescAbc',      displayName: 'Apple Business Chat' },
  // appsServices (marketplace)
  a1: { icon: 'send',     descKey: 'cmDescBasic',    displayName: 'Basic Send App' },
  a2: { icon: 'survey',   descKey: 'cmDescSurvey',   displayName: 'Survey Pro' },
  a3: { icon: 'campaign', descKey: 'cmDescCampaign', displayName: 'Campaign Engine' },
  a4: { icon: 'workflow', descKey: 'cmDescWorkflow', displayName: 'Workflow Builder' },
  a5: { icon: 'analytics',descKey: 'cmDescAnalytics',displayName: 'Analytics Suite' },
  a6: { icon: 'surveyB',  descKey: 'cmDescForms',    displayName: 'Form Builder' },
  a7: { icon: 'reporting',descKey: 'cmDescReporting',displayName: 'Reporting Hub' },
  a8: { icon: 'ai',       descKey: 'cmDescAiAssistant',displayName: 'AI Assistant' },
};
window.CM_META = CM_META;

// Asset map for SVG icons (uploaded by user). Keys not present here fall back to inline glyphs below.
const CM_ICON_ASSETS = {
  sms:        'admin/assets/sms.svg',
  whatsapp:   'admin/assets/whatsapp.svg',
  email:      'admin/assets/email.svg',
  voice:      'admin/assets/voice-service.svg',
  bell:       'admin/assets/push-notifications.svg',
  ai:         'admin/assets/ai.svg',
  send:       'admin/assets/basic-application.svg',   // Basic App
  survey:     'admin/assets/survey-pro.svg',          // Survey Pro
  surveyB:    'admin/assets/survey-builder.svg',
  invitation: 'admin/assets/invitation-builder.svg',
  auth:       'admin/assets/authentication-app.svg',
};

// ===== Card icon — uses uploaded SVG asset when available, else inline glyph =====
const CMIcon = ({ kind, size = 32 }) => {
  const src = CM_ICON_ASSETS[kind];
  if (src) return <img src={src} alt="" width={size} height={size} style={{ display: 'block' }} />;
  const p = { width: size, height: size, viewBox: '0 0 24 24', fill: 'none', stroke: 'currentColor', strokeWidth: 1.7, strokeLinecap: 'round', strokeLinejoin: 'round' };
  switch (kind) {
    case 'sms':      return <svg {...p}><path d="M3 5.5C3 4.7 3.7 4 4.5 4h15c.8 0 1.5.7 1.5 1.5v9c0 .8-.7 1.5-1.5 1.5H9l-4.5 3.5V16H4.5C3.7 16 3 15.3 3 14.5v-9Z"/><text x="12" y="12.5" textAnchor="middle" fontSize="5.5" fill="currentColor" stroke="none" fontWeight="700">SMS</text></svg>;
    case 'whatsapp': return <svg {...p}><path d="M3 21l1.7-5A9 9 0 1 1 8 19.5L3 21Z"/><path d="M9.5 9.2c.4 1.2 1.2 2.3 2.3 3.2 1.1.9 2.3 1.5 3.5 1.7l1.2-1.6c.3-.4.7-.5 1.1-.4l1.6.5c.4.1.6.5.6.9 0 1.4-1.1 2.5-2.5 2.5-4.4 0-9-4.6-9-9 0-1.4 1.1-2.5 2.5-2.5.4 0 .8.2.9.6l.5 1.6c.1.4 0 .8-.4 1.1L9.5 9.2Z"/></svg>;
    case 'email':    return <svg {...p}><rect x="3" y="5" width="18" height="14" rx="2"/><path d="m3.5 6.5 8.5 6 8.5-6"/></svg>;
    case 'voice':    return <svg {...p}><path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.86 19.86 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6A19.86 19.86 0 0 1 2.12 4.18 2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72c.13.96.37 1.9.72 2.81a2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45c.91.35 1.85.59 2.81.72a2 2 0 0 1 1.72 2Z"/></svg>;
    case 'bell':     return <svg {...p}><path d="M15 17h5l-1.4-1.4A2 2 0 0 1 18 14.2V11a6 6 0 0 0-12 0v3.2a2 2 0 0 1-.6 1.4L4 17h5"/><path d="M9 17a3 3 0 0 0 6 0"/></svg>;
    case 'ai':       return <svg {...p}><path d="M5 7h12a2 2 0 0 1 2 2v6a2 2 0 0 1-2 2h-5l-4 3v-3H5a2 2 0 0 1-2-2V9a2 2 0 0 1 2-2Z"/><circle cx="9" cy="12" r="1.2" fill="currentColor" stroke="none"/><circle cx="13" cy="12" r="1.2" fill="currentColor" stroke="none"/><path d="M11 4v3"/><path d="M9.5 4h3"/></svg>;
    case 'rcs':      return <svg {...p}><rect x="3" y="5" width="18" height="14" rx="2"/><path d="M7 10h10M7 13h7"/></svg>;
    case 'telegram': return <svg {...p}><path d="m3 12 18-7-3 16-6-4-3 4-1-6 13-9"/></svg>;
    case 'apple':    return <svg {...p}><path d="M16 4c0 2-1.5 3.5-3 3.5"/><path d="M18 14c0 4-2.5 6-4 6-1 0-1.5-.5-2.5-.5s-1.5.5-2.5.5C7.5 20 5 18 5 13c0-3 2-5 4.5-5 1.2 0 2 .5 2.5.5s1.3-.6 2.7-.5C16 8 17.5 9 18.5 11c-1.5.5-2.5 2-2.5 3Z"/></svg>;
    case 'send':     return <svg {...p}><path d="m4 12 16-8-7 16-2-7-7-1Z"/></svg>;
    case 'survey':   return <svg {...p}><rect x="4" y="3" width="16" height="18" rx="2"/><path d="M8 7h8M8 11h8M8 15h5"/><circle cx="6.2" cy="7" r=".7" fill="currentColor" stroke="none"/><circle cx="6.2" cy="11" r=".7" fill="currentColor" stroke="none"/><circle cx="6.2" cy="15" r=".7" fill="currentColor" stroke="none"/></svg>;
    case 'campaign': return <svg {...p}><path d="M3 11v2a1 1 0 0 0 1 1h2l4 4v-12L6 10H4a1 1 0 0 0-1 1Z"/><path d="M14 7c2 1 2 9 0 10"/><path d="M17 5c3 1.5 3 12.5 0 14"/></svg>;
    case 'workflow': return <svg {...p}><rect x="3" y="3" width="6" height="6" rx="1.5"/><rect x="15" y="3" width="6" height="6" rx="1.5"/><rect x="9" y="15" width="6" height="6" rx="1.5"/><path d="M6 9v3h12V9"/><path d="M12 12v3"/></svg>;
    case 'analytics':return <svg {...p}><path d="M4 19V5"/><path d="M4 19h16"/><rect x="7" y="11" width="3" height="6" rx=".5"/><rect x="12" y="8" width="3" height="9" rx=".5"/><rect x="17" y="13" width="3" height="4" rx=".5"/></svg>;
    case 'forms':    return <svg {...p}><rect x="4" y="3" width="16" height="18" rx="2"/><path d="M8 8h8M8 12h8M8 16h5"/></svg>;
    case 'reporting':return <svg {...p}><path d="M5 21V8l7-5 7 5v13"/><path d="M9 21v-7h6v7"/></svg>;
    default:         return <svg {...p}><circle cx="12" cy="12" r="8"/></svg>;
  }
};

// Currency
const CMRiyal = ({ size = 13 }) => <IcRiyal size={size} />;

// Format price tail (e.g. 9.99/Month). For demo we mod app.priceValue down.
const fmtCardPrice = (app, t) => {
  if (!app.priceValue) return null;
  const n = (app.priceValue % 100) + 0.99;
  const tail = app.priceType === 'Monthly' ? t.cmPerMonth :
               app.priceType === 'Yearly'  ? t.cmPerYear :
               app.priceType === 'Quarterly' ? t.cmPerQuarter : '';
  return { val: n.toFixed(2), tail };
};

// ===== Status pill (reuses Hierarchy's StatusBadge for consistent look) =====
const CMStatusPill = ({ status, t }) => {
  if (!status) return null;
  return <StatusBadge status={status} t={t} />;
};

// Status -> card tone
const cardToneFor = (status) => {
  if (status === 'active')   return 'cm-card-tone-active';
  if (status === 'expired')  return 'cm-card-tone-expired';
  if (status === 'disable')  return 'cm-card-tone-disable';
  if (status === 'paid')     return 'cm-card-tone-paid';
  return '';
};

// ===== Single channel/app card =====
const CMCard = ({ app, t, pending, onAction, isComm = false }) => {
  const meta = CM_META[app.id] || { icon: 'sms', descKey: 'cmDescSms', displayName: app.name };
  const desc = t[meta.descKey] || '';
  const lines = (meta.displayName || app.name).split('\n');
  const price = fmtCardPrice(app, t);
  const hasPending = !!(pending && (pending.type || pending.value));
  const noActivation = !app.firstActivation;
  // "Paid" commchannels have no First Activation yet but still show their Purchase/Paid dates.
  const showDates = !noActivation || (isComm && app.status === 'paid');

  // Pending price-type band content
  const pendBand = hasPending && (pending.type ? {
    a: { label: t.newPriceType, value: (
      pending.type.priceType === 'OneTime'   ? t.priceOneTime :
      pending.type.priceType === 'Monthly'   ? t.priceMonthly :
      pending.type.priceType === 'Quarterly' ? t.priceQuarterly :
      t.priceYearly) },
    b: { label: t.effectiveDate, value: formatDMY(pending.type.effDate) },
    c: { label: t.newPriceValue, value: <><CMRiyal size={11}/> {(pending.type.priceValue || 0).toLocaleString()}</> },
  } : pending.value ? {
    a: { label: t.newPriceValue, value: <><CMRiyal size={11}/> {(pending.value.priceValue || 0).toLocaleString()}</> },
    b: { label: t.effectiveDate, value: formatDMY(pending.value.effDate) },
    c: null,
  } : null);

  // Action buttons per status
  let primary = null, secondary = null;
  if (isComm) {
    // CommChannels: no enable/disable; "Paid" exposes "Activate", unpaid exposes "Do Payment".
    if (app.status === 'paid') {
      primary = { id: 'activate', label: t.actActivate, kind: 'outline-check' };
    } else if (app.status === 'expired' || app.status === 'inactive') {
      primary = { id: 'doPayment', label: t.actDoPayment, kind: 'teal' };
    }
  } else if (app.status === 'active') {
    primary = { id: 'disable', label: t.actDisable, kind: 'dark' };
  } else if (app.status === 'expired') {
    primary = { id: 'doPayment', label: t.actDoPayment, kind: 'teal' };
    secondary = { id: 'disable', label: t.actDisable, kind: 'dark' };
  } else if (app.status === 'disable') {
    primary = { id: 'enable', label: t.actEnable, kind: 'outline-check' };
  } else if (app.status === 'inactive') {
    primary = { id: 'doPayment', label: t.actDoPayment, kind: 'teal' };
  }

  return (
    <div className={`cm-card ${cardToneFor(app.status)} ${hasPending ? 'cm-card-has-pending' : ''}`}>
      <div className="cm-card-top">
        <div className="cm-card-icon"><CMIcon kind={meta.icon} /></div>
        <div className="cm-card-title">
          {lines.map((l, i) => <div key={i}>{l}</div>)}
        </div>
        <div className="cm-card-status">
          {app.status === 'inactive' && price ? (
            <div className="cm-card-price-stack">
              <StatusBadge status="inactive" t={t} />
              <div className="cm-price-line"><CMRiyal size={13}/> <strong>{price.val}</strong>{price.tail}</div>
            </div>
          ) : app.status === 'disable' && price ? (
            <div className="cm-card-price-stack">
              <StatusBadge status="disable" t={t} />
              <div className="cm-price-line"><CMRiyal size={13}/> <strong>{price.val}</strong>{price.tail}</div>
            </div>
          ) : (
            <CMStatusPill status={app.status} t={t} />
          )}
        </div>
      </div>

      <div className="cm-card-desc">{desc}</div>

      {showDates && (
        <div className={`cm-card-dates ${isComm ? 'cm-card-dates-comm' : ''}`}>
          <div className="cm-date">
            <span className="cm-date-label">{t.colFirstActivation.replace(' Date','')}</span>
            <span className="cm-date-value"><img src="admin/assets/calendar.svg" className="cm-date-ico" alt="" /> {formatDMY(app.firstActivation) || '—'}</span>
          </div>
          {isComm && (
            <div className="cm-date">
              <span className="cm-date-label">{t.colPurchaseDate.replace(' Date','')}</span>
              <span className="cm-date-value"><img src="admin/assets/calendar.svg" className="cm-date-ico" alt="" /> {formatDMY(app.purchaseDate) || '—'}</span>
            </div>
          )}
          <div className="cm-date">
            <span className="cm-date-label">{(isComm ? t.colPaidDate : t.colActivationDate).replace(' Date','')}</span>
            <span className="cm-date-value"><img src="admin/assets/calendar.svg" className="cm-date-ico" alt="" /> {formatDMY(app.activation) || '—'}</span>
          </div>
          <div className="cm-date">
            <span className="cm-date-label">Renew</span>
            <span className="cm-date-value"><img src="admin/assets/calendar.svg" className="cm-date-ico" alt="" /> {formatDMY(app.renew) || '—'}</span>
          </div>
        </div>
      )}

      {hasPending && pendBand && (
        <div className="cm-card-pending">
          <div className="cm-pend-col">
            <div className="cm-pend-label">{pendBand.a.label}</div>
            <div className="cm-pend-value">{pendBand.a.value}</div>
          </div>
          <div className="cm-pend-col">
            <div className="cm-pend-label">{pendBand.b.label}</div>
            <div className="cm-pend-value">{pendBand.b.value}</div>
          </div>
          {pendBand.c && (
            <div className="cm-pend-col">
              <div className="cm-pend-label">{pendBand.c.label}</div>
              <div className="cm-pend-value">{pendBand.c.value}</div>
            </div>
          )}
        </div>
      )}

      <div className="cm-card-actions">
        {secondary && (
          <button
            type="button"
            className={`cm-btn cm-btn-${secondary.kind}`}
            onClick={() => onAction(app.id, secondary.id)}>
            <span className="cm-btn-icon"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round"><circle cx="12" cy="12" r="10"/><line x1="4.93" y1="4.93" x2="19.07" y2="19.07"/></svg></span>
            {secondary.label}
          </button>
        )}
        {primary && (
          <button
            type="button"
            className={`cm-btn cm-btn-${primary.kind}`}
            onClick={() => onAction(app.id, primary.id)}>
            <span className="cm-btn-icon">
              {primary.id === 'disable' ? (
                <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round"><circle cx="12" cy="12" r="10"/><line x1="4.93" y1="4.93" x2="19.07" y2="19.07"/></svg>
              ) : (primary.id === 'enable' || primary.id === 'activate') ? (
                <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round"><polyline points="20 6 9 17 4 12"/></svg>
              ) : (
                <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><rect x="3" y="6" width="18" height="13" rx="2"/><path d="M3 10h18"/></svg>
              )}
            </span>
            {primary.label}
          </button>
        )}
      </div>
    </div>
  );
};

// ===== Show filter dropdown =====
const CMShowFilter = ({ value, onChange, t }) => {
  const [open, setOpen] = useStateCM(false);
  const ref = useRefCM(null);
  useEffectCM(() => {
    if (!open) return;
    const f = (e) => { if (ref.current && !ref.current.contains(e.target)) setOpen(false); };
    document.addEventListener('mousedown', f);
    return () => document.removeEventListener('mousedown', f);
  }, [open]);
  const opts = [
    { id: 'all',      label: t.cmShowAll },
    { id: 'active',   label: t.cmShowActive },
    { id: 'expired',  label: t.cmShowExpired },
    { id: 'disable',  label: t.cmShowDisable },
    { id: 'inactive', label: t.cmShowInactive },
  ];
  const cur = opts.find(o => o.id === value) || opts[0];
  return (
    <div className="cm-show" ref={ref}>
      <span className="cm-show-label">{t.cmShow}</span>
      <button type="button" className={`cm-show-btn ${open ? 'open' : ''}`} onClick={() => setOpen(o => !o)}>
        <span>{cur.label}</span>
        <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><polyline points="6 9 12 15 18 9"/></svg>
      </button>
      {open && (
        <div className="cm-show-menu">
          {opts.map(o => (
            <button key={o.id} type="button" className={`cm-show-menu-item ${o.id === value ? 'active' : ''}`} onClick={() => { onChange(o.id); setOpen(false); }}>
              {o.label}
            </button>
          ))}
        </div>
      )}
    </div>
  );
};

// ===== View toggle (list/grid) =====
const CMViewToggle = ({ value, onChange, t }) => (
  <div className="cm-view-toggle" role="group" aria-label="View">
    <button type="button" className={`cm-view-btn ${value === 'list' ? 'active' : ''}`} onClick={() => onChange('list')} title={t.cmViewList} aria-label={t.cmViewList}>
      <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><line x1="8" y1="6" x2="21" y2="6"/><line x1="8" y1="12" x2="21" y2="12"/><line x1="8" y1="18" x2="21" y2="18"/><line x1="3" y1="6" x2="3.01" y2="6"/><line x1="3" y1="12" x2="3.01" y2="12"/><line x1="3" y1="18" x2="3.01" y2="18"/></svg>
    </button>
    <button type="button" className={`cm-view-btn ${value === 'grid' ? 'active' : ''}`} onClick={() => onChange('grid')} title={t.cmViewGrid} aria-label={t.cmViewGrid}>
      <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><rect x="3" y="3" width="7" height="7" rx="1"/><rect x="14" y="3" width="7" height="7" rx="1"/><rect x="3" y="14" width="7" height="7" rx="1"/><rect x="14" y="14" width="7" height="7" rx="1"/></svg>
    </button>
  </div>
);

// ===== Falcon Clients picker (left rail) — uses the compact Template Management list =====
const CMClientsPanel = ({ tree, selected, onSelect, t }) => {
  const clients = (tree?.children || []).filter(c => c.type === 'client');
  return (
    <div className="clients-panel tm-clients-panel cm-clients-panel with-falcon-head">
      <div className="clients-root">
        <div className="clients-root-inner" style={{ cursor: 'default' }}>
          <span className="clients-root-icon"><IcFalcon size={20} /></span>
          <span title={tree?.name || 'Falcon'}>{tree?.name || 'Falcon'}</span>
        </div>
      </div>
      <div className="clients-section-label">{t.falconClients || 'Clients'}</div>
      <div className="tm-clients-list">
        {clients.map(c => (
          <div
            key={c.id}
            className={`tm-client-row ${selected === c.id ? 'selected' : ''}`}
            onClick={() => onSelect(c.id)}
          >
            <BrandLogo brand={c.brand} size={24} />
            <span className="nm">{c.name}</span>
          </div>
        ))}
      </div>
    </div>
  );
};

// ===== Falcon / Client perspective picker =====
const CMViewAsPicker = ({ t, onPick }) => (
  <div className="tpl-picker-page">
    <div className="tpl-picker-card">
      <div className="tpl-picker-head">
        <div>
          <h2>{t.cmViewAsTitle}</h2>
          <p>{t.cmViewAsSubtitle}</p>
        </div>
      </div>
      <div className="tpl-picker-grid">
        <button className="tpl-picker-tile falcon" onClick={() => onPick('falcon')}>
          <span className="ic-wrap"><T2Mark size={28} color="white" /></span>
          <span className="ttl">{t.cmViewAsFalcon}</span>
          <span className="dsc">{t.cmViewAsFalconDesc}</span>
          <span className="cta">{t.cmViewAsFalcon} <IcChevronRight size={14} stroke={2} /></span>
        </button>
        <button className="tpl-picker-tile client" onClick={() => onPick('client')}>
          <span className="ic-wrap"><IcBuildingS size={26} stroke={1.7} /></span>
          <span className="ttl">{t.cmViewAsClient}</span>
          <span className="dsc">{t.cmViewAsClientDesc}</span>
          <span className="cta">{t.cmViewAsClient} <IcChevronRight size={14} stroke={2} /></span>
        </button>
      </div>
    </div>
  </div>
);

// ===== Page wrapper — kind: 'commChannels' | 'appsServices' =====
const CommMktPage = ({ kind, tree, selected, selectNode, lang, t, pushToast }) => {
  const tabKey = kind; // matches APPS_BY_TAB key
  const [viewAs, setViewAs] = useStateCM(null); // null | 'falcon' | 'client'
  const selectedNode = useMemoCM(() => findNode(tree, selected) || tree.children[0], [tree, selected]);

  const [view, setView] = useStateCM('grid'); // grid | list (client view only; Falcon is always list)
  const [showFilter, setShowFilter] = useStateCM('all');
  const [showIB, setShowIB] = useStateCM(false);
  const [ibTargetId, setIbTargetId] = useStateCM(null);

  // pending edits + apps state for grid view
  const [apps, setApps] = useStateCM(() => (APPS_BY_TAB[tabKey] || []).map(a => ({ ...a })));
  const [pendingMap, setPendingMap] = useStateCM({});

  // Reset apps/pending when client or tab changes
  useEffectCM(() => {
    setApps((APPS_BY_TAB[tabKey] || []).map(a => ({ ...a })));
    setPendingMap({});
  }, [tabKey, selectedNode?.id]);

  const filtered = useMemoCM(() => {
    if (showFilter === 'all') return apps;
    return apps.filter(a => a.status === showFilter);
  }, [apps, showFilter]);

  const isComm = tabKey === 'commChannels';
  const handleAction = (id, action) => {
    if (action === 'activate') {
      // Route by channel: WhatsApp \u2192 Meta Service .Mng; Voice (and any other) \u2192 Voice Service, Voice account tab.
      const ch = (CM_META[id] && CM_META[id].icon) || '';
      if (ch === 'whatsapp') { if (window.falconGoMetaService) window.falconGoMetaService(); }
      else { if (window.falconGoVoiceAccount) window.falconGoVoiceAccount(); }
    } else if (action === 'disable') {
      setApps(a => a.map(x => x.id === id ? { ...x, status: 'disable' } : x));
      pushToast(`${t.actDisable} \u2713`);
    } else if (action === 'enable') {
      setApps(a => a.map(x => x.id === id ? { ...x, status: 'active' } : x));
      pushToast(`${t.actEnable} \u2713`);
    } else if (action === 'doPayment') {
      // Show the same Insufficient Balance modal used in Hierarchy/Applications
      setIbTargetId(id);
      setShowIB(true);
    }
  };

  // Hardcode one demo pending change on c2 (WhatsApp) to mirror the screenshot
  useEffectCM(() => {
    if (tabKey === 'commChannels' && Object.keys(pendingMap).length === 0) {
      setPendingMap({
        c2: { type: { priceType: 'OneTime', effDate: '1/11/2025', priceValue: 2500 } }
      });
    }
  }, [tabKey]);

  const isRoot = selectedNode?.type === 'root';

  // ---- PICKER PAGE ----
  if (viewAs === null) {
    return <CMViewAsPicker t={t} onPick={(v) => {
      setViewAs(v);
      if (v === 'client') selectNode('aramco');
    }} />;
  }

  const isFalcon = viewAs === 'falcon';
  // Falcon view is list-only — no card/grid toggle
  const effectiveView = isFalcon ? 'list' : view;
  const headerNode = isFalcon ? selectedNode : (findNode(tree, 'aramco') || selectedNode);

  return (
    <div className={`cm-page ${isFalcon ? '' : 'cm-page-client'}`}>
      {isFalcon && <CMClientsPanel tree={tree} selected={selectedNode?.id} onSelect={selectNode} t={t} />}

      <div className="cm-main">
        {/* Top header — same style as Organization Hierarchy's userdetails top bar */}
        <div className="ud-top-bar cm-ud-top-bar">
          <div className="ud-top-left">
            <button type="button" className="ud-back-btn" onClick={() => setViewAs(null)} title={t.cmBackToPicker} aria-label={t.cmBackToPicker}>
              <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round"><polyline points="15 18 9 12 15 6"/></svg>
            </button>
            {headerNode?.type === 'root' ? (
              <span className="node-avatar" style={{ background: 'white', border: '1px solid var(--border)', color: 'var(--teal)', width: 32, height: 32 }}>
                <IcFalcon size={18} />
              </span>
            ) : headerNode?.type === 'client' ? (
              <BrandLogo brand={headerNode.brand} size={32} />
            ) : (
              <span className="node-avatar" style={{ background: '#0d3f44', color: 'white', width: 32, height: 32 }}>
                <span style={{ fontSize: 12, fontWeight: 700 }}>{(headerNode?.name || 'N').slice(0, 1)}</span>
              </span>
            )}
            <span className="ud-top-name">{headerNode?.name || ''}</span>
          </div>
          <div className="cm-main-actions">
            <CMShowFilter value={showFilter} onChange={setShowFilter} t={t} />
            {!isFalcon && <CMViewToggle value={view} onChange={setView} t={t} />}
          </div>
        </div>

        {effectiveView === 'grid' ? (
          <div className="cm-grid">
            {filtered.map(app => (
              <CMCard
                key={app.id}
                app={app}
                t={t}
                isComm={isComm}
                pending={pendingMap[app.id]}
                onAction={handleAction}
              />
            ))}
            {filtered.length === 0 && (
              <div className="cm-empty">No items match the current filter.</div>
            )}
          </div>
        ) : (
          <div className="cm-list-wrap">
            <ApplicationsPage tabKey={tabKey} t={t} pushToast={pushToast} hideVisibility={!isFalcon} nodeId={headerNode?.id} />
          </div>
        )}
      </div>
      {showIB && (
        <InsufficientBalanceModal
          t={t}
          onCancel={() => { setShowIB(false); setIbTargetId(null); }}
          onProceed={(items) => {
            setShowIB(false);
            const first = items[0]?.name || '';
            if (ibTargetId) {
              const today = formatMdy(new Date());
              setApps(a => a.map(x => {
                if (x.id !== ibTargetId) return x;
                if (isComm) {
                  // First purchase (never activated) → "Paid" (awaiting activation); otherwise a renewal → Active.
                  if (!x.firstActivation) return { ...x, status: 'paid', purchaseDate: x.purchaseDate || today, activation: today };
                  return { ...x, status: 'active', activation: today };
                }
                return { ...x, status: 'active' };
              }));
            }
            setIbTargetId(null);
            pushToast(`${t.ibProceed} \u2713 — ${first}`);
          }}
        />
      )}
    </div>
  );
};

const CommChannelsPage = (props) => <CommMktPage {...props} kind="commChannels" />;
const MarketplacePage  = (props) => <CommMktPage {...props} kind="appsServices" />;

window.CommChannelsPage = CommChannelsPage;
window.MarketplacePage = MarketplacePage;
