// T2 Falcon Admin — Templates: Create wizard (3 steps)

const { useState: useStateW, useRef: useRefW, useEffect: useEffectW } = React;

// ---- Country dropdown (matches AddUser/OTP PhoneInput style) ----
const TplCountrySelect = ({ value, onChange }) => {
  const [open, setOpen] = useStateW(false);
  const [query, setQuery] = useStateW('');
  const [pos, setPos] = useStateW({ top: 0, left: 0, width: 0, dropUp: false });
  const wrapRef = useRefW();
  const triggerRef = useRefW();
  const menuRef = useRefW();
  const list = (window.COUNTRIES || []);
  const country = list.find(c => c.code === value) || list.find(c => c.code === 'SA') || list[0];

  useEffectW(() => {
    if (!open) return;
    const recalc = () => {
      const r = triggerRef.current?.getBoundingClientRect();
      if (!r) return;
      const menuH = 340;
      const spaceBelow = window.innerHeight - r.bottom;
      const dropUp = spaceBelow < menuH && r.top > menuH;
      setPos({ top: dropUp ? r.top - menuH - 4 : r.bottom + 4, left: r.left, width: r.width, dropUp });
    };
    recalc();
    const onDoc = (e) => {
      const inTrigger = wrapRef.current && wrapRef.current.contains(e.target);
      const inMenu = menuRef.current && menuRef.current.contains(e.target);
      if (!inTrigger && !inMenu) setOpen(false);
    };
    document.addEventListener('mousedown', onDoc);
    window.addEventListener('resize', recalc);
    window.addEventListener('scroll', recalc, true);
    return () => {
      document.removeEventListener('mousedown', onDoc);
      window.removeEventListener('resize', recalc);
      window.removeEventListener('scroll', recalc, true);
    };
  }, [open]);

  const q = query.trim().toLowerCase();
  const filtered = !q ? list : list.filter(c => c.name.toLowerCase().includes(q) || c.dial.includes(q));
  const Flag = country?.flag;
  const select = (c) => { onChange(c.code); setOpen(false); setQuery(''); };

  return (
    <div className="tpl-cc-wrap" ref={wrapRef}>
      <button type="button" ref={triggerRef} className="tpl-cc-trigger" onClick={() => setOpen(o => !o)}>
        {Flag && <span className="tpl-cc-flag"><Flag /></span>}
        <span className="tpl-cc-text">{country ? `${country.name} ${country.dial}` : 'Select country'}</span>
        <span className="tpl-cc-chev"><IcChevronDown size={14} stroke={2} /></span>
      </button>
      {open && (
        <div
          className="tpl-cc-menu tpl-cc-menu-fixed"
          ref={menuRef}
          style={{ top: pos.top, left: pos.left, width: pos.width }}
        >
          <div className="tpl-cc-search">
            <IcSearch size={16} />
            <input
              type="text"
              autoFocus
              value={query}
              onChange={(e) => setQuery(e.target.value)}
              placeholder="Search for countries"
            />
          </div>
          <div className="tpl-cc-list">
            {filtered.map(c => {
              const F = c.flag;
              return (
                <button key={c.code} type="button"
                  className={`tpl-cc-item ${c.code === country?.code ? 'is-active' : ''}`}
                  onClick={() => select(c)}>
                  <span className="tpl-cc-flag tpl-cc-flag-md"><F /></span>
                  <span className="tpl-cc-name">{c.name}</span>
                  <span className="tpl-cc-dial">{c.dial}</span>
                </button>
              );
            })}
            {filtered.length === 0 && <div className="tpl-cc-empty">No countries match</div>}
          </div>
        </div>
      )}
    </div>
  );
};

// ---- Contact group multi-select control ----
const TplContactGroupMulti = ({ value = [], onChange, t }) => {
  const [open, setOpen] = useStateW(false);
  const ref = useRefW();
  useEffectW(() => {
    const onDoc = (e) => { if (ref.current && !ref.current.contains(e.target)) setOpen(false); };
    document.addEventListener('mousedown', onDoc);
    return () => document.removeEventListener('mousedown', onDoc);
  }, []);
  const groups = window.contactGroups || [];
  const selected = groups.filter(g => value.includes(g.id));
  const toggle = (id) => {
    const next = value.includes(id) ? value.filter(x => x !== id) : [...value, id];
    onChange(next);
  };
  return (
    <div className="tpl-cg-multi" ref={ref}>
      <div
        className={`tpl-cg-multi-control ${open ? 'open' : ''}`}
        onClick={() => setOpen(o => !o)}
      >
        {selected.length === 0 ? (
          <span className="placeholder">{t.selectPlaceholder}</span>
        ) : selected.map(g => (
          <span key={g.id} className="tpl-cg-chip">
            {g.name}
            <span
              className="x"
              onClick={(e) => { e.stopPropagation(); toggle(g.id); }}
            ><IcClose size={10} stroke={2.4} /></span>
          </span>
        ))}
        <span className="chev"><IcChevronDown size={14} stroke={1.7} /></span>
      </div>
      {open && (
        <div className="tpl-cg-multi-menu">
          {groups.map(g => (
            <div
              key={g.id}
              className={`tpl-cg-multi-opt ${value.includes(g.id) ? 'checked' : ''}`}
              onClick={() => toggle(g.id)}
            >
              <span className="cb">{value.includes(g.id) && <IcCheck size={9} stroke={3} />}</span>
              <span className="meta">
                <span className="nm">{g.name}</span>
                <span className="ct"> · {g.count.toLocaleString()} contacts</span>
              </span>
            </div>
          ))}
        </div>
      )}
    </div>
  );
};

// ---- Stepper (uses shared .ac-stepper styles from addclient.css) ----
const TplStepper = ({ step, t }) => {
  const labels = [t.stepBasicInfo, t.stepMessageStructure, t.stepShareSubmit];
  const current = step - 1; // zero-based index for positioning math
  const lastIdx = labels.length - 1;
  const pct = (current / lastIdx) * 100;
  return (
    <div className="ac-stepper">
      <div className="ac-stepper-track">
        <div className="ac-stepper-fill" style={{ width: pct + '%' }} />
        {labels.map((lbl, i) => {
          const state = i < current ? 'done' : i === current ? 'active' : 'idle';
          return (
            <button
              key={i}
              type="button"
              className={`ac-stepper-dot ${state}`}
              style={{ left: (i / lastIdx) * 100 + '%' }}
              aria-label={lbl}
            >
              {state === 'done' ? (
                <svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="white" strokeWidth="3.5" strokeLinecap="round" strokeLinejoin="round"><polyline points="20 6 9 17 4 12" /></svg>
              ) : state === 'active' ? (
                <span className="ac-stepper-dot-pulse" />
              ) : null}
            </button>
          );
        })}
      </div>
      <div className="ac-stepper-labels">
        {labels.map((lbl, i) => (
          <span
            key={i}
            className={`ac-step-label ${i === current ? 'active' : ''} ${i < current ? 'done' : ''}`}
            style={{ left: (i / lastIdx) * 100 + '%' }}
          >
            {lbl}
          </span>
        ))}
      </div>
    </div>
  );
};

// ---- Sub-category card ----
const SubCard = ({ id, title, desc, selected, disabled, onSelect, comingSoon, t }) => (
  <div className={`tpl-sub-card ${selected ? 'selected' : ''} ${disabled ? 'disabled' : ''}`} onClick={() => !disabled && onSelect(id)}>
    <span className="tpl-sub-radio"></span>
    <div className="tpl-sub-text">
      <div className="title">{title}{comingSoon && <span className="coming"> ({t.comingSoon})</span>}</div>
      <div className="desc">{desc}</div>
    </div>
  </div>
);

// ---- Category icons (Marketing / Utility / Authentication) ----
const IcCatMarketing = ({ size = 18 }) => (
  <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
    <path d="M3 11v2a1 1 0 0 0 1 1h2l5 4V6L6 10H4a1 1 0 0 0-1 1Z" />
    <path d="M14 8.5a4 4 0 0 1 0 7" />
    <path d="M17 6a7 7 0 0 1 0 12" />
  </svg>
);
const IcCatUtility = ({ size = 18 }) => (
  <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
    <path d="M6 8a6 6 0 0 1 12 0c0 5 2.5 6 2.5 6h-17S6 13 6 8Z" />
    <path d="M10 19a2 2 0 0 0 4 0" />
  </svg>
);
const IcCatAuth = ({ size = 18 }) => (
  <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
    <circle cx="9" cy="8" r="3.2" />
    <path d="M3 20c0-3.2 2.7-5 6-5s6 1.8 6 5" />
    <circle cx="18.5" cy="9.5" r="1.7" />
    <path d="M17.2 10.8 14.5 13.5" />
    <path d="m16 12 1 1" />
  </svg>
);

// ---- Step 1: Basic Information ----
const TplWizardStep1 = ({ data, setData, t }) => {
  const cats = ['Marketing', 'Utility', 'Authentication'];
  const catIcons = { Marketing: IcCatMarketing, Utility: IcCatUtility, Authentication: IcCatAuth };
  const subOpts = {
    Marketing: [
      { id: 'Default', title: t.subDefault, desc: t.subDefaultDescMkt },
      { id: 'Catalog', title: t.subCatalog, desc: t.subCatalogDesc, comingSoon: true, disabled: true },
      { id: 'Flows', title: t.subFlows, desc: t.subFlowsDescMkt },
      { id: 'Calling', title: t.subCallingPerm, desc: t.subCallingPermDesc, comingSoon: true, disabled: true },
    ],
    Utility: [
      { id: 'Default', title: t.subDefault, desc: t.subDefaultDescUtil },
      { id: 'Flows', title: t.subFlows, desc: t.subFlowsDescUtil },
      { id: 'Calling', title: t.subCallingPerm, desc: t.subCallingPermDesc, comingSoon: true, disabled: true },
    ],
    Authentication: [
      { id: 'OTP', title: t.subOTP, desc: t.subOTPDesc },
    ],
  };
  const wabaAccounts = ['Aramco WABA Main', 'Aramco WABA Secondary', 'Falcon Demo WABA'];
  return (
    <div>
      <div className="tpl-grid-3">
        <div className="tpl-field tpl-col-waba">
          <label className="tpl-field-label">{t.wabaAccountLbl}</label>
          <TplDropdown
            value={data.wabaAccount || ''}
            onChange={(v) => setData({ ...data, wabaAccount: v })}
            placeholder={t.wabaAccountPh}
            options={[
              { value: '', label: t.wabaAccountPh },
              ...wabaAccounts.map(w => ({ value: w, label: w })),
            ]}
          />
        </div>
        <div className="tpl-field tpl-col-name">
          <label className="tpl-field-label">{t.templateNameLbl}</label>
          <div className="tpl-input-with-counter">
            <input className={`tpl-field-input ${(data.name || '').trim() ? 'is-valid' : ''}`} placeholder={t.templateNamePh} value={data.name || ''} onChange={(e) => setData({ ...data, name: e.target.value.slice(0, 512) })} />
            <span className="tpl-input-counter">{(data.name || '').length}/512</span>
          </div>
        </div>
        <div className="tpl-field tpl-col-ref">
          <label className="tpl-field-label">{t.referenceIdLbl}</label>
          <input
            className={`tpl-field-input ${(data.referenceId || '').trim() ? 'is-valid' : ''}`}
            type="text"
            placeholder={t.referenceIdPh || ''}
            value={data.referenceId || ''}
            onChange={(e) => setData({ ...data, referenceId: e.target.value })}
          />
        </div>
        <div className="tpl-field tpl-col-lang">
          <label className="tpl-field-label">{t.selectLanguage}</label>
          <TplDropdown
            value={data.language || ''}
            onChange={(v) => setData({ ...data, language: v })}
            placeholder={t.selectPlaceholder}
            options={[
              { value: '', label: t.selectPlaceholder },
              { value: 'English', label: 'English' },
              { value: 'Arabic', label: 'العربية' },
            ]}
          />
        </div>
      </div>

      <div className="tpl-cat-tabs">
        {cats.map(c => {
          const Icon = catIcons[c];
          const label = c === 'Marketing' ? t.catMarketing : c === 'Utility' ? t.catUtility : t.catAuthentication;
          return (
            <button key={c} type="button" className={`tpl-cat-tab ${data.category === c ? 'active' : ''}`} onClick={() => setData({ ...data, category: c, subCategory: subOpts[c][0].id })}>
              <span className="tpl-cat-tab-icon"><Icon size={18} /></span>
              <span className="tpl-cat-tab-label">{label}</span>
            </button>
          );
        })}
      </div>

      <div className="tpl-sub-list">
        {(subOpts[data.category] || []).map(s => (
          <SubCard key={s.id} {...s} selected={data.subCategory === s.id} onSelect={(id) => setData({ ...data, subCategory: id })} t={t} />
        ))}
      </div>
    </div>
  );
};

// ---- Step 2 (Authentication variant): Code delivery · Content · Validity ----
const TplWizardStep2Auth = ({ data, setData, t }) => {
  const auth = data.auth || {};
  const updAuth = (patch) => setData({ ...data, auth: { ...auth, ...patch } });

  const delivery = auth.delivery || 'copy';
  // Defaults: security recommendation ON, expiration OFF.
  const addSecurity = auth.addSecurity !== false;
  const addExpiration = auth.addExpiration === true;
  // Expiration input is stored as a raw string so the user can briefly empty
  // the field (which surfaces the validation message) without us forcing a number.
  const expiresInRaw = (auth.expiresInRaw !== undefined) ? auth.expiresInRaw : '10';
  const expiresInNum = parseInt(expiresInRaw, 10);
  const expiresErr = expiresInRaw === '' || isNaN(expiresInNum) || expiresInNum < 1 || expiresInNum > 90;
  const bumpExpires = (delta) => {
    const cur = isNaN(expiresInNum) ? 10 : expiresInNum;
    updAuth({ expiresInRaw: String(Math.max(1, Math.min(90, cur + delta))) });
  };
  const customValidity = !!auth.customValidity;
  const validity = auth.validity || '10';
  const validityOptions = [
    { value: '30s', label: '30 seconds' },
    { value: '1',   label: '1 minute' },
    { value: '2',   label: '2 minutes' },
    { value: '3',   label: '3 minutes' },
    { value: '5',   label: '5 minutes' },
    { value: '10',  label: '10 minutes' },
    { value: '15',  label: '15 minutes' },
  ];

  const deliveryOpts = [
    { id: 'zero',  title: t.authZeroTap,  desc: t.authZeroTapDesc,  enabled: false },
    { id: 'one',   title: t.authOneTap,   desc: t.authOneTapDesc,   enabled: false },
    { id: 'copy',  title: t.authCopyCode, desc: t.authCopyCodeDesc, enabled: true  },
  ];

  return (
    <div className="tpl-auth-step">
      {/* === Code delivery setup === */}
      <div className="tpl-auth-section">
        <div className="tpl-auth-section-title">{t.authCodeDeliveryTitle}</div>
        <div className="tpl-auth-radio-list">
          {deliveryOpts.map(o => (
            <div
              key={o.id}
              className={`tpl-auth-radio-row ${delivery === o.id ? 'selected' : ''} ${!o.enabled ? 'disabled' : ''}`}
              onClick={() => o.enabled && updAuth({ delivery: o.id })}
            >
              <span className={`tpl-flow-type-radio ${delivery === o.id && o.enabled ? 'on' : ''}`} />
              <div className="tpl-auth-radio-meta">
                <div className="name">
                  {o.title}
                  <IcInfo size={13} stroke={1.7} className="info" />
                  {!o.enabled && <span className="coming">.{t.comingSoon}</span>}
                </div>
                <div className="desc">{o.desc}</div>
              </div>
            </div>
          ))}
        </div>
      </div>

      {/* === Content === */}
      <div className="tpl-auth-section">
        <div className="tpl-auth-section-title">{t.authContentTitle}</div>
        <div className="tpl-auth-section-help">{t.authContentHelp}</div>
        <label className="tpl-auth-check">
          <span
            className={`tpl-auth-check-box ${addSecurity ? 'on' : ''}`}
            onClick={() => updAuth({ addSecurity: !addSecurity })}
          >
            {addSecurity && <IcCheck size={11} stroke={3} />}
          </span>
          <span className="lbl">{t.authAddSecurity}</span>
        </label>
        <label className="tpl-auth-check">
          <span
            className={`tpl-auth-check-box ${addExpiration ? 'on' : ''}`}
            onClick={() => updAuth({ addExpiration: !addExpiration })}
          >
            {addExpiration && <IcCheck size={11} stroke={3} />}
          </span>
          <span className="lbl">{t.authAddExpiration}</span>
        </label>
        {addExpiration && (
          <div className={`tpl-auth-expires-panel ${expiresErr ? 'has-error' : ''}`}>
            <label className="tpl-field-label">{t.authExpiresIn}</label>
            <div className="tpl-auth-expires-row">
              <input
                type="text"
                inputMode="numeric"
                className={`tpl-field-input tpl-auth-expires-num ${expiresErr ? 'has-error' : 'is-valid'}`}
                value={expiresInRaw}
                onChange={(e) => updAuth({ expiresInRaw: e.target.value.replace(/[^\d]/g, '').slice(0, 3) })}
              />
              <span className="tpl-auth-expires-unit">{t.authMinutesUnit}</span>
              <span className="tpl-auth-expires-spin">
                <button type="button" aria-label="Increase" onClick={() => bumpExpires(1)}><IcChevronUp size={12} stroke={2} /></button>
                <button type="button" aria-label="Decrease" onClick={() => bumpExpires(-1)}><IcChevronDown size={12} stroke={2} /></button>
              </span>
            </div>
            {expiresErr && (
              <div className="tpl-auth-expires-err">
                <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><circle cx="12" cy="12" r="10"/><line x1="5" y1="5" x2="19" y2="19"/></svg>
                <span>{t.authExpiresErr}</span>
              </div>
            )}
          </div>
        )}
      </div>

      {/* === Message validity period === */}
      <div className="tpl-auth-section">
        <div className="tpl-auth-section-title">
          {t.authValidityTitle} <IcInfo size={13} stroke={1.7} className="info" />
        </div>
        <label className="tpl-auth-toggle-row">
          <span
            className={`tpl-auth-toggle ${customValidity ? 'on' : ''}`}
            onClick={() => updAuth({ customValidity: !customValidity })}
          >
            <span className="thumb" />
          </span>
          <span className="tpl-auth-toggle-meta">
            <span className="lbl">{t.authValidityToggle}</span>
            <span className="desc">{t.authValidityHelp}</span>
          </span>
        </label>
        {customValidity && (
          <div className="tpl-auth-validity-field">
            <label className="tpl-field-label">
              {t.authValidityLabel} <IcInfo size={12} stroke={1.7} className="info" />
            </label>
            <TplDropdown
              value={validity}
              onChange={(v) => updAuth({ validity: v })}
              options={validityOptions}
            />
          </div>
        )}
      </div>
    </div>
  );
};

// ---- Flow Preview modal (interactive ratings) ----
const TplFlowPreview = ({ t, onClose }) => {
  const questions = [
    { id: 'q1', label: 'Quality of our products aroob' },
    { id: 'q2', label: 'Customer service experience' },
    { id: 'q3', label: 'Likelihood to recommend' },
  ];
  const [answers, setAnswers] = useStateW({});
  const allAnswered = questions.every(q => answers[q.id]);
  const select = (qid, n) => setAnswers(prev => ({ ...prev, [qid]: n }));

  return (
    <div className="tpl-flow-preview-scrim" onClick={onClose}>
      <div className="tpl-flow-preview-modal" onClick={(e) => e.stopPropagation()}>
        <div className="tpl-flow-preview-head">
          <div>
            <div className="tpl-flow-preview-title">{t.flowPreview || 'Preview'}</div>
            <div className="tpl-flow-preview-sub">{t.flowPreviewSub || 'You can interact with your Flow the way customers would in their chat with you.'}</div>
          </div>
          <button type="button" className="tpl-flow-preview-close" onClick={onClose}>
            <IcClose size={18} stroke={2} />
          </button>
        </div>
        <div className="tpl-flow-preview-body">
          <div className="tpl-flow-preview-phone">
            <div className="tpl-flow-preview-phone-bar" />
            <div className="tpl-flow-preview-phone-head">
              <button type="button" className="tpl-flow-preview-phone-close"><IcClose size={14} stroke={2} /></button>
              <span className="tpl-flow-preview-phone-title">{t.flowScreenHelp || 'Help us improve'}</span>
              <span className="tpl-flow-preview-phone-more">⋮</span>
            </div>
            <div className="tpl-flow-preview-phone-body">
              <h3 className="tpl-flow-preview-phone-h">{t.flowScreenHelp || 'Help us improve'}</h3>
              {questions.map((q, qi) => (
                <React.Fragment key={q.id}>
                  {qi > 0 && <div className="tpl-flow-preview-phone-divider" />}
                  <p className="tpl-flow-preview-phone-q">{q.label}</p>
                  <div className="tpl-flow-preview-phone-sub">Rating</div>
                  {[1, 2, 3, 4, 5].map(n => {
                    const isSelected = answers[q.id] === n;
                    return (
                      <div
                        key={q.id + '-' + n}
                        className="tpl-flow-preview-phone-row"
                        onClick={() => select(q.id, n)}
                      >
                        <span>{n}</span>
                        <span className={`tpl-flow-preview-phone-radio ${isSelected ? 'is-selected' : ''}`} />
                      </div>
                    );
                  })}
                </React.Fragment>
              ))}
            </div>
            <div className="tpl-flow-preview-phone-foot">
              <button type="button" className={`tpl-flow-preview-phone-send ${allAnswered ? 'is-active' : ''}`} disabled={!allAnswered}>Send responses</button>
              <div className="tpl-flow-preview-phone-managed">Managed by the business. <span>Learn more</span></div>
            </div>
          </div>
        </div>
        <div className="tpl-flow-preview-foot">
          <button type="button" className="btn btn-secondary" onClick={onClose}>{t.close || 'Close'}</button>
        </div>
      </div>
    </div>
  );
};

// ---- Media-sample icons (used in the custom dropdown) ----
const MS_ICON = {
  image: (
    <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#6b7280" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round">
      <rect x="3" y="3" width="18" height="18" rx="2"/><circle cx="9" cy="9" r="2"/><path d="M21 15l-5-5L5 21"/>
    </svg>
  ),
  video: (
    <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#6b7280" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round">
      <circle cx="12" cy="12" r="9"/><polygon points="10 8 16 12 10 16 10 8" fill="#6b7280" stroke="#6b7280"/>
    </svg>
  ),
  document: (
    <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#6b7280" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round">
      <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/><line x1="9" y1="13" x2="15" y2="13"/><line x1="9" y1="17" x2="15" y2="17"/>
    </svg>
  ),
  location: (
    <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#6b7280" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round">
      <path d="M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z"/><circle cx="12" cy="10" r="3"/>
    </svg>
  ),
};

// Compute fixed-position coordinates for a dropdown menu so it can render
// above any clipping ancestor. Decides drop direction (up vs down) based on
// available viewport space. Returns { style, dropUp } — apply style to the
// fixed-positioned menu.
const useDropPosition = (wrapRef, menuRef, open) => {
  const [state, setState] = useStateW({ style: { display: 'none' }, dropUp: false });
  useEffectW(() => {
    if (!open) { setState({ style: { display: 'none' }, dropUp: false }); return; }
    const recalc = () => {
      const trig = wrapRef.current;
      if (!trig) return;
      const r = trig.getBoundingClientRect();
      const menuH = (menuRef.current && menuRef.current.offsetHeight) || 280;
      const gap = 6;
      const spaceBelow = window.innerHeight - r.bottom;
      const spaceAbove = r.top;
      const dropUp = spaceBelow < menuH + gap && spaceAbove > spaceBelow;
      const style = {
        position: 'fixed',
        left: Math.round(r.left),
        width: Math.round(r.width),
        zIndex: 10000,
      };
      if (dropUp) style.bottom = Math.round(window.innerHeight - r.top + gap);
      else style.top = Math.round(r.bottom + gap);
      setState({ style, dropUp });
    };
    recalc();
    window.addEventListener('resize', recalc);
    window.addEventListener('scroll', recalc, true);
    // Re-measure after the menu first renders, in case our height estimate
    // was off and the choice between drop-up vs drop-down would flip.
    const id = setTimeout(recalc, 0);
    return () => {
      clearTimeout(id);
      window.removeEventListener('resize', recalc);
      window.removeEventListener('scroll', recalc, true);
    };
  }, [open]);
  return state;
};

// ---- Reusable text-only dropdown (matches the Media sample design,
//      minus the per-row leading icon). Use this for any select that
//      doesn't need icons. ----
const TplDropdown = ({ value, onChange, options, placeholder, disabled = false, className = '' }) => {
  const [open, setOpen] = useStateW(false);
  const wrapRef = useRefW();
  const menuRef = useRefW();
  const { style: menuStyle, dropUp } = useDropPosition(wrapRef, menuRef, open);

  const current = options.find(o => String(o.value) === String(value)) ||
                  (placeholder ? { value: '', label: placeholder } : (options[0] || { value: '', label: '' }));

  useEffectW(() => {
    if (!open) return;
    const onDoc = (e) => {
      const inTrig = wrapRef.current && wrapRef.current.contains(e.target);
      const inMenu = menuRef.current && menuRef.current.contains(e.target);
      if (!inTrig && !inMenu) setOpen(false);
    };
    document.addEventListener('mousedown', onDoc);
    return () => document.removeEventListener('mousedown', onDoc);
  }, [open]);

  return (
    <div className={`tpl-icon-select tpl-dropdown ${open ? 'is-open' : ''} ${dropUp ? 'drop-up' : ''} ${disabled ? 'is-disabled' : ''} ${className}`} ref={wrapRef}>
      <button
        type="button"
        className="tpl-icon-select-trigger"
        onClick={() => !disabled && setOpen(o => !o)}
        disabled={disabled}
        aria-haspopup="listbox"
        aria-expanded={open}
      >
        <span className="tpl-icon-select-current">
          <span>{current.label}</span>
        </span>
        <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="#6b7280" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className="tpl-icon-select-chev"><polyline points="6 9 12 15 18 9"/></svg>
      </button>
      {open && !disabled && (
        <div className="tpl-icon-select-menu tpl-icon-select-menu-fixed" role="listbox" ref={menuRef} style={menuStyle}>
          {options.map((o) => {
            const selected = String(o.value) === String(value);
            return (
              <div
                key={String(o.value)}
                className={`tpl-icon-select-row ${selected ? 'is-selected' : ''}`}
                role="option"
                aria-selected={selected}
                onClick={() => { onChange(o.value); setOpen(false); }}
              >
                <span className="tpl-icon-select-label">{o.label}</span>
              </div>
            );
          })}
        </div>
      )}
    </div>
  );
};

// ---- Custom dropdown for "Media sample" (icon + radio per row) ----
const TplMediaSampleSelect = ({ value, onChange, t }) => {
  const [open, setOpen] = useStateW(false);
  const wrapRef = useRefW();
  const menuRef = useRefW();
  const { style: menuStyle, dropUp } = useDropPosition(wrapRef, menuRef, open);
  const opts = [
    { v: 'none',     label: 'None' },
    { v: 'image',    label: 'Image',    icon: MS_ICON.image },
    { v: 'video',    label: 'Video',    icon: MS_ICON.video },
    { v: 'document', label: 'Document', icon: MS_ICON.document },
    { v: 'location', label: 'Location', icon: MS_ICON.location },
  ];
  const current = opts.find(o => o.v === (value || 'none')) || opts[0];

  useEffectW(() => {
    if (!open) return;
    const onDoc = (e) => {
      const inTrig = wrapRef.current && wrapRef.current.contains(e.target);
      const inMenu = menuRef.current && menuRef.current.contains(e.target);
      if (!inTrig && !inMenu) setOpen(false);
    };
    document.addEventListener('mousedown', onDoc);
    return () => document.removeEventListener('mousedown', onDoc);
  }, [open]);

  return (
    <div className={`tpl-icon-select ${open ? 'is-open' : ''} ${dropUp ? 'drop-up' : ''}`} ref={wrapRef}>
      <button
        type="button"
        className="tpl-icon-select-trigger"
        onClick={() => setOpen(o => !o)}
        aria-haspopup="listbox"
        aria-expanded={open}
      >
        <span className="tpl-icon-select-current">
          {current.icon && <span className="tpl-icon-select-ic">{current.icon}</span>}
          <span>{current.label}</span>
        </span>
        <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="#6b7280" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className="tpl-icon-select-chev"><polyline points="6 9 12 15 18 9"/></svg>
      </button>
      {open && (
        <div className="tpl-icon-select-menu tpl-icon-select-menu-fixed" role="listbox" ref={menuRef} style={menuStyle}>
          {opts.map(o => {
            const selected = o.v === (value || 'none');
            return (
              <div
                key={o.v}
                className={`tpl-icon-select-row ${selected ? 'is-selected' : ''}`}
                role="option"
                aria-selected={selected}
                onClick={() => { onChange(o.v); setOpen(false); }}
              >
                <span className="tpl-icon-select-ic">{o.icon || null}</span>
                <span className="tpl-icon-select-label">{o.label}</span>
              </div>
            );
          })}
        </div>
      )}
    </div>
  );
};

// ---- Emoji picker (small, self-contained) ----
const EMOJI_CATEGORIES = [
  { id: 'recent', tabIcon: (<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><circle cx="12" cy="12" r="10"/><polyline points="12 7 12 12 15 14"/></svg>), label: 'Recently Used', emojis: [] },
  { id: 'smileys', tabIcon: (<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><circle cx="12" cy="12" r="10"/><path d="M8 14s1.5 2 4 2 4-2 4-2"/><line x1="9" y1="9" x2="9.01" y2="9"/><line x1="15" y1="9" x2="15.01" y2="9"/></svg>), label: 'Smileys & People', emojis: ['😀','😃','😄','😁','😆','😅','🤣','😂','🙂','🙃','😉','😊','😇','🥰','😍','🤩','😘','😗','😚','😙','😋','😛','😜','🤪','😝','🤑','🤗','🤭','🤫','🤔','🤐','🤨','😐','😑','😶','😏','😒','🙄','😬','🤥','😌','😔','😪','🤤','😴','😷','🤒','🤕','🤢','🤮','🤧','🥵','🥶','🥴','😵','🤯','🤠','🥳','😎','🤓','🧐','😕','😟','🙁','☹️','😮','😯','😲','😳','🥺','😦','😧','😨','😰','😥','😢','😭','😱','😖','😣','😞','😓','😩','😫','🥱','😤','😡','😠','🤬','😈','👿','💀','☠️','💩','🤡','👹','👺','👻','👽','👾','🤖','👋','🤚','🖐️','✋','🖖','👌','🤏','✌️','🤞','🤟','🤘','🤙','👈','👉','👆','🖕','👇','☝️','👍','👎','✊','👊','🤛','🤜','👏','🙌','👐','🤲','🙏'] },
  { id: 'animals', tabIcon: (<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><path d="M3 12c0-5 4-9 9-9s9 4 9 9-4 9-9 9-9-4-9-9z"/><path d="M8 9h.01M16 9h.01"/><path d="M8 14c1 1.5 2.5 2 4 2s3-.5 4-2"/></svg>), label: 'Animals & Nature', emojis: ['🐶','🐱','🐭','🐹','🐰','🦊','🐻','🐼','🐨','🐯','🦁','🐮','🐷','🐽','🐸','🐵','🙈','🙉','🙊','🐒','🐔','🐧','🐦','🐤','🐣','🐥','🦆','🦅','🦉','🦇','🐺','🐗','🐴','🦄','🐝','🐛','🦋','🐌','🐞','🐜','🦗','🕷️','🕸️','🦂','🦟','🦠','🐢','🐍','🦎','🦖','🦕','🐙','🦑','🦐','🦞','🦀','🐡','🐠','🐟','🐬','🐳','🐋','🦈','🐊','🐅','🐆','🦓','🦍','🦧','🐘','🦛','🦏','🐪','🐫','🦒','🦘','🐃','🐂','🐄','🐎','🐖','🐏','🐑','🦙','🐐','🦌','🐕','🐩','🦮','🐕‍🦺','🐈','🐓','🦃','🦚','🦜','🦢','🦩','🕊️','🐇','🦝','🦨','🦡','🦦','🦥','🐁','🐀','🐿️','🦔','🌲','🌳','🌴','🌵','🌿','☘️','🍀','🎍','🎋','🍃','🍂','🍁','🍄','🌾','💐','🌷','🌹','🥀','🌺','🌸','🌼','🌻'] },
  { id: 'food', tabIcon: (<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><circle cx="12" cy="12" r="10"/><circle cx="12" cy="12" r="6"/><circle cx="12" cy="12" r="2"/></svg>), label: 'Food & Drink', emojis: ['🍏','🍎','🍐','🍊','🍋','🍌','🍉','🍇','🍓','🍈','🍒','🍑','🥭','🍍','🥥','🥝','🍅','🍆','🥑','🥦','🥬','🥒','🌶️','🌽','🥕','🥔','🍠','🥐','🥯','🍞','🥖','🥨','🧀','🥚','🍳','🧈','🥞','🧇','🥓','🥩','🍗','🍖','🦴','🌭','🍔','🍟','🍕','🥪','🥙','🧆','🌮','🌯','🥗','🥘','🥫','🍝','🍜','🍲','🍛','🍣','🍱','🥟','🍤','🍙','🍚','🍘','🍥','🥮','🥠','🍢','🍡','🍧','🍨','🍦','🥧','🧁','🍰','🎂','🍮','🍭','🍬','🍫','🍿','🍩','🍪','🌰','🥜','🍯','🥛','🍼','☕','🍵','🍶','🍾','🍷','🍸','🍹','🍺','🍻','🥂','🥃','🥤','🧃','🧉','🧊'] },
  { id: 'sports', tabIcon: (<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><circle cx="12" cy="12" r="10"/><path d="M2 12h20M12 2v20M5 5l14 14M19 5L5 19"/></svg>), label: 'Activity', emojis: ['⚽','🏀','🏈','⚾','🥎','🎾','🏐','🏉','🥏','🎱','🪀','🏓','🏸','🏒','🏑','🥍','🏏','🥅','⛳','🪁','🏹','🎣','🤿','🥊','🥋','🎽','🛹','🛼','🛷','⛸️','🥌','🎿','⛷️','🏂','🪂','🏋️','🤼','🤸','⛹️','🤺','🤾','🏌️','🏇','🧘','🏄','🏊','🤽','🚣','🧗','🚵','🚴','🏆','🥇','🥈','🥉','🏅','🎖️','🏵️','🎗️','🎫','🎟️','🎪','🤹','🎭','🩰','🎨','🎬','🎤','🎧','🎼','🎹','🥁','🎷','🎺','🎸','🪕','🎻','🎲','♟️','🎯','🎳','🎮','🎰','🧩'] },
  { id: 'travel', tabIcon: (<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><circle cx="12" cy="10" r="3"/><path d="M12 2C8 2 5 5 5 9c0 5 7 13 7 13s7-8 7-13c0-4-3-7-7-7z"/></svg>), label: 'Travel & Places', emojis: ['🚗','🚕','🚙','🚌','🚎','🏎️','🚓','🚑','🚒','🚐','🛻','🚚','🚛','🚜','🛴','🚲','🛵','🏍️','🛺','🚨','🚔','🚍','🚘','🚖','🚡','🚠','🚟','🚃','🚋','🚞','🚝','🚄','🚅','🚈','🚂','🚆','🚇','🚊','🚉','✈️','🛫','🛬','🛩️','💺','🛰️','🚀','🛸','🚁','🛶','⛵','🚤','🛥️','🛳️','⛴️','🚢','⚓','⛽','🚧','🚦','🚥','🗺️','🗿','🗽','🗼','🏰','🏯','🏟️','🎡','🎢','🎠','⛲','⛱️','🏖️','🏝️','🏜️','🌋','⛰️','🏔️','🗻','🏕️','⛺','🏠','🏡','🏘️','🏚️','🏗️','🏭','🏢','🏬','🏣','🏤','🏥','🏦','🏨','🏪','🏫','🏩','💒','🏛️','⛪','🕌','🛕','🕍','🕋','⛩️','🗾','🎑','🏞️','🌅','🌄','🌠','🎇','🎆','🌇','🌆','🏙️','🌃','🌌','🌉','🌁'] },
  { id: 'objects', tabIcon: (<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><path d="M9 18h6M10 22h4M12 2a7 7 0 0 0-4 12.5l1 1.5h6l1-1.5A7 7 0 0 0 12 2z"/></svg>), label: 'Objects', emojis: ['💡','🔦','🕯️','🪔','🧯','🛢️','💸','💵','💴','💶','💷','💰','💳','💎','⚖️','🧰','🔧','🔨','⚒️','🛠️','⛏️','🪛','🪚','🔩','⚙️','🧱','🔫','💣','🧨','🪓','🔪','🗡️','⚔️','🛡️','🚬','⚰️','⚱️','🏺','🔮','📿','💈','⚗️','🔭','🔬','🕳️','💊','💉','🩸','🩹','🩺','🌡️','🧹','🧺','🧻','🚽','🚰','🚿','🛁','🛀','🧼','🪒','🧽','🧴','🛎️','🔑','🗝️','🚪','🪑','🛋️','🛏️','🛌','🧸','🖼️','🪞','🪟','🛍️','🛒','🎁','🎀','🎉','🎊','🎈','🎂','🎄','🎋','🎍','🎎','🎏','🎐','🎑','🧧','🎀','🎁','🎗️','🎫','🎟️'] },
  { id: 'symbols', tabIcon: (<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"/></svg>), label: 'Symbols', emojis: ['❤️','🧡','💛','💚','💙','💜','🖤','🤍','🤎','💔','❣️','💕','💞','💓','💗','💖','💘','💝','💟','☮️','✝️','☪️','🕉️','☸️','✡️','🔯','🕎','☯️','☦️','🛐','⛎','♈','♉','♊','♋','♌','♍','♎','♏','♐','♑','♒','♓','🆔','⚛️','🉑','☢️','☣️','📴','📳','🈶','🈚','🈸','🈺','🈷️','✴️','🆚','💮','🉐','㊙️','㊗️','🈴','🈵','🈹','🈲','🅰️','🅱️','🆎','🆑','🅾️','🆘','❌','⭕','🛑','⛔','📛','🚫','💯','💢','♨️','🚷','🚯','🚳','🚱','🔞','📵','🚭','❗','❕','❓','❔','‼️','⁉️','🔅','🔆','〽️','⚠️','🚸','🔱','⚜️','🔰','♻️','✅','🈯','💹','❇️','✳️','❎','🌐','💠','Ⓜ️','🌀','💤','🏧','🚾','♿','🅿️','🈳','🈂️','🛂','🛃','🛄','🛅','🚹','🚺','🚼','🚻','🚮','🎦','📶','🈁','🔣','ℹ️','🔤','🔡','🔠','🆖','🆗','🆙','🆒','🆕','🆓'] },
  { id: 'flags', tabIcon: (<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><path d="M4 22V4M4 4h13l-3 5 3 5H4"/></svg>), label: 'Flags', emojis: ['🏳️','🏴','🏁','🚩','🏳️‍🌈','🏴‍☠️','🇦🇪','🇦🇷','🇦🇹','🇦🇺','🇧🇪','🇧🇷','🇨🇦','🇨🇭','🇨🇱','🇨🇳','🇨🇴','🇨🇿','🇩🇪','🇩🇰','🇪🇬','🇪🇸','🇫🇮','🇫🇷','🇬🇧','🇬🇷','🇭🇰','🇭🇺','🇮🇩','🇮🇪','🇮🇱','🇮🇳','🇮🇶','🇮🇷','🇮🇹','🇯🇵','🇯🇴','🇰🇷','🇰🇼','🇱🇧','🇲🇦','🇲🇽','🇲🇾','🇳🇱','🇳🇴','🇳🇿','🇵🇭','🇵🇰','🇵🇱','🇵🇹','🇶🇦','🇷🇴','🇷🇺','🇸🇦','🇸🇪','🇸🇬','🇸🇰','🇹🇭','🇹🇷','🇺🇦','🇺🇸','🇻🇪','🇻🇳','🇾🇪','🇿🇦'] },
];

const TplEmojiPicker = ({ onSelect, onClose }) => {
  const [activeCat, setActiveCat] = useStateW('smileys');
  const [recent, setRecent] = useStateW(() => {
    try { return JSON.parse(localStorage.getItem('tpl-emoji-recent') || '[]'); } catch { return []; }
  });
  const wrapRef = useRefW();

  useEffectW(() => {
    const onDoc = (e) => { if (wrapRef.current && !wrapRef.current.contains(e.target)) onClose && onClose(); };
    document.addEventListener('mousedown', onDoc);
    return () => document.removeEventListener('mousedown', onDoc);
  }, [onClose]);

  const pick = (e) => {
    onSelect && onSelect(e);
    const next = [e, ...recent.filter(x => x !== e)].slice(0, 16);
    setRecent(next);
    try { localStorage.setItem('tpl-emoji-recent', JSON.stringify(next)); } catch {}
  };

  // The "Recently Used" header is only shown if there are any.
  const cat = EMOJI_CATEGORIES.find(c => c.id === activeCat) || EMOJI_CATEGORIES[1];

  return (
    <div className="tpl-emoji-picker" ref={wrapRef} onMouseDown={(e) => e.stopPropagation()}>
      <div className="tpl-emoji-picker-body">
        {recent.length > 0 && (
          <>
            <div className="tpl-emoji-section-title">Recently Used</div>
            <div className="tpl-emoji-grid">
              {recent.map((em, i) => (
                <button key={'r-' + i} type="button" className="tpl-emoji-btn" onClick={() => pick(em)}>{em}</button>
              ))}
            </div>
          </>
        )}
        <div className="tpl-emoji-section-title">{cat.label}</div>
        <div className="tpl-emoji-grid">
          {cat.emojis.map((em, i) => (
            <button key={cat.id + '-' + i} type="button" className="tpl-emoji-btn" onClick={() => pick(em)}>{em}</button>
          ))}
        </div>
      </div>
      <div className="tpl-emoji-tabs">
        {EMOJI_CATEGORIES.filter(c => c.id !== 'recent' || recent.length > 0).map(c => (
          <button
            key={c.id}
            type="button"
            className={`tpl-emoji-tab ${activeCat === c.id ? 'is-active' : ''}`}
            onClick={() => setActiveCat(c.id)}
            title={c.label}
          >{c.tabIcon}</button>
        ))}
      </div>
    </div>
  );
};

// ---- Step 2: Message Structure ----
const TplWizardStep2 = ({ data, setData, t, onOpenFlowType, onOpenFlowEditor }) => {
  const hasFlow = data.flow && data.flow.type;

  // Authentication category uses a different Step 2 layout
  if (data.category === 'Authentication') {
    return <TplWizardStep2Auth data={data} setData={setData} t={t} />;
  }

  // Refs to the header input and body textarea so we can place the caret
  // between {{}} after inserting an empty Name variable.
  const headerInputRef = useRefW();
  const bodyTextareaRef = useRefW();

  const MAX_HEADER = 60;
  const BODY_BASE_MAX = 1024;
  // Each variable in the body increases the budget by 4 characters
  // (so 1 var → 1028, 2 vars → 1032, etc. — leaves room for the sample value).
  const countBodyVars = (text) => ((text || '').match(/\{\{[^{}]*\}\}/g) || []).length;
  const bodyMaxFor = (text) => BODY_BASE_MAX + 4 * countBodyVars(text);
  const MAX_BODY = bodyMaxFor(data.body || '');

  // Build the next variable token based on the user's selected variable type.
  // Number variables are numbered INDEPENDENTLY per field:
  //   header starts at {{1}}; body starts at {{1}}.
  const nextVariableToken = (field /* 'header' | 'body' */) => {
    const kind = data.variableType || 'Number';
    if (kind === 'Number') {
      const text = field === 'header' ? (data.header || '') : (data.body || '');
      const nums = [...text.matchAll(/\{\{\s*(\d+)\s*\}\}/g)].map(m => parseInt(m[1], 10));
      const next = (nums.length ? Math.max(...nums) : 0) + 1;
      return `{{${next}}}`;
    }
    return '{{}}';
  };

  const insertVariable = (field /* 'header' | 'body' */) => {
    const token = nextVariableToken(field);
    const cur = data[field] || '';
    const el = field === 'body' ? bodyTextareaRef.current : headerInputRef.current;
    let start = cur.length, end = cur.length;
    if (el && typeof el.selectionStart === 'number') {
      start = el.selectionStart;
      end = el.selectionEnd;
    }
    const before = cur.slice(0, start);
    const after = cur.slice(end);
    const needsLeadingSpace = before && !/\s$/.test(before);
    const needsTrailingSpace = after && !/^\s/.test(after);
    const inserted = (needsLeadingSpace ? ' ' : '') + token + (needsTrailingSpace ? ' ' : '');
    const merged = before + inserted + after;
    const max = field === 'body' ? bodyMaxFor(merged) : MAX_HEADER;
    const next = merged.slice(0, max);
    setData({ ...data, [field]: next });
    // Drop the caret between the empty {{ }} for the Name flow.
    if (token === '{{}}' && el) {
      const caret = (before + (needsLeadingSpace ? ' ' : '') + '{{').length;
      setTimeout(() => { try { el.focus(); el.setSelectionRange(caret, caret); } catch {} }, 0);
    }
  };

  // Wrap selection (or insert at caret) with a pair of markdown-like marks.
  // Used by the Body toolbar (B/I/S/code/emoji).
  const wrapBody = (left, right) => {
    const el = bodyTextareaRef.current;
    if (!el) return;
    const cur = data.body || '';
    const s = el.selectionStart ?? cur.length;
    const e = el.selectionEnd ?? cur.length;
    const before = cur.slice(0, s);
    const sel = cur.slice(s, e);
    const after = cur.slice(e);
    const merged = before + left + sel + right + after;
    const next = merged.slice(0, bodyMaxFor(merged));
    setData({ ...data, body: next });
    setTimeout(() => {
      try {
        el.focus();
        const caretStart = (before + left).length;
        const caretEnd = caretStart + sel.length;
        el.setSelectionRange(caretStart, caretEnd || caretStart);
      } catch {}
    }, 0);
  };
  const insertAtCursorBody = (text) => wrapBody(text, '');

  // Emoji picker state — toggled by the smiley button in the body toolbar.
  const [emojiOpen, setEmojiOpen] = useStateW(false);

  // Extract unique variable tokens in order of first appearance.
  const extractVariableTokens = (text) => {
    const out = [];
    const seen = new Set();
    for (const m of String(text || '').matchAll(/\{\{[^{}]*\}\}/g)) {
      const tok = m[0];
      if (!seen.has(tok)) { seen.add(tok); out.push(tok); }
    }
    return out;
  };

  const headerTokens = extractVariableTokens(data.header);
  const bodyTokens = extractVariableTokens(data.body);
  const hasAnyVariables = headerTokens.length > 0 || bodyTokens.length > 0;
  const samples = data.samples || {};
  const updateSample = (token, val) => setData({ ...data, samples: { ...(data.samples || {}), [token]: val } });

  // Validate the body text against the rules the user described:
  //   - Format: each {{token}} must match the selected variable type
  //   - Length: body with any variables shorter than 140 chars triggers
  //   - Placement: any variable touching the start/end of the body
  const bodyValidation = (() => {
    const body = (data.body || '').trim();
    if (!body) return null;
    const kind = data.variableType || 'Number';
    const varRe = /\{\{\s*([^{}]*)\s*\}\}/g;
    const matches = [...body.matchAll(varRe)];
    if (!matches.length) return null;

    // Format check, per selected variable type
    let formatBad = false;
    for (const m of matches) {
      const inside = (m[1] || '').trim();
      if (inside === '') { formatBad = true; continue; }
      if (kind === 'Number') {
        if (!/^\d+$/.test(inside)) { formatBad = true; }
      } else { // Name
        if (!/^[a-z][a-z0-9_]*$/.test(inside)) { formatBad = true; }
      }
    }
    // Length check (only if the body has any variables)
    const lengthBad = body.length < 140;
    // Placement check
    const placementBad = /^\{\{[^{}]*\}\}/.test(body) || /\{\{[^{}]*\}\}$/.test(body);

    let main = null;
    if (formatBad) main = t.bodyErrFmt;
    else if (lengthBad) main = t.bodyErrLength;
    const parts = [];
    if (main) parts.push(main);
    if (placementBad) parts.push(t.bodyErrPlacement);
    return parts.length ? parts.join(' ') : null;
  })();

  return (
    <div>
      <div className="tpl-grid-3">
        <div className="tpl-field">
          <label className="tpl-field-label">{t.mediaSample} <span className="opt">{t.optional}</span></label>
          <TplMediaSampleSelect
            value={data.mediaSampleId || 'none'}
            onChange={(v) => setData({ ...data, mediaSampleId: v })}
            t={t}
          />
        </div>
        <div className="tpl-field">
          <label className="tpl-field-label">{t.typeOfVariable}</label>
          <TplDropdown
            value={data.variableType || 'Number'}
            onChange={(v) => setData({ ...data, variableType: v })}
            options={[
              { value: 'Number', label: t.varOptNumber || 'Number' },
              { value: 'Name', label: t.varOptName || 'Name' },
            ]}
          />
        </div>
      </div>

      {/* Header / Body / Footer — grouped panel with #F7F7F7 background */}
      <div className="tpl-msg-panel">
        {/* Header — text when mediaSample = none, upload zone otherwise */}
        {(!data.mediaSampleId || data.mediaSampleId === 'none') ? (
          <div className="tpl-field tpl-msg-field">
            <label className="tpl-field-label"><strong>{t.headerLbl}</strong> <span className="opt">{t.optional}</span></label>
            <div className="tpl-input-with-counter">
              <input
                ref={headerInputRef}
                className={`tpl-field-input ${(data.header || '').trim() ? 'is-valid' : ''}`}
                placeholder={t.headerPh}
                value={data.header || ''}
                onChange={(e) => setData({ ...data, header: e.target.value.slice(0, MAX_HEADER) })}
              />
              <span className="tpl-input-counter">{(data.header || '').length}/{MAX_HEADER}</span>
            </div>
            <div className="tpl-add-var-row">
              <span
                className="tpl-add-var-link"
                onClick={() => insertVariable('header')}
                role="button"
                tabIndex={0}
                style={{ cursor: 'pointer' }}
              >+ {t.addVariable}</span>
              <span className="tpl-add-var-info" aria-hidden="true"><IcInfo size={12} stroke={1.7} /></span>
            </div>
          </div>
        ) : data.mediaSampleId === 'location' ? (
          <div className="tpl-field tpl-msg-field">
            <label className="tpl-field-label"><strong>{t.headerLbl}</strong> <span className="opt">{t.optional}</span></label>
            <div className="tpl-input-with-counter">
              <input
                className="tpl-field-input"
                placeholder={t.headerPh}
                value={data.header || ''}
                disabled
                readOnly
              />
              <span className="tpl-input-counter">{(data.header || '').length}/{MAX_HEADER}</span>
            </div>
          </div>
        ) : (
          <div className="tpl-field tpl-msg-field">
            <label className="tpl-field-label"><strong>{t.headerLbl}</strong> <span className="opt">{t.optional}</span></label>
            <div className="tpl-media-drop">
              <div className="tpl-media-drop-title">Drag and drop to upload</div>
              <div className="tpl-media-drop-sub">Or <span className="tpl-media-drop-link">choose files on your device</span></div>
              <div className="tpl-media-drop-hint">
                {data.mediaSampleId === 'image' && 'JPG or PNG · max 5 MB'}
                {data.mediaSampleId === 'video' && 'MP4 · max 16 MB'}
                {data.mediaSampleId === 'document' && 'PDF · max 100 MB'}
              </div>
            </div>
          </div>
        )}

        {/* Body */}
        <div className="tpl-field tpl-msg-field">
          <label className="tpl-field-label"><strong>{t.bodyLbl}</strong></label>
          <div className="tpl-input-with-counter" style={{ position: 'relative' }}>
            <textarea
              ref={bodyTextareaRef}
              className={`tpl-field-textarea ${bodyValidation ? 'has-error' : ((data.body || '').trim() ? 'is-valid' : '')}`}
              placeholder={t.bodyPh}
              value={data.body || ''}
              onChange={(e) => {
                const val = e.target.value;
                setData({ ...data, body: val.slice(0, bodyMaxFor(val)) });
              }}
            ></textarea>
            <span className="tpl-input-counter tpl-body-counter" style={{ bottom: 8 }}>
              {(data.body || '').length}/{MAX_BODY}
              {bodyValidation && (
                <span className="tpl-body-counter-err" aria-hidden="true" title={bodyValidation}>
                  <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><circle cx="12" cy="12" r="10"/><line x1="5" y1="5" x2="19" y2="19"/></svg>
                </span>
              )}
            </span>
          </div>
          {bodyValidation && <div className="tpl-field-error">{bodyValidation}</div>}
          <div className="tpl-add-var-row tpl-body-toolbar" style={{ position: 'relative' }}>
            <span className="tpl-toolbar-spacer" />
            <span className={`tpl-toolbar-btn ${emojiOpen ? 'is-active' : ''}`} title={t.fmtEmoji} role="button" tabIndex={0} onClick={(e) => { e.stopPropagation(); setEmojiOpen(o => !o); }}>
              <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><circle cx="12" cy="12" r="10"/><path d="M8 14s1.5 2 4 2 4-2 4-2"/><line x1="9" y1="9" x2="9.01" y2="9"/><line x1="15" y1="9" x2="15.01" y2="9"/></svg>
            </span>
            {emojiOpen && (
              <TplEmojiPicker
                onSelect={(emoji) => insertAtCursorBody(emoji)}
                onClose={() => setEmojiOpen(false)}
              />
            )}
            <span className="tpl-toolbar-btn tpl-toolbar-glyph" title={t.fmtBold} role="button" tabIndex={0} onClick={() => wrapBody('*', '*')} style={{ fontWeight: 700 }}>B</span>
            <span className="tpl-toolbar-btn tpl-toolbar-glyph" title={t.fmtItalic} role="button" tabIndex={0} onClick={() => wrapBody('_', '_')} style={{ fontStyle: 'italic', fontFamily: 'serif' }}>I</span>
            <span className="tpl-toolbar-btn tpl-toolbar-glyph" title={t.fmtStrike} role="button" tabIndex={0} onClick={() => wrapBody('~', '~')} style={{ textDecoration: 'line-through' }}>S</span>
            <span className="tpl-toolbar-btn" title={t.fmtMono} role="button" tabIndex={0} onClick={() => wrapBody('```', '```')}>
              <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><polyline points="16 18 22 12 16 6"/><polyline points="8 6 2 12 8 18"/></svg>
            </span>
            <span
              className="tpl-add-var-link"
              onClick={() => insertVariable('body')}
              role="button"
              tabIndex={0}
              style={{ cursor: 'pointer' }}
            >+ {t.addVariable}</span>
            <span className="tpl-add-var-info" aria-hidden="true"><IcInfo size={12} stroke={1.7} /></span>
          </div>
        </div>

        {/* Footer */}
        <div className="tpl-field tpl-msg-field">
          <label className="tpl-field-label"><strong>{t.footerLbl}</strong> <span className="opt">{t.optional}</span></label>
          <div className="tpl-input-with-counter">
            <input className={`tpl-field-input ${(data.footer || '').trim() ? 'is-valid' : ''}`} placeholder={t.footerPh} value={data.footer || ''} onChange={(e) => setData({ ...data, footer: e.target.value.slice(0, 60) })} />
            <span className="tpl-input-counter">{(data.footer || '').length}/60</span>
          </div>
        </div>
      </div>

      {/* Variable Samples — appears whenever a variable exists in header or body */}
      {hasAnyVariables && (
        <div className="tpl-var-samples">
          <div className="tpl-var-samples-title">{t.variableSamples}</div>
          <div className="tpl-var-samples-desc">{t.variableSamplesDesc}</div>
          {headerTokens.length > 0 && (
            <div className="tpl-var-samples-section">
              <div className="tpl-var-samples-section-title">{t.headerLbl}</div>
              {headerTokens.map(tok => {
                const v = samples[tok] || '';
                const err = !v;
                return (
                  <div className="tpl-var-sample-row" key={'h-' + tok}>
                    <div className="tpl-var-sample-chip">{tok}</div>
                    <div className="tpl-var-sample-input-col">
                      <div className="tpl-input-with-counter">
                        <input
                          className={`tpl-field-input ${err ? 'has-error' : 'is-valid'}`}
                          placeholder={`${t.sampleEnterContent} ${tok}`}
                          value={v}
                          onChange={(e) => updateSample(tok, e.target.value)}
                        />
                        {err && (
                          <span className="tpl-input-counter tpl-var-sample-err" aria-hidden="true">
                            <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><circle cx="12" cy="12" r="10"/><line x1="5" y1="5" x2="19" y2="19"/></svg>
                          </span>
                        )}
                      </div>
                      {err && <div className="tpl-var-sample-add">{t.addSampleText}</div>}
                    </div>
                  </div>
                );
              })}
            </div>
          )}
          {bodyTokens.length > 0 && (
            <div className="tpl-var-samples-section">
              <div className="tpl-var-samples-section-title">{t.bodyLbl}</div>
              {bodyTokens.map(tok => {
                const v = samples[tok] || '';
                const err = !v;
                return (
                  <div className="tpl-var-sample-row" key={'b-' + tok}>
                    <div className="tpl-var-sample-chip">{tok}</div>
                    <div className="tpl-var-sample-input-col">
                      <div className="tpl-input-with-counter">
                        <input
                          className={`tpl-field-input ${err ? 'has-error' : 'is-valid'}`}
                          placeholder={`${t.sampleEnterContent} ${tok}`}
                          value={v}
                          onChange={(e) => updateSample(tok, e.target.value)}
                        />
                        {err && (
                          <span className="tpl-input-counter tpl-var-sample-err" aria-hidden="true">
                            <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><circle cx="12" cy="12" r="10"/><line x1="5" y1="5" x2="19" y2="19"/></svg>
                          </span>
                        )}
                      </div>
                      {err && <div className="tpl-var-sample-add">{t.addSampleText}</div>}
                    </div>
                  </div>
                );
              })}
            </div>
          )}
        </div>
      )}

      {/* Buttons */}
      <div className="tpl-field" style={{ marginTop: 18 }}>
        <label className="tpl-field-label"><strong>{t.buttonsLbl}</strong> <span className="opt">{t.optional}</span></label>
        <div className="tpl-buttons-help">{t.buttonsHelp}</div>

        {/* Add-button control sits right under the Buttons label; added buttons render below it. */}
        <TplAddButton
          buttons={data.buttons || []}
          hasFlow={!!hasFlow}
          category={data.category}
          t={t}
          onAdd={(kind) => {
            if (kind === 'flow') {
              // Image 1 — show the empty flow card with Create new / Use existing pickers
              setData({ ...data, flow: { type: 'placeholder', icon: 'default', buttonText: '' } });
              return;
            }
            const id = 'b' + Date.now();
            const defaults = {
              custom:  { id, kind: 'custom',  text: 'Reply' },
              visit:   { id, kind: 'visit',   text: 'Visit website', url: 'https://' },
              wa:      { id, kind: 'wa',      text: 'Call on WhatsApp', phone: '' },
              phone:   { id, kind: 'phone',   text: 'Call phone number', phone: '' },
              copy:    { id, kind: 'copy',    text: 'Copy offer code', code: '' },
            };
            setData({ ...data, buttons: [...(data.buttons || []), defaults[kind]] });
          }}
        />

        {/* Quick Reply section (custom buttons) */}
        {(data.buttons || []).some(b => b.kind === 'custom') && (
          <div className="tpl-btn-section-head">
            <strong>{t.btnSectionQuickReply}</strong> <span className="opt">{t.optional}</span>
          </div>
        )}
        {(data.buttons || []).map((b, i) => b.kind !== 'custom' ? null : (
          <TplButtonCard
            key={b.id}
            button={b}
            index={i}
            t={t}
            onChange={(next) => {
              const list = [...(data.buttons || [])];
              list[i] = next;
              setData({ ...data, buttons: list });
            }}
            onRemove={() => {
              const list = (data.buttons || []).filter((_, j) => j !== i);
              setData({ ...data, buttons: list });
            }}
            onEditFlow={onOpenFlowType}
          />
        ))}

        {/* Call to Action section (visit, wa, phone, copy) */}
        {((data.buttons || []).some(b => b.kind !== 'custom') || hasFlow) && (
          <div className="tpl-btn-section-head">
            <strong>{t.btnSectionCallToAction}</strong> <span className="opt">{t.optional}</span>
          </div>
        )}
        {(data.buttons || []).map((b, i) => b.kind === 'custom' ? null : (
          <TplButtonCard
            key={b.id}
            button={b}
            index={i}
            t={t}
            onChange={(next) => {
              const list = [...(data.buttons || [])];
              list[i] = next;
              setData({ ...data, buttons: list });
            }}
            onRemove={() => {
              const list = (data.buttons || []).filter((_, j) => j !== i);
              setData({ ...data, buttons: list });
            }}
            onEditFlow={onOpenFlowType}
          />
        ))}

        {/* Auto-added flow button (from flow type modal / editor) — rendered ABOVE Add Button */}
        {hasFlow && (() => {
          const flowSaved = !!data.flow?.name;
          const flowFile = data.flow?.name ? data.flow.name.toLowerCase().replace(/\s+/g, '-') : '';
          return (
          <div className="tpl-flow-card">
            <div className="tpl-flow-card-head">
              <span className="title"><span className="ic"><IcGrid size={15} stroke={1.7} /></span> {t.flowComplete}</span>
              <span className="remove" onClick={() => setData({ ...data, flow: null })}>
                <IcClose size={14} stroke={2} /> {t.flowRemove}
              </span>
            </div>
            <div className="tpl-flow-card-body">
              <div className="row-2 row-narrow-wide">
                <div className="tpl-field">
                  <label className="tpl-field-label">{t.btnCardButtonIcon || t.flowButtonIcon}</label>
                  <TplDropdown
                    value={data.flow.icon || 'default'}
                    onChange={(v) => setData({ ...data, flow: { ...data.flow, icon: v } })}
                    options={[
                      { value: 'default',  label: t.flowDefaultIcon },
                      { value: 'document', label: t.flowIconDocument || 'Document' },
                      { value: 'promotion',label: t.flowIconPromotion || 'Promotion' },
                      { value: 'review',   label: t.flowIconReview || 'Review' },
                    ]}
                  />
                </div>
                <div className="tpl-field tpl-flow-btntext">
                  <label className="tpl-field-label">{t.flowButtonText}</label>
                  <div className="tpl-input-with-counter">
                    <input
                      className={`tpl-field-input ${(data.flow.buttonText || t.flowGetFeedback || '').trim() ? 'is-valid' : ''}`}
                      value={data.flow.buttonText || t.flowGetFeedback}
                      onChange={(e) => setData({ ...data, flow: { ...data.flow, buttonText: e.target.value.slice(0, 40) } })}
                      maxLength={40}
                      placeholder="View Flow"
                    />
                    <span className="tpl-input-counter">{(data.flow.buttonText || t.flowGetFeedback || '').length}/40</span>
                  </div>
                </div>
              </div>

              {/* Image 3 — flow created via "Create new": dropdown + Edit + Delete (no flow-starts row) */}
              {flowSaved && data.flow.source === 'new' && (
                <div className="tpl-flow-newrow">
                  <select className="tpl-field-select tpl-flow-newrow-select" value={flowFile} readOnly>
                    <option value={flowFile}>{data.flow.buttonText || t.flowGetFeedback || 'View Flow'}</option>
                  </select>
                  <button type="button" className="tpl-flow-action-btn" onClick={() => onOpenFlowEditor && onOpenFlowEditor(data.flow)}>
                    <IcEdit size={13} stroke={1.7} /> {t.flowEdit || 'Edit'}
                  </button>
                  <button type="button" className="tpl-flow-action-btn" onClick={() => setData({ ...data, flow: null })}>
                    <IcTrash size={13} stroke={1.7} /> {t.flowDelete || 'Delete'}
                  </button>
                </div>
              )}

              {/* Image 4 — flow added via "Use existing": filename + Preview + Delete + Flow starts row */}
              {flowSaved && data.flow.source === 'existing' && (
                <>
                  <div className="tpl-flow-fileactions-row">
                    <span className="tpl-flow-filename" title={flowFile}>{flowFile}</span>
                    <button type="button" className="tpl-flow-action-btn" onClick={() => setData({ ...data, flow: { ...data.flow, _previewOpen: true } })}>{t.flowPreview || 'Preview'}</button>
                    <button type="button" className="tpl-flow-action-btn" onClick={() => setData({ ...data, flow: null })}>{t.flowDelete || 'Delete'}</button>
                  </div>
                  <div className="row-2 row-narrow-wide">
                    <div className="tpl-field">
                      <label className="tpl-field-label">{t.flowStartsWith || 'Flow starts with'}</label>
                      <TplDropdown
                        value={data.flow.startsWith || 'predefined'}
                        onChange={(v) => setData({ ...data, flow: { ...data.flow, startsWith: v } })}
                        disabled
                        options={[
                          { value: 'predefined', label: t.flowStartsPredefined || 'Pre-defined screen' },
                          { value: 'dynamic',    label: t.flowStartsDynamic || 'Dynamic screen' },
                        ]}
                      />
                    </div>
                    <div className="tpl-field">
                      <label className="tpl-field-label">{t.flowSelectScreen || 'Select pre-defined screen'}</label>
                      <TplDropdown
                        value={data.flow.startScreen || 'help'}
                        onChange={(v) => setData({ ...data, flow: { ...data.flow, startScreen: v } })}
                        options={[
                          { value: 'help',    label: t.flowScreenHelp || 'Help us improve' },
                          { value: 'survey',  label: t.flowScreenSurvey || 'Customer survey' },
                          { value: 'welcome', label: t.flowScreenWelcome || 'Welcome' },
                        ]}
                      />
                    </div>
                  </div>
                </>
              )}

              {/* Image 1 — initial state: Create new / Use existing pickers */}
              {!flowSaved && (
                <div className="tpl-flow-pickers">
                  <button
                    type="button"
                    className={`tpl-flow-picker ${data.flow.source === 'new' || !data.flow.source ? 'selected' : ''}`}
                    onClick={() => { setData({ ...data, flow: { ...data.flow, source: 'new' } }); onOpenFlowType(); }}
                  >
                    <IcPlus size={14} stroke={2.2} /> {t.btnCardCreateNew}
                  </button>
                  <button
                    type="button"
                    className={`tpl-flow-picker ${data.flow.source === 'existing' ? 'selected' : ''}`}
                    onClick={() => { setData({ ...data, flow: { ...data.flow, source: 'existing' } }); onOpenFlowType('existing'); }}
                  >
                    <IcGrid size={14} stroke={1.7} /> {t.btnCardUseExisting}
                  </button>
                </div>
              )}
            </div>
          </div>
          );
        })()}

        {data.flow?._previewOpen && (
          <TplFlowPreview t={t} onClose={() => setData({ ...data, flow: { ...data.flow, _previewOpen: false } })} />
        )}
      </div>
    </div>
  );
};

// ---- Add Button (pill + dropdown menu, with limits enforced) ----
const TplAddButton = ({ buttons, hasFlow = false, category, t, onAdd }) => {
  const [open, setOpen] = useStateW(false);
  const [pos, setPos] = useStateW({ top: 0, left: 0, dropUp: false });
  const ref = useRefW();
  const btnRef = useRefW();
  const menuRef = useRefW();
  useEffectW(() => {
    if (!open) return;
    const recalc = () => {
      const r = btnRef.current?.getBoundingClientRect();
      if (!r) return;
      const menuH = menuRef.current?.offsetHeight || 340;
      const spaceBelow = window.innerHeight - r.bottom;
      const dropUp = spaceBelow < menuH + 12 && r.top > menuH + 12;
      setPos({ top: dropUp ? r.top - menuH - 6 : r.bottom + 6, left: r.left, dropUp });
    };
    recalc();
    const onDoc = (e) => {
      const inBtn = ref.current && ref.current.contains(e.target);
      const inMenu = menuRef.current && menuRef.current.contains(e.target);
      if (!inBtn && !inMenu) setOpen(false);
    };
    document.addEventListener('mousedown', onDoc);
    window.addEventListener('resize', recalc);
    window.addEventListener('scroll', recalc, true);
    return () => {
      document.removeEventListener('mousedown', onDoc);
      window.removeEventListener('resize', recalc);
      window.removeEventListener('scroll', recalc, true);
    };
  }, [open]);

  // WhatsApp button limits. Flow lives on data.flow (not data.buttons), so fold
  // hasFlow into the count for 'flow' so the max:1 cap actually triggers.
  // Per-kind caps: custom up to the overall 10, visit twice, the rest once.
  const counts = (buttons || []).reduce((m, b) => ({ ...m, [b.kind]: (m[b.kind] || 0) + 1 }), {});
  if (hasFlow) counts.flow = (counts.flow || 0) + 1;
  const max = { custom: 10, visit: 2, wa: 1, phone: 1, flow: 1, copy: 1 };
  const total = (buttons || []).length + (hasFlow ? 1 : 0);
  const allowed = (k) => (counts[k] || 0) < (max[k] || 1) && total < 10;

  const opts = [
    { k: 'custom', label: t.btnCustom,        hint: t.btnCustomHint,         icon: <IcReply size={14} stroke={1.7} /> },
    { k: 'visit',  label: t.btnVisitWebsite,  hint: t.btnVisitWebsiteHint,   icon: <IcExternal size={14} stroke={1.7} /> },
    { k: 'wa',     label: t.btnCallWhatsApp,  hint: t.btnCallWhatsAppHint,   icon: <IcWa size={14} stroke={1.7} /> },
    { k: 'phone',  label: t.btnCallPhone,     hint: t.btnCallPhoneHint,      icon: <IcPhone size={14} stroke={1.7} /> },
    { k: 'flow',   label: t.btnCompleteFlow,  hint: t.btnCompleteFlowHint,   icon: <IcGrid size={14} stroke={1.7} /> },
    // "Copy offer code" is a Marketing-only CTA — Meta disallows it under Utility.
    ...(category === 'Utility' ? [] : [{ k: 'copy', label: t.btnCopyOffer, hint: t.btnCopyOfferHint, icon: <IcContracts size={14} stroke={1.7} /> }]),
  ];

  return (
    <div className="tpl-add-btn-wrap" ref={ref}>
      <button type="button" ref={btnRef} className="tpl-add-btn" onClick={() => setOpen(o => !o)}>
        <IcPlus size={14} stroke={2.2} />
        <span>{t.addButton}</span>
        <IcChevronDown size={12} stroke={2} style={{ marginInlineStart: 4, opacity: 0.85 }} />
      </button>
      {open && (
        <div
          className="tpl-add-btn-menu tpl-add-btn-menu-fixed"
          ref={menuRef}
          style={{ top: pos.top, left: pos.left }}
        >
          {opts.map((o) => {
            const dis = !allowed(o.k);
            return (
              <div
                key={o.k}
                className={`row ${dis ? 'disabled' : ''}`}
                onClick={() => { if (dis) return; setOpen(false); onAdd(o.k); }}
              >
                <span className="lbl">
                  <span className="ic">{o.icon}</span>
                  <span className="lbl-text">
                    <span className="nm">{o.label}</span>
                    {dis && o.hint && <span className="hint">{o.hint}</span>}
                  </span>
                </span>
                {dis && (
                  <span className="row-blocked" aria-hidden="true">
                    <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round">
                      <circle cx="12" cy="12" r="10"/>
                      <line x1="5" y1="5" x2="19" y2="19"/>
                    </svg>
                  </span>
                )}
              </div>
            );
          })}
        </div>
      )}
    </div>
  );
};

// ---- Editable card for an added button ----
const TplButtonCard = ({ button, index, t, onChange, onRemove, onEditFlow }) => {
  const titleMap = {
    custom: { title: t.btnCustom,        icon: <IcReply size={15} stroke={1.7} /> },
    visit:  { title: t.btnVisitWebsite,  icon: <IcExternal size={15} stroke={1.7} /> },
    wa:     { title: t.btnCallWhatsApp,  icon: <IcWa size={15} stroke={1.7} /> },
    phone:  { title: t.btnCallPhone,     icon: <IcPhone size={15} stroke={1.7} /> },
    copy:   { title: t.btnCopyOffer,     icon: <IcContracts size={15} stroke={1.7} /> },
  };
  const m = titleMap[button.kind] || titleMap.custom;
  const upd = (patch) => onChange({ ...button, ...patch });

  return (
    <div className="tpl-flow-card">
      <div className="tpl-flow-card-head">
        <span className="title"><span className="ic">{m.icon}</span> {m.title}</span>
        <span className="remove" onClick={onRemove}>
          <IcClose size={14} stroke={2} /> {t.flowRemove}
        </span>
      </div>

      <div className="tpl-flow-card-body">
        {/* Quick Reply (custom) — single Button Text field */}
        {button.kind === 'custom' && (
          <div className="row-1">
            <div className="tpl-field">
              <label className="tpl-field-label">{t.btnCardText}</label>
              <div className="tpl-input-with-counter">
                <input
                  className={`tpl-field-input ${(button.text || '').trim() ? 'is-valid' : ''}`}
                  value={button.text || ''}
                  onChange={(e) => upd({ text: e.target.value.slice(0, 25) })}
                  placeholder={t.btnCustom || 'Quick Reply'}
                  maxLength={25}
                />
                <span className="tpl-input-counter">{(button.text || '').length}/25</span>
              </div>
            </div>
          </div>
        )}

        {/* Visit website — Button Text (wider) + URL Type (narrower), then half-width Website URL */}
        {button.kind === 'visit' && (
          <>
            <div className="row-2 row-wide-narrow">
              <div className="tpl-field">
                <label className="tpl-field-label">{t.btnCardText}</label>
                <div className="tpl-input-with-counter">
                  <input
                    className={`tpl-field-input ${(button.text || '').trim() ? 'is-valid' : ''}`}
                    value={button.text || ''}
                    onChange={(e) => upd({ text: e.target.value.slice(0, 25) })}
                    placeholder={t.btnVisitWebsite}
                    maxLength={25}
                  />
                  <span className="tpl-input-counter">{(button.text || '').length}/25</span>
                </div>
              </div>
              <div className="tpl-field">
                <label className="tpl-field-label">{t.btnCardUrlType}</label>
                <TplDropdown
                  value={button.urlType || 'Static'}
                  onChange={(v) => upd({ urlType: v })}
                  options={[
                    { value: 'Static', label: t.btnCardUrlStatic },
                    { value: 'Dynamic', label: t.btnCardUrlDynamic },
                  ]}
                />
              </div>
            </div>
            <div className="row-2 row-wide-narrow">
              <div className="tpl-field">
                <label className="tpl-field-label">{t.btnCardWebsiteUrl}</label>
                <div className="tpl-input-with-counter">
                  <input
                    className={`tpl-field-input ${(button.url || '').trim() ? (/^https?:\/\//i.test(button.url || '') ? 'is-valid' : 'has-error') : ''}`}
                    value={button.url || ''}
                    onChange={(e) => upd({ url: e.target.value.slice(0, 2000) })}
                    placeholder={button.urlType === 'Dynamic' ? 'https://www.example.com/{{1}}' : (t.btnCardWebsiteUrlPh || 'https://www.example.com')}
                    maxLength={2000}
                  />
                  <span className="tpl-input-counter">{(button.url || '').length}/2000</span>
                </div>
              </div>
              {button.urlType === 'Dynamic' && (
                <div className="tpl-field">
                  <label className="tpl-field-label">&nbsp;</label>
                  <span className="tpl-url-var-chip" title="Dynamic URL variable">
                    <span className="tpl-url-var-text">{`{{1}}`}</span>
                    <span className="tpl-url-var-info" aria-hidden="true"><IcInfo size={12} stroke={1.7} /></span>
                  </span>
                </div>
              )}
            </div>
            {/* Variable URL sample — appears once a {{1}} variable is added to a
                Dynamic URL (mirrors Meta's "Add sample URL"): a sample value for
                the URL variable so the template can be reviewed. */}
            {button.urlType === 'Dynamic' && /\{\{\s*1\s*\}\}/.test(button.url || '') && (() => {
              const sample = button.urlSample || '';
              const sampleInvalid = !!sample.trim() && !/^https?:\/\//i.test(sample.trim());
              return (
                <div className="tpl-url-sample-block">
                  <div className="tpl-url-sample-title">{t.btnCardUrlSample || 'Variable URL sample'}</div>
                  <div className="tpl-url-sample-desc">{t.btnCardUrlSampleDesc || 'To help us review your message template, please add an example of the website URL. Do not use real customer information.'}</div>
                  <div className="tpl-var-sample-row">
                    <div className="tpl-var-sample-chip">{`{{1}}`}</div>
                    <div className="tpl-var-sample-input-col">
                      <div className="tpl-input-with-counter">
                        <input
                          className={`tpl-field-input ${sample.trim() ? (sampleInvalid ? 'has-error' : 'is-valid') : ''}`}
                          value={sample}
                          onChange={(e) => upd({ urlSample: e.target.value.slice(0, 2000) })}
                          placeholder={`${t.btnCardUrlSamplePh || 'Enter full URL for'} ${button.url || ''}`}
                          maxLength={2000}
                        />
                        <span className="tpl-input-counter">{sample.length}/2000</span>
                      </div>
                      {sampleInvalid && (
                        <div className="tpl-url-sample-err">{t.btnCardUrlSampleErr || 'Please enter a valid website URL'}</div>
                      )}
                    </div>
                  </div>
                </div>
              );
            })()}
          </>
        )}

        {/* Call on WhatsApp — Button Text (wider) + Active for (narrower) */}
        {button.kind === 'wa' && (
          <div className="row-2 row-wide-narrow">
            <div className="tpl-field">
              <label className="tpl-field-label">{t.btnCardText}</label>
              <div className="tpl-input-with-counter">
                <input
                  className={`tpl-field-input ${(button.text || '').trim() ? 'is-valid' : ''}`}
                  value={button.text || ''}
                  onChange={(e) => upd({ text: e.target.value.slice(0, 25) })}
                  placeholder={t.btnCallWhatsApp}
                  maxLength={25}
                />
                <span className="tpl-input-counter">{(button.text || '').length}/25</span>
              </div>
            </div>
            <div className="tpl-field">
              <label className="tpl-field-label">{t.btnCardActiveFor}</label>
              <TplDropdown
                value={button.activeFor || '7 days'}
                onChange={(v) => upd({ activeFor: v })}
                options={Array.from({ length: 30 }, (_, i) => i + 1).map(n => ({
                  value: `${n} days`,
                  label: `${n} ${n === 1 ? 'day' : 'days'}`,
                }))}
              />
            </div>
          </div>
        )}

        {/* Call Phone number — Button Text + Phone Number on a single row,
             matching the Call on WhatsApp layout. */}
        {button.kind === 'phone' && (() => {
          const phoneInvalid = !button.phone || button.phone.trim().length < 7;
          const PI = window.PhoneInput;
          return (
            <div className="row-2 row-wide-narrow">
              <div className="tpl-field">
                <label className="tpl-field-label">{t.btnCardText}</label>
                <div className="tpl-input-with-counter">
                  <input
                    className={`tpl-field-input ${(button.text || '').trim() ? 'is-valid' : ''}`}
                    value={button.text || ''}
                    onChange={(e) => upd({ text: e.target.value.slice(0, 25) })}
                    placeholder={t.btnCallPhone}
                    maxLength={25}
                  />
                  <span className="tpl-input-counter">{(button.text || '').length}/25</span>
                </div>
              </div>
              <div className="tpl-field tpl-phone-field">
                <label className="tpl-field-label">{t.btnCardPhone || 'Phone Number'} <span className="req">*</span></label>
                {PI ? (
                  <PI
                    data={{ phoneCountry: button.country || 'SA', phone: button.phone || '' }}
                    onChange={(key, val) => upd({ [key === 'phoneCountry' ? 'country' : 'phone']: val })}
                  />
                ) : (
                  <div className={`tpl-input-with-counter ${phoneInvalid ? 'has-error' : ''}`}>
                    <input
                      className={`tpl-field-input ${phoneInvalid ? 'is-invalid' : 'is-valid'}`}
                      value={button.phone || ''}
                      onChange={(e) => upd({ phone: e.target.value.slice(0, 25) })}
                      placeholder={t.btnCallPhone}
                      maxLength={25}
                    />
                  </div>
                )}
                {phoneInvalid && (
                  <div className="tpl-field-error">{t.btnCardPhoneError}</div>
                )}
              </div>
            </div>
          );
        })()}

        {/* Copy offer code — locked Button Text (narrow) + Offer code (wide, validated) */}
        {button.kind === 'copy' && (() => {
          const codeInvalid = !button.code || button.code.trim().length === 0;
          return (
            <div className="row-2 row-narrow-wide">
              <div className="tpl-field">
                <label className="tpl-field-label">{t.btnCardText}</label>
                <input
                  className="tpl-field-input is-locked"
                  value={button.text || t.btnCopyOffer}
                  readOnly
                  disabled
                />
              </div>
              <div className="tpl-field">
                <label className="tpl-field-label">{t.btnCardOfferCode}</label>
                <div className={`tpl-input-with-counter ${codeInvalid ? 'has-error' : ''}`}>
                  <input
                    className={`tpl-field-input ${codeInvalid ? 'is-invalid' : 'is-valid'}`}
                    value={button.code || ''}
                    onChange={(e) => upd({ code: e.target.value.slice(0, 25) })}
                    placeholder={t.btnCardOfferCodePh}
                    maxLength={25}
                  />
                  <span className="tpl-input-counter">{(button.code || '').length}/25</span>
                  {codeInvalid && (
                    <span className="tpl-input-err-icon" aria-hidden="true"><IcBanField size={16} /></span>
                  )}
                </div>
                {codeInvalid && (
                  <div className="tpl-field-error">{t.btnCardOfferCodeError}</div>
                )}
              </div>
            </div>
          );
        })()}
      </div>
    </div>
  );
};

// Small ban / circle-with-slash icon used inline for field validation
const IcBanField = ({ size = 16 }) => (
  <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
    <circle cx="12" cy="12" r="9" />
    <path d="M5.6 5.6l12.8 12.8" />
  </svg>
);

// ---- Step 3: Share & Submit ----
const TplWizardStep3 = ({ data, setData, t }) => {
  const [search, setSearch] = useStateW('');
  const candidates = window.sharedWithCandidates || [];
  const filtered = candidates.filter(c => !search || c.name.toLowerCase().includes(search.toLowerCase()) || c.username.toLowerCase().includes(search.toLowerCase()));
  const selectedIds = data.sharedIds || [];
  const toggle = (id) => {
    const next = selectedIds.includes(id) ? selectedIds.filter(x => x !== id) : [...selectedIds, id];
    setData({ ...data, sharedIds: next });
  };
  const selectedItems = candidates.filter(c => selectedIds.includes(c.id));
  // "Select all" toggles every user currently shown (respects the search filter).
  const allFilteredSelected = filtered.length > 0 && filtered.every(c => selectedIds.includes(c.id));
  const toggleAll = () => {
    if (allFilteredSelected) setData({ ...data, sharedIds: selectedIds.filter(id => !filtered.some(c => c.id === id)) });
    else setData({ ...data, sharedIds: [...new Set([...selectedIds, ...filtered.map(c => c.id)])] });
  };

  return (
    <div className="tpl-share-wrap">
      {/* Left column — Shared With (multi-select picker) */}
      <div className="tpl-share-col">
        <h4>
          <span>
            <strong>{t.sharedWithLbl}</strong>{' '}
            <span className="sub">{t.sharedWithRoleSub || 'Normal User (Multiple Select)'}</span>
          </span>
        </h4>

        {/* Chip-display multi-select */}
        <div className={`tpl-share-multi ${selectedItems.length ? 'has-values' : ''}`}>
          <div className="tpl-share-multi-chips">
            {selectedItems.length === 0 && (
              <span className="placeholder">{t.selectPlaceholder}</span>
            )}
            {selectedItems.map(c => (
              <span key={c.id} className="tpl-share-chip">
                {c.name}
                <span className="x" onClick={(e) => { e.stopPropagation(); toggle(c.id); }}>
                  <IcClose size={10} stroke={2.4} />
                </span>
              </span>
            ))}
          </div>
          <span className="tpl-share-multi-chev"><IcChevronDown size={14} stroke={1.7} /></span>
        </div>

        {/* Search + selectable list card */}
        <div className="tpl-share-list-card">
          <div className="tpl-share-search">
            <IcSearch size={14} stroke={1.7} />
            <input type="text" placeholder={t.searchUsers} value={search} onChange={(e) => setSearch(e.target.value)} />
          </div>
          <div className="tpl-share-list">
            {filtered.length > 0 && (
              <div className={`tpl-share-row tpl-share-row-all ${allFilteredSelected ? 'checked' : ''}`} onClick={toggleAll}>
                <span className="tpl-share-cb">{allFilteredSelected && <IcCheck size={10} stroke={3} />}</span>
                <div className="meta"><div className="name"><strong>{t.selectAll || 'Select All'}</strong></div></div>
              </div>
            )}
            {filtered.map(c => (
              <div key={c.id} className={`tpl-share-row ${selectedIds.includes(c.id) ? 'checked' : ''}`} onClick={() => toggle(c.id)}>
                <span className="tpl-share-cb">{selectedIds.includes(c.id) && <IcCheck size={10} stroke={3} />}</span>
                <div className="meta">
                  <div className="name">{c.name}</div>
                  <div className="un">{c.username}</div>
                </div>
              </div>
            ))}
          </div>
        </div>
      </div>

      {/* Right column — Selected Users */}
      <div className="tpl-share-col">
        <h4>
          <span><strong>{t.selectedUsersFull || 'Selected Users'}</strong></span>
          <span className="clear" onClick={() => setData({ ...data, sharedIds: [] })}>
            <IcClose size={12} stroke={2} /> {t.unselectAll}
          </span>
        </h4>
        <div className="tpl-share-selected">
          {selectedItems.length === 0 ? (
            <div className="tpl-share-empty">
              {t.noUsersSelected || 'No users selected yet.'}
            </div>
          ) : selectedItems.map(c => (
            <div key={c.id} className="tpl-share-selected-row">
              <span className="tpl-share-cb"><IcCheck size={10} stroke={3} /></span>
              <div className="meta">
                <div className="name">{c.name}</div>
                <div className="un">{c.username}</div>
              </div>
              <span className="x" onClick={() => toggle(c.id)}><IcClose size={14} stroke={2} /></span>
            </div>
          ))}
        </div>
      </div>
    </div>
  );
};

// ---- Compact "Shared With" multi-select (Edit screen top grid) ----
const TplShareMulti = ({ value = [], onChange, t }) => {
  const [open, setOpen] = useStateW(false);
  const [pos, setPos] = useStateW(null);
  const ref = useRefW();
  const popRef = useRefW();
  const candidates = window.sharedWithCandidates || [];
  useEffectW(() => {
    if (!open) return;
    const onDoc = (e) => {
      if (ref.current && ref.current.contains(e.target)) return;
      if (popRef.current && popRef.current.contains(e.target)) return;
      setOpen(false);
    };
    const close = () => setOpen(false);
    document.addEventListener('mousedown', onDoc);
    window.addEventListener('scroll', close, true);
    window.addEventListener('resize', close);
    return () => {
      document.removeEventListener('mousedown', onDoc);
      window.removeEventListener('scroll', close, true);
      window.removeEventListener('resize', close);
    };
  }, [open]);
  // Open the menu as a fixed-positioned portal so it is never clipped by the
  // details card's `overflow: hidden`. Flips up when there isn't room below.
  const openMenu = () => {
    if (open) { setOpen(false); return; }
    const trig = ref.current && ref.current.querySelector('.tpl-share-multi-trigger');
    if (trig) {
      const r = trig.getBoundingClientRect();
      const spaceBelow = window.innerHeight - r.bottom;
      let top, maxH;
      if (spaceBelow < 200 && r.top > spaceBelow) { maxH = Math.min(240, r.top - 16); top = r.top - maxH - 6; }
      else { maxH = Math.min(240, spaceBelow - 16); top = r.bottom + 4; }
      setPos({ top, left: r.left, width: r.width, maxH });
    }
    setOpen(true);
  };
  const toggle = (id) => onChange(value.includes(id) ? value.filter(x => x !== id) : [...value, id]);
  const allIds = candidates.map(c => c.id);
  const allSelected = candidates.length > 0 && allIds.every(id => value.includes(id));
  const toggleAll = () => onChange(allSelected ? [] : allIds);
  const label = allSelected ? (t.allSelected || 'All selected')
              : value.length ? `${value.length} ${t.itemsSelected || 'Items Selected'}`
              : (t.selectPlaceholder || 'Select…');
  return (
    <div className="tpl-share-multi-wrap" ref={ref}>
      <button type="button" className={`tpl-field-input tpl-share-multi-trigger ${open ? 'open' : ''}`} onClick={openMenu}>
        <span className={value.length ? '' : 'ph'}>{label}</span>
        <IcChevronDown size={14} stroke={1.7} />
      </button>
      {open && pos && ReactDOM.createPortal(
        <div className="tpl-share-multi-pop" ref={popRef} style={{ position: 'fixed', top: pos.top, left: pos.left, width: pos.width, right: 'auto', maxHeight: pos.maxH }}>
          {candidates.length > 0 && (
            <>
              <div className={`tpl-share-multi-opt all ${allSelected ? 'on' : ''}`} onClick={toggleAll}>
                <span className="cb">{allSelected && <IcCheck size={10} stroke={3} />}</span>
                <span className="nm"><strong>{t.selectAll || 'Select All'}</strong></span>
              </div>
              <div className="tpl-share-multi-sep" />
            </>
          )}
          {candidates.map(c => (
            <div key={c.id} className={`tpl-share-multi-opt ${value.includes(c.id) ? 'on' : ''}`} onClick={() => toggle(c.id)}>
              <span className="cb">{value.includes(c.id) && <IcCheck size={10} stroke={3} />}</span>
              <span className="nm">{c.name}</span>
            </div>
          ))}
          {candidates.length === 0 && <div className="tpl-share-multi-empty">{t.tplEmptyList || 'No users'}</div>}
        </div>,
        document.body
      )}
    </div>
  );
};

// ---- Single-page "Edit Template" form (only reachable for internally-rejected
// templates). Reuses the create Step-2 component for the whole message/buttons/flow
// section so every field & behaviour matches the create flow; the Template ID is the
// one field that's locked. ----
const TplEditForm = ({ data, setData, t, lang, openFlowType, openFlowEditor, readOnly = false }) => {
  const langOpts = [
    { value: 'English', label: t.langEnglish || 'English' },
    { value: 'Arabic', label: t.langArabic || 'العربية' },
  ];
  const catOpts = [
    { value: 'Marketing', label: t.catMarketing || 'Marketing' },
    { value: 'Utility', label: t.catUtility || 'Utility' },
    { value: 'Authentication', label: t.catAuthentication || 'Authentication' },
  ];
  const subFor = (cat) => cat === 'Authentication'
    ? [{ value: 'OTP', label: t.subOTP || 'OTP' }]
    : [{ value: 'Default', label: t.subDefault || 'Default' }, { value: 'Flows', label: t.subFlows || 'Flows' }];
  const wabaAccounts = ['Aramco WABA Main', 'Aramco WABA Secondary', 'Falcon Demo WABA'];
  return (
    <div className="tpl-wizard ac-card tpl-edit-card">
      <div className="ac-card-head">
        <div className="ac-card-title">{readOnly ? (t.shareTemplate || 'Share Template') : (t.editTemplate || 'Edit Template')}</div>
      </div>
      <div className={`ac-card-body tpl-wizard-body ${readOnly ? 'tpl-share-locked' : ''}`}>
        {readOnly && (
          <div className="tpl-share-note">
            <IcInfo size={13} stroke={1.7} />
            <span>{t.shareNote || 'All fields are read-only. Choose who this template is shared with below.'}</span>
          </div>
        )}
        <div className="tpl-edit-grid">
          <div className="tpl-field">
            <label className="tpl-field-label">{t.wabaAccountLbl || 'WABA Account'}</label>
            <TplDropdown value={data.wabaAccount || ''} onChange={(v) => setData({ ...data, wabaAccount: v })} placeholder={t.wabaAccountPh || 'Select WABA account'} options={[{ value: '', label: t.wabaAccountPh || 'Select WABA account' }, ...wabaAccounts.map(w => ({ value: w, label: w }))]} />
          </div>
          <div className="tpl-field">
            <label className="tpl-field-label">{t.templateNameLbl || 'Template Name'}</label>
            <input className="tpl-field-input is-locked" value={data.name || ''} readOnly disabled title={t.fieldLocked || 'This field cannot be changed'} />
          </div>
          <div className="tpl-field">
            <label className="tpl-field-label">{t.selectLanguage || 'Select language'}</label>
            <TplDropdown value={data.language || 'English'} onChange={(v) => setData({ ...data, language: v })} options={langOpts} disabled />
          </div>
          <div className="tpl-field">
            <label className="tpl-field-label">{t.templateIdLbl || 'Template ID'}</label>
            <input className="tpl-field-input is-locked" value={`#${data._editId || ''}`} readOnly disabled title={t.templateIdLocked || 'Template ID cannot be changed'} />
          </div>
          <div className="tpl-field">
            <label className="tpl-field-label">{t.referenceIdLbl || 'Reference ID'}</label>
            <input className="tpl-field-input" value={data.referenceId || ''} onChange={(e) => setData({ ...data, referenceId: e.target.value })} />
          </div>
          <div className="tpl-field">
            <label className="tpl-field-label">{t.categoryLbl || 'Category'}</label>
            <TplDropdown value={data.category || 'Marketing'} onChange={(v) => setData({ ...data, category: v, subCategory: subFor(v)[0].value })} options={catOpts} disabled />
          </div>
          <div className="tpl-field">
            <label className="tpl-field-label">{t.subCategoryLbl || 'Sub Category'}</label>
            <TplDropdown value={data.subCategory || 'Default'} onChange={(v) => setData({ ...data, subCategory: v })} options={subFor(data.category || 'Marketing')} disabled />
          </div>
          <div className="tpl-field tpl-edit-shared">
            <label className="tpl-field-label">{t.sharedWithLbl || 'Shared With'} <span className="opt">({t.multipleSelect || 'Multiple Select'})</span></label>
            <TplShareMulti value={data.sharedIds || []} onChange={(ids) => setData({ ...data, sharedIds: ids })} t={t} />
          </div>
        </div>

        {/* Message & structure — reuses the create Step-2 so header/body/variables/
            footer/buttons/flow all match the create experience exactly. */}
        <TplWizardStep2 data={data} setData={setData} t={t} onOpenFlowType={openFlowType} onOpenFlowEditor={openFlowEditor} />
      </div>
    </div>
  );
};

// ---- Wizard wrapper (matches Create New Client ac-card structure) ----
const TplWizard = ({ t, lang, step, data, setData, openFlowType, openFlowEditor }) => {
  return (
    <div className="tpl-wizard ac-card">
      <div className="ac-card-head">
        <div className="ac-card-title">{t.newTemplate}</div>
        <div className="ac-step-counter">{(t.stepNum || 'step').toLowerCase()} <strong>{step}/3</strong></div>
      </div>

      <TplStepper step={step} t={t} />

      <div className="ac-card-body tpl-wizard-body">
        {step === 1 && <TplWizardStep1 data={data} setData={setData} t={t} />}
        {step === 2 && <TplWizardStep2 data={data} setData={setData} t={t} onOpenFlowType={openFlowType} onOpenFlowEditor={openFlowEditor} />}
        {step === 3 && <TplWizardStep3 data={data} setData={setData} t={t} />}
      </div>
    </div>
  );
};

Object.assign(window, { TplWizard, TplStepper, TplContactGroupMulti, TplDropdown, TplWizardStep3, TplEditForm, TplShareMulti });
