// ─── کمپین‌ها ─────────────────────────────────────────────────────────────
﻿// campaigns.jsx — سیستم کمپین با wizard ساخت + مرکز فرماندهی
const Campaigns = () => {
  const { Icon, Button, useToast } = window.SB_UI;
  const { fa } = window.SB_DATA;

  const [campaigns, setCampaigns] = useState([]);
  const [loading,   setLoading]   = useState(true);
  const [selected,  setSelected]  = useState(null);
  const [mode,      setMode]      = useState('list'); // list | intel | profile | script_seg | flow
  const [flowCampId, setFlowCampId] = useState(null);
  const [section, setSection] = window.useStickyState('tab_automation', 'campaigns');
  const toast = useToast();

  const token   = localStorage.getItem(window.TOKEN_KEY);
  const headers = { 'Content-Type': 'application/json', Authorization: `Bearer ${token}` };

  const load = () => {
    setLoading(true);
    window.api('/campaigns/campaigns')
      .then(rows => { if (Array.isArray(rows)) setCampaigns(rows); })
      .finally(() => setLoading(false));
  };

  const openFlow = (campId) => { setFlowCampId(campId); setMode('flow'); };

  useEffect(() => {
    load();
    // اگه از جای دیگه‌ای redirect شده بودیم
    const openId = window.SB_openCampaign;
    if (openId) { window.SB_openCampaign = null; openFlow(openId); }
  }, []);

  const createCampaign = async () => {
    const autoName = 'کمپین جدید ' + new Date().toLocaleDateString('fa-IR', { month:'short', day:'numeric' });
    const r = await window.api('/campaigns/campaigns', { method: 'POST', body: { name: autoName, type: 'product' } });
    if (r && r.id) { openFlow(r.id); }
    else toast('خطا در ساخت کمپین', 'error');
  };

  const toggleActive = (c) => {
    fetch(`/api/campaigns/campaigns/${c.id}`, {
      method: 'PUT', headers,
      body: JSON.stringify({ is_active: c.is_active ? 0 : 1 }),
    }).then(r => r.json()).then(d => {
      if (d.success) {
        setCampaigns(prev => prev.map(x => x.id === c.id ? { ...x, is_active: x.is_active ? 0 : 1 } : x));
        toast(c.is_active ? 'کمپین غیرفعال شد' : 'کمپین فعال شد', 'success');
      }
    });
  };

  const deleteCampaign = (c) => {
    if (!confirm(`کمپین «${c.name}» حذف شود؟`)) return;
    fetch(`/api/campaigns/campaigns/${c.id}`, { method: 'DELETE', headers })
      .then(r => r.json())
      .then(d => {
        if (d.success) {
          setCampaigns(prev => prev.filter(x => x.id !== c.id));
          toast('کمپین حذف شد', 'success');
        }
      });
  };

  if (selected) return <CampaignDetail campaign={selected} onBack={() => { setSelected(null); load(); }} headers={headers} />;
  if (mode === 'flow' && flowCampId) return (
    <div style={{ display:'flex', flexDirection:'column', height:'100%' }}>
      <div style={{ display:'flex', alignItems:'center', gap:10, padding:'8px 14px', borderBottom:'1px solid var(--border-soft)', flexShrink:0, background:'var(--surface)' }}>
        <button onClick={() => { setMode('list'); load(); }}
          style={{ display:'flex', alignItems:'center', gap:6, padding:'5px 12px', borderRadius:7, border:'1px solid var(--border-soft)', background:'transparent', color:'var(--text-2)', cursor:'pointer', fontSize:12, fontFamily:'inherit' }}>
          ← کمپین‌ها
        </button>
        <span style={{ width:1, height:18, background:'var(--border-soft)' }} />
        <span style={{ fontSize:13, color:'var(--text-3)', display:'flex', alignItems:'center', gap:5 }}>
          <Icon name="workflow" size={14} color="#8B5CF6" /> طراح فلو
        </span>
      </div>
      <div style={{ flex:1, minHeight:0 }}>
        {window.FlowBuilder
          ? React.createElement(window.FlowBuilder, { key: flowCampId, initialCampId: flowCampId, embedded: true })
          : <div style={{ padding:40, textAlign:'center', color:'var(--text-3)' }}>در حال بارگذاری...</div>
        }
      </div>
    </div>
  );
  if (mode === 'intel')  return <CampaignIntelligence headers={headers} onBack={() => setMode('list')} onCreateCampaign={createCampaign} />;
  if (mode === 'profile') return <LeadProfile headers={headers} onBack={() => setMode('list')} />;
  if (mode === 'script_seg') return <ScriptSegments headers={headers} onBack={() => setMode('list')} />;
  if (mode === 'ai_designer') return (
    <CampaignAIDesigner
      headers={headers}
      onBack={() => setMode('list')}
      onCreated={(camp) => {
        setMode('list');
        load();
        toast(`کمپین «${camp.name}» ساخته شد`, 'success');
        setTimeout(() => openFlow(camp.id), 400);
      }}
    />
  );

  const statusColor = (a) => a ? '#34D399' : '#6B7280';
  const _autoTabs = [['campaigns','🎯 کمپین‌ها'],['triggers','⚡ تریگرها'],['scripts','📋 اسکریپت‌ها'],['followup','🔄 پیگیری']];
  return (
    <div style={{ display:'flex', flexDirection:'column', height:'100%' }}>
      <div style={{ padding:'6px 16px 0', borderBottom:'1px solid var(--border)', background:'var(--surface)', display:'flex', gap:4, flexShrink:0 }}>
        {_autoTabs.map(([id,label]) => (
          <button key={id} onClick={() => setSection(id)} style={{ padding:'6px 16px', borderRadius:'6px 6px 0 0', border:'none', cursor:'pointer', fontSize:12, fontFamily:'inherit', background: section===id ? 'var(--bg)' : 'transparent', color: section===id ? 'var(--primary)' : 'var(--text-muted)', borderBottom: section===id ? '2px solid var(--primary)' : '2px solid transparent' }}>{label}</button>
        ))}
      </div>
      {section === 'triggers'  && <div style={{ flex:1 }}><Triggers /></div>}
      {section === 'scripts'   && <div style={{ flex:1 }}><Scripts /></div>}
      {section === 'followup'  && <div style={{ flex:1 }}><FollowUp /></div>}
      {section === 'campaigns' && <div style={{ padding:16, overflow:'auto', flex:1 }}>
      <div className="row between">
        <div>
          <div className="semi" style={{ fontSize: 15 }}>کمپین‌ها</div>
          <div className="text-xs text-3 mt-4">{loading ? '...' : `${fa(campaigns.length)} کمپین`}</div>
        </div>
        <div className="row gap-8">
          <button
            onClick={() => setMode('ai_designer')}
            style={{ padding: '7px 14px', borderRadius: 9, border: '1px solid rgba(108,99,255,0.35)', background: 'rgba(108,99,255,0.1)', color: '#818CF8', cursor: 'pointer', fontSize: 12, fontFamily: 'inherit', display: 'flex', alignItems: 'center', gap: 6 }}
          >
            🤖 طراحی با AI
          </button>
          <Button kind="primary" icon="plus" onClick={createCampaign}>کمپین جدید</Button>
        </div>
      </div>

      {loading ? (
        <div style={{ textAlign: 'center', padding: 60, color: 'var(--text-3)' }}>در حال بارگذاری...</div>
      ) : campaigns.length === 0 ? (
        <div className="card mt-16" style={{ textAlign: 'center', padding: 60 }}>
          <Icon name="target" size={44} color="var(--text-3)" />
          <div className="semi mt-16">هنوز کمپینی نساختی</div>
          <div className="text-sm text-3 mt-8">با کمپین می‌تونی پیام‌های خودکار برای لیدها ارسال کنی</div>
          <div style={{ marginTop: 16, display: 'flex', justifyContent: 'center', gap: 10 }}>
            <button onClick={() => setMode('intel')} style={{ padding: '8px 16px', borderRadius: 8, border: '1px solid rgba(251,191,36,0.3)', background: 'rgba(251,191,36,0.06)', color: '#FBBF24', cursor: 'pointer', fontSize: 12, fontFamily: 'inherit' }}>
              📊 ببین چه کمپینی لازم داری
            </button>
            <Button kind="primary" icon="plus" onClick={createCampaign}>اولین کمپین را بساز</Button>
          </div>
        </div>
      ) : (
        <div style={{ marginTop: 16, display: 'flex', flexDirection: 'column', gap: 10 }}>
          {campaigns.map(c => (
            <div key={c.id} style={{ padding: '14px 16px', borderRadius: 12, background: 'var(--surface)', border: '1px solid var(--border-soft)', display: 'flex', alignItems: 'center', gap: 14 }}>
              <div style={{ width: 8, height: 8, borderRadius: '50%', background: statusColor(c.is_active), flexShrink: 0 }} />
              <div style={{ flex: 1, minWidth: 0 }}>
                <div className="semi" style={{ fontSize: 13 }}>{c.name}</div>
                <div style={{ display: 'flex', gap: 14, marginTop: 4 }}>
                  <span className="text-xs text-3">👥 {fa(c.lead_count || 0)} لید</span>
                  {c.goal && <span className="text-xs text-3" style={{ color: '#818CF8' }}>{c.goal}</span>}
                </div>
              </div>
              <div className="row gap-8">
                <button onClick={() => openFlow(c.id)}
                  style={{ padding: '5px 12px', borderRadius: 8, border: '1px solid rgba(139,92,246,0.35)', background: 'rgba(139,92,246,0.1)', color: '#A78BFA', cursor: 'pointer', fontSize: 11, fontFamily: 'inherit', display:'flex', alignItems:'center', gap:5 }}>
                  <Icon name="workflow" size={12} /> طراح فلو
                </button>
                <button onClick={() => setSelected(c)} style={{ padding: '5px 12px', borderRadius: 8, border: '1px solid rgba(99,102,241,0.3)', background: 'rgba(99,102,241,0.08)', color: '#818CF8', cursor: 'pointer', fontSize: 11, fontFamily: 'inherit' }}>
                  جزئیات ←
                </button>
                <button onClick={() => toggleActive(c)} title={c.is_active ? 'غیرفعال' : 'فعال'} style={{ width: 36, height: 20, borderRadius: 10, border: 'none', cursor: 'pointer', background: c.is_active ? '#34D399' : 'rgba(255,255,255,0.08)', position: 'relative', transition: 'background .2s', flexShrink: 0 }}>
                  <span style={{ position: 'absolute', top: 2, right: c.is_active ? 2 : 18, width: 16, height: 16, borderRadius: 8, background: '#fff', transition: 'right .2s', display: 'block' }} />
                </button>
                <button onClick={() => deleteCampaign(c)} title="حذف" style={{ width: 28, height: 28, borderRadius: 7, border: '1px solid rgba(248,113,113,0.2)', background: 'transparent', color: '#F87171', cursor: 'pointer', display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: 12 }}>🗑</button>
              </div>
            </div>
          ))}
        </div>
      )}
      </div>}
    </div>
  );
};

// ══════════════════════════════════════════════════════════
// ── مرکز فرماندهی کمپین ───────────────────────────────────
// ══════════════════════════════════════════════════════════
const CampaignIntelligence = ({ headers, onBack, onCreateCampaign }) => {
  const { Icon, Button } = window.SB_UI;
  const { fa } = window.SB_DATA;

  const [data,     setData]     = useState(null);
  const [loading,  setLoading]  = useState(true);
  const [tab,      setTab]      = window.useStickyState('tab_campaigns', 'lifecycle'); // lifecycle | filter
  const [drillKey, setDrillKey] = useState(null);        // drill-down stage key

  useEffect(() => {
    window.api('/campaigns/intelligence')
      .then(d => { if (!d.error) setData(d); else console.error('intel err:', d.error); })
      .finally(() => setLoading(false));
  }, []);

  // ── ثابت‌ها ─────────────────────────────────────────
  const LIFECYCLE = [
    { key:'buyer_active',      icon:'✅', title:'خریدار فعال',           desc:'خریدن + تماس در ۹۰ روز',                  color:'#34D399', goal:'product',  action:'کمپین upsell' },
    { key:'buyer_stale',       icon:'💤', title:'خریدار راکد',            desc:'خریدن ولی ۹۰+ روز تماسی نبوده',           color:'#6EE7B7', goal:'product',  action:'کمپین احیای خریدار' },
    { key:'followup_overdue',  icon:'🔴', title:'پیگیری دیر شده',         desc:'گفتیم تماس بگیریم، بیشتر از ۷ روز گذشته', color:'#F87171', goal:'followup', action:'کمپین پیگیری فوری' },
    { key:'followup_pending',  icon:'🔄', title:'در دست پیگیری',          desc:'آخرین تماس: follow_up، کمتر از ۷ روز',    color:'#FBBF24', goal:'followup', action:'کمپین ادامه پیگیری' },
    { key:'not_interested',    icon:'🙅', title:'علاقه‌ای نداشت',         desc:'آخرین تماس: not_interested',               color:'#94A3B8', goal:'followup', action:'کمپین تغییر ذهن' },
    { key:'unreachable',       icon:'📵', title:'جواب نمی‌ده',            desc:'همه تماس‌ها: no_answer (۲+)',              color:'#FB923C', goal:'followup', action:'کمپین پیام متنی' },
    { key:'answered_cold',     icon:'💬', title:'جواب داد، ادامه نداد',   desc:'آخرین تماس: answered + بیشتر از ۱۴ روز', color:'#818CF8', goal:'product',  action:'کمپین پیشنهاد ویژه' },
    { key:'in_contact',        icon:'📞', title:'در تماس فعال',           desc:'آخرین تماس: answered + کمتر از ۱۴ روز',  color:'#A5B4FC', goal:'product',  action:'کمپین تخفیف محدود' },
    { key:'has_phone_no_call', icon:'📱', title:'تلفن داده، تماس نگرفتیم',desc:'شماره داریم ولی هیچ تماسی ثبت نشده',     color:'#C084FC', goal:'product',  action:'کمپین اولین تماس' },
    { key:'new_fresh',         icon:'🆕', title:'تازه وارد این هفته',      desc:'status=new + کمتر از ۷ روز + بدون تماس', color:'#A5B4FC', goal:'lead',     action:'کمپین خوش‌آمدگویی' },
    { key:'new_waiting',       icon:'⏳', title:'منتظر اولین تماس',        desc:'status=new + بیشتر از ۷ روز + بدون تماس',color:'#7DD3FC', goal:'lead',     action:'کمپین فعال‌سازی' },
    { key:'cold',              icon:'🧊', title:'سرد شده',                desc:'تماس داشته + آخرین تماس ۳۰+ روز پیش',    color:'#CBD5E1', goal:'followup', action:'کمپین گرم کردن' },
    { key:'lost',              icon:'❌', title:'از دست رفته / منقضی',    desc:'status=lost یا expired',                  color:'#6B7280', goal:'followup', action:null },
    { key:'other',             icon:'🔘', title:'سایر',                   desc:'بقیه',                                    color:'#475569', goal:'lead',     action:null },
  ];

  const FILTER_DEF = [
    { group:'زمان ورود', items:[
      { key:'entered_this_week',  label:'این هفته', color:'#34D399' },
      { key:'entered_this_month', label:'این ماه',  color:'#FBBF24' },
      { key:'entered_old',        label:'قدیمی‌تر', color:'#6B7280' },
    ]},
    { group:'تلفن', items:[
      { key:'has_phone', label:'تلفن دارد', color:'#818CF8' },
      { key:'no_phone',  label:'تلفن ندارد', color:'#94A3B8' },
    ]},
    { group:'نتیجه تماس', items:[
      { key:'outcome_answered',       label:'✅ جواب داد',       color:'#34D399' },
      { key:'outcome_no_answer',      label:'📵 جواب نداد',      color:'#FB923C' },
      { key:'outcome_follow_up',      label:'🔄 پیگیری می‌خواد', color:'#FBBF24' },
      { key:'outcome_not_interested', label:'🙅 علاقه نداشت',    color:'#94A3B8' },
      { key:'never_called',           label:'📭 اصلاً تماس نگرفتیم', color:'#C084FC' },
    ]},
    { group:'دوره رایگان', items:[
      { key:'free_course', label:'🎓 دوره رایگان دیده', color:'#60A5FA' },
    ]},
  ];

  const platLabel  = { bale:'بله', telegram:'تلگرام', rubika:'روبیکا', instagram:'اینستاگرام', eitaa:'ایتا', manual:'دستی' };
  const platIcon   = { bale:'💬', telegram:'✈️', rubika:'🔵', instagram:'📷', eitaa:'🟢', manual:'📋' };
  const statusLabel= { new:'جدید', warm:'گرم', hot:'داغ', follow_up:'پیگیری', buyer:'خریدار', lost:'از دست رفته', expired:'منقضی' };
  const statusColor= { new:'#A5B4FC', warm:'#FBBF24', hot:'#F87171', follow_up:'#FB923C', buyer:'#34D399', lost:'#6B7280', expired:'#6B7280' };

  const ago = (d) => {
    if (!d) return null;
    const diff = Math.floor((Date.now() - new Date(d)) / 86400000);
    if (diff === 0) return 'امروز';
    if (diff === 1) return 'دیروز';
    return `${fa(diff)} روز پیش`;
  };

  // ── Drill-down view ──────────────────────────────────
  if (drillKey && data) {
    const stageDef = LIFECYCLE.find(s => s.key === drillKey) || { icon:'📋', title: drillKey, color:'#818CF8', bg:'rgba(129,140,248,0.08)', border:'rgba(129,140,248,0.25)', action:null };
    const leads    = (data.lifecycle && data.lifecycle.leads && data.lifecycle.leads[drillKey]) || [];
    const count    = (data.lifecycle && data.lifecycle.counts && data.lifecycle.counts[drillKey]) || leads.length;
    const bg       = stageDef.bg || `${stageDef.color}12`;
    const border   = stageDef.border || `${stageDef.color}40`;

    return (
      <div>
        <div style={{ display: 'flex', alignItems: 'center', gap: 12, marginBottom: 20 }}>
          <button onClick={() => setDrillKey(null)} style={{ padding: '7px 14px', borderRadius: 8, border: '1px solid var(--border-soft)', background: 'transparent', color: 'var(--text-2)', cursor: 'pointer', fontSize: 12, fontFamily: 'inherit' }}>
            ← بازگشت
          </button>
          <div style={{ flex: 1 }}>
            <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
              <span style={{ fontSize: 20 }}>{stageDef.icon}</span>
              <span className="semi" style={{ fontSize: 15, color: stageDef.color }}>{stageDef.title}</span>
              <span className="mono semi" style={{ fontSize: 18, color: stageDef.color }}>{fa(count)}</span>
              <span className="text-xs text-3">نفر</span>
            </div>
            <div className="text-xs text-3 mt-2">{stageDef.desc}</div>
          </div>
          {stageDef.action && (
            <button onClick={() => onCreateCampaign && onCreateCampaign({ goal: stageDef.goal, segment: drillKey })}
              style={{ padding: '8px 16px', borderRadius: 8, border: `1px solid ${border}`, background: bg, color: stageDef.color, cursor: 'pointer', fontSize: 12, fontFamily: 'inherit', fontWeight: 600, whiteSpace: 'nowrap' }}>
              🚀 {stageDef.action}
            </button>
          )}
        </div>

        {count > 30 && (
          <div style={{ padding: '8px 14px', borderRadius: 8, background: 'rgba(251,191,36,0.06)', border: '1px solid rgba(251,191,36,0.2)', marginBottom: 12, fontSize: 12, color: '#FBBF24' }}>
            ⚠️ {fa(count)} نفر در این گروه هستن — فقط ۳۰ نفر اول نشون داده می‌شه
          </div>
        )}

        {leads.length === 0 ? (
          <div style={{ textAlign: 'center', padding: 60, color: 'var(--text-3)' }}>
            <div style={{ fontSize: 40, marginBottom: 12 }}>🔍</div>
            <div>لیدی در این گروه پیدا نشد</div>
          </div>
        ) : (
          <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
            {leads.map((l, i) => {
              const outcomeName = { answered:'جواب داد', no_answer:'جواب نداد', follow_up:'پیگیری', not_interested:'علاقه نداشت', sold:'خرید کرد' };
              const outcomeColor= { answered:'#34D399', no_answer:'#FB923C', follow_up:'#FBBF24', not_interested:'#94A3B8', sold:'#34D399' };
              return (
                <div key={l.id} style={{ display: 'flex', alignItems: 'center', gap: 12, padding: '12px 14px', borderRadius: 12, background: 'var(--surface)', border: '1px solid var(--border-soft)' }}>
                  <div style={{ width: 24, flexShrink: 0, textAlign: 'center', fontSize: 11, color: 'var(--text-3)' }}>{fa(i+1)}</div>
                  <div style={{ width: 34, height: 34, borderRadius: '50%', background: `${stageDef.color}20`, display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0, fontSize: 15 }}>
                    {platIcon[l.platform] || '👤'}
                  </div>
                  <div style={{ flex: 1, minWidth: 0 }}>
                    <div style={{ display: 'flex', alignItems: 'center', gap: 8, flexWrap: 'wrap' }}>
                      <span style={{ fontSize: 13, fontWeight: 600 }}>{l.full_name || '—'}</span>
                      {l.status && <span style={{ padding:'1px 7px', borderRadius:10, background:`${statusColor[l.status]||'#6B7280'}22`, color:statusColor[l.status]||'#6B7280', fontSize:10 }}>{statusLabel[l.status]||l.status}</span>}
                      {l.last_call_outcome && <span style={{ padding:'1px 7px', borderRadius:10, background:`${outcomeColor[l.last_call_outcome]||'#818CF8'}22`, color:outcomeColor[l.last_call_outcome]||'#818CF8', fontSize:10 }}>{outcomeName[l.last_call_outcome]||l.last_call_outcome}</span>}
                    </div>
                    <div style={{ display:'flex', gap:12, marginTop:4, flexWrap:'wrap' }}>
                      {l.phone && <span style={{ fontSize:11, color:'var(--text-2)' }}>📱 <span style={{direction:'ltr'}}>{l.phone}</span></span>}
                      {l.sale_amount > 0 && <span style={{ fontSize:11, color:'#34D399' }}>💰 {fa(Math.round(l.sale_amount))}</span>}
                      {l.call_count > 0 && <span style={{ fontSize:11, color:'var(--text-3)' }}>📞 {fa(l.call_count)} تماس</span>}
                      {l.free_courses_count > 0 && <span style={{ fontSize:11, color:'#60A5FA' }}>🎓 {fa(l.free_courses_count)} دوره</span>}
                    </div>
                  </div>
                  <div style={{ textAlign:'right', flexShrink:0 }}>
                    {l.last_call_at ? (
                      <div><div style={{ fontSize:10, color:'var(--text-3)' }}>آخرین تماس</div><div style={{ fontSize:11, color:'#34D399', fontWeight:600 }}>{ago(l.last_call_at)}</div></div>
                    ) : (
                      <div><div style={{ fontSize:10, color:'var(--text-3)' }}>تماس</div><div style={{ fontSize:11, color:'#F87171', fontWeight:600 }}>ندارد</div></div>
                    )}
                    <div style={{ fontSize:10, color:'var(--text-3)', marginTop:2 }}>ثبت {ago(l.created_at)}</div>
                  </div>
                </div>
              );
            })}
          </div>
        )}
      </div>
    );
  }

  // ── Overview loading/error ─────────────────────────
  if (loading) return (
    <div style={{ textAlign:'center', padding:80, color:'var(--text-3)' }}>
      <div style={{ fontSize:32, marginBottom:12 }}>📊</div>در حال تحلیل لیدها...
    </div>
  );
  if (!data) return <div style={{ padding:40, color:'var(--text-3)' }}>خطا در بارگذاری</div>;

  const { funnel=[], platforms=[], lifecycle={}, filters={}, call_stats=[], assets={}, total=0 } = data;
  const funnelMap = {};
  funnel.forEach(f => { funnelMap[f.status] = f.n; });
  const funnelTotal = funnel.reduce((s,f)=>s+f.n,0);

  return (
    <div>
      {/* هدر */}
      <div className="row between" style={{ marginBottom: 16 }}>
        <div>
          <div className="semi" style={{ fontSize:15 }}>📊 مرکز فرماندهی کمپین</div>
          <div className="text-xs text-3 mt-2">تحلیل وضعیت {fa(total)} لید — کلیک روی هر گروه برای دیدن لیدها</div>
        </div>
        <div className="row gap-8">
          <button onClick={onBack} style={{ padding:'6px 12px', borderRadius:8, border:'1px solid var(--border-soft)', background:'transparent', color:'var(--text-2)', cursor:'pointer', fontSize:12, fontFamily:'inherit' }}>
            ← بازگشت
          </button>
          <Button kind="primary" icon="plus" onClick={() => onCreateCampaign && onCreateCampaign()}>کمپین جدید</Button>
        </div>
      </div>

      {/* قیف */}
      <div style={{ display:'grid', gridTemplateColumns:'repeat(5,1fr)', gap:8, marginBottom:16 }}>
        {[{key:'new',label:'جدید',color:'#A5B4FC',icon:'🆕'},{key:'follow_up',label:'پیگیری',color:'#FBBF24',icon:'🔄'},{key:'buyer',label:'خریدار',color:'#34D399',icon:'✅'},{key:'lost',label:'از دست رفته',color:'#F87171',icon:'❌'},{key:'expired',label:'منقضی',color:'#6B7280',icon:'⏰'}].map(f => {
          const n=funnelMap[f.key]||0, pct=funnelTotal?Math.round(n*100/funnelTotal):0;
          return (
            <div key={f.key} style={{ padding:'10px 8px', borderRadius:10, background:'var(--surface)', border:'1px solid var(--border-soft)', textAlign:'center' }}>
              <div style={{ fontSize:16, marginBottom:3 }}>{f.icon}</div>
              <div className="mono semi" style={{ fontSize:18, color:f.color }}>{fa(n)}</div>
              <div style={{ fontSize:10, color:'var(--text-3)', marginTop:2 }}>{f.label}</div>
              <div style={{ height:3, background:f.color, width:`${Math.max(6,pct)}%`, margin:'6px auto 0', borderRadius:3 }} />
              <div style={{ fontSize:9, color:'var(--text-3)', marginTop:2 }}>{fa(pct)}٪</div>
            </div>
          );
        })}
      </div>

      {/* تب‌ها */}
      <div style={{ display:'flex', gap:0, borderRadius:10, overflow:'hidden', border:'1px solid var(--border-soft)', marginBottom:16 }}>
        {[['lifecycle','🔄 چرخه حیات (بدون overlap)'],['filter','🏷️ فیلتر خصوصیات']].map(([k,l]) => (
          <button key={k} onClick={() => setTab(k)} style={{ flex:1, padding:'10px', border:'none', background:tab===k?'rgba(129,140,248,0.12)':'transparent', color:tab===k?'#818CF8':'var(--text-3)', cursor:'pointer', fontSize:12, fontFamily:'inherit', fontWeight:tab===k?600:400, borderBottom:tab===k?'2px solid #818CF8':'2px solid transparent' }}>
            {l}
          </button>
        ))}
      </div>

      {/* ── تب چرخه حیات ── */}
      {tab === 'lifecycle' && (
        <div style={{ display:'flex', flexDirection:'column', gap:8 }}>
          <div className="text-xs text-3" style={{ marginBottom:4 }}>هر لید فقط در <strong>یه گروه</strong> قرار داره — بر اساس آخرین وضعیت تماس</div>
          {LIFECYCLE.map(seg => {
            const count = (lifecycle.counts && lifecycle.counts[seg.key]) || 0;
            if (!count && seg.key === 'other') return null;
            const bg     = `${seg.color}10`;
            const border = `${seg.color}35`;
            return (
              <div
                key={seg.key}
                onClick={() => count > 0 && setDrillKey(seg.key)}
                style={{ display:'flex', alignItems:'center', gap:12, padding:'12px 16px', borderRadius:12, background:'var(--surface)', border:`1px solid var(--border-soft)`, cursor:count>0?'pointer':'default', opacity:count?1:.4, transition:'all .15s' }}
                onMouseEnter={e => { if(count>0){ e.currentTarget.style.background=bg; e.currentTarget.style.borderColor=border; } }}
                onMouseLeave={e => { e.currentTarget.style.background='var(--surface)'; e.currentTarget.style.borderColor='var(--border-soft)'; }}
              >
                <span style={{ fontSize:22, flexShrink:0 }}>{seg.icon}</span>
                <div style={{ flex:1, minWidth:0 }}>
                  <div style={{ display:'flex', alignItems:'center', gap:8 }}>
                    <span className="semi" style={{ fontSize:12, color:'var(--text-2)' }}>{seg.title}</span>
                    {seg.action && <span style={{ padding:'1px 7px', borderRadius:10, background:`${seg.color}15`, color:seg.color, fontSize:10 }}>{seg.goal==='product'?'فروش':seg.goal==='followup'?'پیگیری':'لیدسازی'}</span>}
                  </div>
                  <div className="text-xs text-3" style={{ marginTop:2 }}>{seg.desc}</div>
                </div>
                <div style={{ textAlign:'center', flexShrink:0 }}>
                  <div className="mono semi" style={{ fontSize:22, color:seg.color, lineHeight:1 }}>{fa(count)}</div>
                  {count > 0 && <div style={{ fontSize:10, color:seg.color, marginTop:2 }}>مشاهده ←</div>}
                </div>
              </div>
            );
          })}
        </div>
      )}

      {/* ── تب فیلتر خصوصیات ── */}
      {tab === 'filter' && (
        <div>
          <div className="text-xs text-3" style={{ marginBottom:12 }}>این ویژگی‌ها <strong>overlapping</strong> هستن — یه لید می‌تونه در چند گروه باشه</div>

          {/* آمار تماس‌ها */}
          {call_stats.length > 0 && (
            <div style={{ padding:'12px 14px', borderRadius:12, background:'var(--surface)', border:'1px solid var(--border-soft)', marginBottom:16 }}>
              <div className="text-xs text-3" style={{ fontWeight:600, marginBottom:10 }}>📞 نتیجه {fa(assets.total_calls||0)} تماس CRM</div>
              <div style={{ display:'flex', gap:8, flexWrap:'wrap' }}>
                {call_stats.map(cs => {
                  const label = {answered:'✅ جواب داد', no_answer:'📵 جواب نداد', follow_up:'🔄 پیگیری', not_interested:'🙅 علاقه نداشت', sold:'💰 خرید کرد'}[cs.outcome] || cs.outcome;
                  const color = {answered:'#34D399', no_answer:'#FB923C', follow_up:'#FBBF24', not_interested:'#94A3B8', sold:'#34D399'}[cs.outcome] || '#818CF8';
                  const pct   = assets.total_calls ? Math.round(cs.n * 100 / assets.total_calls) : 0;
                  return (
                    <div key={cs.outcome} style={{ flex:1, minWidth:120, padding:'10px', borderRadius:10, background:`${color}10`, border:`1px solid ${color}30`, textAlign:'center' }}>
                      <div className="mono semi" style={{ fontSize:20, color }}>{fa(cs.n)}</div>
                      <div style={{ fontSize:10, color:'var(--text-3)', marginTop:3 }}>{label}</div>
                      <div style={{ fontSize:10, color, marginTop:2 }}>{fa(pct)}٪</div>
                    </div>
                  );
                })}
              </div>
            </div>
          )}

          {/* فیلترهای خصوصیات */}
          {FILTER_DEF.map(group => (
            <div key={group.group} style={{ marginBottom:14 }}>
              <div className="text-xs text-3" style={{ fontWeight:600, marginBottom:8 }}>{group.group}</div>
              <div style={{ display:'flex', gap:8, flexWrap:'wrap' }}>
                {group.items.map(item => {
                  const cnt = filters[item.key] || 0;
                  const pct = total ? Math.round(cnt*100/total) : 0;
                  return (
                    <div key={item.key} style={{ padding:'10px 14px', borderRadius:10, background:'var(--surface)', border:'1px solid var(--border-soft)', minWidth:130 }}>
                      <div style={{ display:'flex', justifyContent:'space-between', alignItems:'center' }}>
                        <span style={{ fontSize:12 }}>{item.label}</span>
                        <span className="mono semi" style={{ fontSize:16, color:item.color }}>{fa(cnt)}</span>
                      </div>
                      <div style={{ height:4, borderRadius:4, background:'rgba(255,255,255,0.05)', marginTop:6 }}>
                        <div style={{ height:'100%', borderRadius:4, background:item.color, width:`${pct}%` }} />
                      </div>
                      <div style={{ fontSize:10, color:'var(--text-3)', marginTop:3 }}>{fa(pct)}٪ از کل لیدها</div>
                    </div>
                  );
                })}
              </div>
            </div>
          ))}

          {/* پلتفرم */}
          <div style={{ marginBottom:14 }}>
            <div className="text-xs text-3" style={{ fontWeight:600, marginBottom:8 }}>پلتفرم</div>
            <div style={{ display:'flex', gap:8, flexWrap:'wrap' }}>
              {platforms.map(p => {
                const icon = platIcon[p.platform]||'💬';
                const lbl  = platLabel[p.platform]||p.platform;
                const pct  = total?Math.round(p.n*100/total):0;
                return (
                  <div key={p.platform} style={{ padding:'10px 14px', borderRadius:10, background:'var(--surface)', border:'1px solid var(--border-soft)', minWidth:110 }}>
                    <div style={{ display:'flex', justifyContent:'space-between', alignItems:'center' }}>
                      <span style={{ fontSize:12 }}>{icon} {lbl}</span>
                      <span className="mono semi" style={{ fontSize:16, color:'var(--text-2)' }}>{fa(p.n)}</span>
                    </div>
                    <div style={{ height:4, borderRadius:4, background:'rgba(255,255,255,0.05)', marginTop:6 }}>
                      <div style={{ height:'100%', borderRadius:4, background:'#818CF8', width:`${pct}%` }} />
                    </div>
                    <div style={{ fontSize:10, color:'var(--text-3)', marginTop:3 }}>{fa(pct)}٪</div>
                  </div>
                );
              })}
            </div>
          </div>
        </div>
      )}
    </div>
  );
};

// ══════════════════════════════════════════════════════════
// ── Wizard ساخت کمپین ─────────────────────────────────────
// ══════════════════════════════════════════════════════════
// ── wizard بایگانی شد — بعداً در جای مناسب استفاده می‌شه ──────────
// TODO: وقتی onboarding یا setup flow لازم شد اینجا برگرد
const _CampaignWizard = ({ headers, toast, onDone, onCancel, presets = {} }) => {
  const { Icon, Button } = window.SB_UI;
  const { fa } = window.SB_DATA;

  const [step,   setStep]   = useState(1); // 1..5
  const [saving, setSaving] = useState(false);
  const [w, setW] = useState({
    goal_type:    presets.goal || '',   // product | lead | followup | other
    platform:     '',                   // bale | telegram | rubika | instagram | eitaa | multi
    trigger_type: '',                   // keyword | new_user | manual
    keyword:      '',
    has_script:   false,
    has_files:    false,
    name:         '',
  });
  const set = (k, v) => setW(p => ({ ...p, [k]: v }));

  // نام پیشنهادی بر اساس جواب‌ها
  const autoName = () => {
    const gn = { product: 'فروش', lead: 'لیدسازی', followup: 'پیگیری', other: 'عمومی' };
    const pn = { bale: 'بله', telegram: 'تلگرام', rubika: 'روبیکا', instagram: 'اینستاگرام', eitaa: 'ایتا', multi: 'چند پلتفرم' };
    const g  = gn[w.goal_type] || '';
    const p  = pn[w.platform] || '';
    const kw = w.trigger_type === 'keyword' && w.keyword ? ` «${w.keyword}»` : '';
    return `کمپین ${g} ${p}${kw}`.trim() || 'کمپین جدید';
  };

  // وقتی step4 تموم می‌شه، نام auto پر کن
  const goStep5 = () => {
    if (!w.name) set('name', autoName());
    setStep(5);
  };

  const canNext = () => {
    if (step === 1) return !!w.goal_type;
    if (step === 2) return !!w.platform;
    if (step === 3) return !!w.trigger_type && (w.trigger_type !== 'keyword' || w.keyword.trim().length >= 1);
    if (step === 4) return true; // اختیاریه
    if (step === 5) return !!w.name.trim();
    return false;
  };

  const next = () => {
    if (step === 4) { goStep5(); return; }
    if (step < 5) setStep(s => s + 1);
  };
  const back = () => { if (step > 1) setStep(s => s - 1); };

  const create = () => {
    if (!w.name.trim()) return;
    setSaving(true);
    const goalLabel = { product: 'فروش محصول', lead: 'جمع‌آوری لید', followup: 'پیگیری لیدهای قدیمی', other: 'هدف دیگه' };
    const platLabel = { bale: 'بله', telegram: 'تلگرام', rubika: 'روبیکا', instagram: 'اینستاگرام', eitaa: 'ایتا', multi: 'چند پلتفرم' };
    const trigLabel = { keyword: `کلمه کلیدی «${w.keyword}»`, new_user: 'هر کاربر جدید', manual: 'انتخاب دستی' };
    const goalStr = goalLabel[w.goal_type] || w.goal_type;
    const meta = { platform: w.platform, trigger_type: w.trigger_type, keyword: w.keyword, has_script: w.has_script, has_files: w.has_files };
    fetch('/api/campaigns/campaigns', {
      method: 'POST', headers,
      body: JSON.stringify({
        name:  w.name.trim(),
        goal:  goalStr,
        type:  w.goal_type === 'product' ? 'product' : w.goal_type === 'free' ? 'free' : 'branding',
        notes: `پلتفرم: ${platLabel[w.platform]} | شروع: ${trigLabel[w.trigger_type]} | اسکریپت: ${w.has_script?'دارم':'ندارم'} | فایل: ${w.has_files?'دارم':'ندارم'}\n${JSON.stringify(meta)}`,
      }),
    })
      .then(r => r.json())
      .then(d => {
        if (d.id) { toast('کمپین ساخته شد ✓', 'success'); onDone(d); }
        else toast(d.error || 'خطا در ساخت', 'error');
      })
      .finally(() => setSaving(false));
  };

  // ── رنگ‌ها ──
  const SEL = 'rgba(99,102,241,0.15)';
  const SEL_B = '1px solid rgba(99,102,241,0.5)';
  const NRM = 'var(--surface)';
  const NRM_B = '1px solid var(--border-soft)';

  const Card = ({ chosen, onClick, icon, label, desc }) => (
    <div onClick={onClick} style={{ padding: '14px 16px', borderRadius: 10, cursor: 'pointer', display: 'flex', alignItems: 'flex-start', gap: 12, background: chosen ? SEL : NRM, border: chosen ? SEL_B : NRM_B, transition: 'all .15s' }}>
      <div style={{ width: 34, height: 34, borderRadius: 8, background: chosen ? 'rgba(99,102,241,0.2)' : 'rgba(255,255,255,0.05)', display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }}>
        {typeof icon === 'string' && icon.length <= 2
          ? <span style={{ fontSize: 17 }}>{icon}</span>
          : <Icon name={icon} size={16} color={chosen ? '#818CF8' : 'var(--text-3)'} />
        }
      </div>
      <div>
        <div style={{ fontSize: 13, fontWeight: 600, color: chosen ? '#e2e8f0' : 'var(--text-2)' }}>{label}</div>
        {desc && <div style={{ fontSize: 11, color: 'var(--text-3)', marginTop: 3, lineHeight: 1.6 }}>{desc}</div>}
      </div>
      {chosen && <div style={{ marginRight: 'auto', flexShrink: 0, width: 18, height: 18, borderRadius: '50%', background: '#818CF8', display: 'flex', alignItems: 'center', justifyContent: 'center' }}><Icon name="check" size={11} color="#fff"/></div>}
    </div>
  );

  // ── Progress bar ──
  const Progress = () => (
    <div style={{ display: 'flex', gap: 6, marginBottom: 24 }}>
      {[1,2,3,4,5].map(i => (
        <div key={i} style={{ flex: 1, height: 3, borderRadius: 3, background: i <= step ? '#818CF8' : 'rgba(255,255,255,0.08)', transition: 'background .3s' }} />
      ))}
    </div>
  );

  const STEP_LABELS = ['هدف', 'پلتفرم', 'شروع', 'محتوا', 'تأیید'];

  return (
    <div style={{ maxWidth: 540, margin: '0 auto' }}>
      {/* هدر */}
      <div className="row between" style={{ marginBottom: 20 }}>
        <div>
          <div className="semi" style={{ fontSize: 15 }}>کمپین جدید</div>
          <div className="text-xs text-3 mt-2">گام {fa(step)} از ۵ — {STEP_LABELS[step-1]}</div>
        </div>
        <button onClick={onCancel} style={{ padding: '5px 12px', borderRadius: 8, border: '1px solid var(--border-soft)', background: 'transparent', color: 'var(--text-3)', cursor: 'pointer', fontSize: 12, fontFamily: 'inherit' }}>
          انصراف
        </button>
      </div>

      <Progress />

      {/* ── Step 1: هدف ── */}
      {step === 1 && (
        <div className="col gap-10">
          <div className="semi" style={{ marginBottom: 6 }}>هدف این کمپین چیه؟</div>
          <Card chosen={w.goal_type==='product'} onClick={() => set('goal_type','product')} icon="shopping-bag" label="فروش یه محصول یا دوره" desc="می‌خوای لیدها رو به خرید یه محصول خاص هدایت کنی" />
          <Card chosen={w.goal_type==='lead'}    onClick={() => set('goal_type','lead')}    icon="user-plus"    label="جمع‌آوری لید جدید"           desc="می‌خوای مخاطبین جدید رو وارد سیستم کنی و اطلاعاتشون رو بگیری" />
          <Card chosen={w.goal_type==='followup'}onClick={() => set('goal_type','followup')}icon="refresh-cw"   label="پیگیری لیدهای قدیمی"         desc="کسایی که قبلاً پیام دادن ولی خرید نکردن رو دوباره فعال کنی" />
          <Card chosen={w.goal_type==='other'}   onClick={() => set('goal_type','other')}   icon="more-horizontal" label="هدف دیگه‌ای دارم"          desc="اطلاع‌رسانی، رویداد، نظرسنجی و..." />
        </div>
      )}

      {/* ── Step 2: پلتفرم ── */}
      {step === 2 && (
        <div className="col gap-10">
          <div className="semi" style={{ marginBottom: 6 }}>پلتفرم هدف؟</div>
          <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 10 }}>
            <Card chosen={w.platform==='bale'}      onClick={() => set('platform','bale')}      icon="💬" label="بله"          desc="پیام از طریق بله" />
            <Card chosen={w.platform==='telegram'}  onClick={() => set('platform','telegram')}  icon="✈️" label="تلگرام"      desc="پیام از طریق تلگرام" />
            <Card chosen={w.platform==='rubika'}    onClick={() => set('platform','rubika')}    icon="🔵" label="روبیکا"      desc="پیام از طریق روبیکا" />
            <Card chosen={w.platform==='instagram'} onClick={() => set('platform','instagram')} icon="📷" label="اینستاگرام" desc="پیام از طریق اینستاگرام" />
            <Card chosen={w.platform==='eitaa'}     onClick={() => set('platform','eitaa')}     icon="🟢" label="ایتا"        desc="پیام از طریق ایتا" />
            <Card chosen={w.platform==='multi'}     onClick={() => set('platform','multi')}     icon="layers"  label="چند پلتفرم"  desc="ارسال همزمان روی چند کانال" />
          </div>
        </div>
      )}

      {/* ── Step 3: نحوه شروع ── */}
      {step === 3 && (
        <div className="col gap-10">
          <div className="semi" style={{ marginBottom: 6 }}>کمپین چطور شروع می‌شه؟</div>
          <Card chosen={w.trigger_type==='keyword'}  onClick={() => set('trigger_type','keyword')}  icon="hash"        label="کاربر یه کلمه کلیدی خاص می‌فرسته" desc="مثلاً «دوره»، «ثبت‌نام»، «قیمت» — هر کس این رو بفرسته وارد کمپین می‌شه" />
          <Card chosen={w.trigger_type==='new_user'} onClick={() => set('trigger_type','new_user')} icon="user"        label="هر کسی که اولین بار پیام بده"         desc="همه مخاطبین جدید خودکار وارد کمپین می‌شن" />
          <Card chosen={w.trigger_type==='manual'}   onClick={() => set('trigger_type','manual')}   icon="mouse-pointer" label="دستی — خودم انتخاب می‌کنم"           desc="تو از پنل لیدها، هر لیدی که خواستی وارد این کمپین می‌کنی" />

          {w.trigger_type === 'keyword' && (
            <div style={{ marginTop: 4 }}>
              <div className="text-xs text-3" style={{ marginBottom: 6 }}>کلمه کلیدی رو بنویس:</div>
              <input
                className="input" autoFocus
                value={w.keyword}
                onChange={e => set('keyword', e.target.value)}
                placeholder="مثلاً: دوره، ثبت نام، قیمت"
                style={{ width: '100%' }}
              />
            </div>
          )}
        </div>
      )}

      {/* ── Step 4: محتوا ── */}
      {step === 4 && (
        <div className="col gap-10">
          <div className="semi" style={{ marginBottom: 6 }}>محتوا داری؟</div>
          <div className="text-xs text-3" style={{ marginBottom: 8, lineHeight: 1.7 }}>
            این گام اختیاریه — فقط می‌خوایم بدونیم الان چی داری تا بعداً بهتر راهنماییت کنیم.
          </div>

          {/* چک‌باکس — چند تا با هم انتخاب می‌شه */}
          {[
            { key: 'has_script', icon: 'file-text',  label: 'متن اسکریپت دارم',            desc: 'نوشتی بات چی بگه، چطور شروع کنه، چطور پیگیری کنه' },
            { key: 'has_files',  icon: 'video',       label: 'ویدیو یا فایل آماده دارم',    desc: 'ویدیو معرفی، PDF، عکس — چیزی که بات باید بفرسته' },
          ].map(item => {
            const on = w[item.key];
            return (
              <div key={item.key} onClick={() => set(item.key, !on)} style={{ padding: '14px 16px', borderRadius: 10, cursor: 'pointer', display: 'flex', alignItems: 'flex-start', gap: 12, background: on ? SEL : NRM, border: on ? SEL_B : NRM_B, transition: 'all .15s' }}>
                <div style={{ width: 34, height: 34, borderRadius: 8, background: on ? 'rgba(99,102,241,0.2)' : 'rgba(255,255,255,0.05)', display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }}>
                  <Icon name={item.icon} size={16} color={on ? '#818CF8' : 'var(--text-3)'} />
                </div>
                <div style={{ flex: 1 }}>
                  <div style={{ fontSize: 13, fontWeight: 600, color: on ? '#e2e8f0' : 'var(--text-2)' }}>{item.label}</div>
                  <div style={{ fontSize: 11, color: 'var(--text-3)', marginTop: 3 }}>{item.desc}</div>
                </div>
                <div style={{ width: 18, height: 18, borderRadius: 4, border: `2px solid ${on ? '#818CF8' : 'rgba(255,255,255,0.15)'}`, background: on ? '#818CF8' : 'transparent', display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0, marginTop: 2 }}>
                  {on && <Icon name="check" size={11} color="#fff" />}
                </div>
              </div>
            );
          })}

          {/* اگه هیچ‌چیزی نداره */}
          <div onClick={() => { set('has_script', false); set('has_files', false); }} style={{ padding: '12px 16px', borderRadius: 10, cursor: 'pointer', display: 'flex', alignItems: 'center', gap: 12, background: (!w.has_script && !w.has_files) ? SEL : NRM, border: (!w.has_script && !w.has_files) ? SEL_B : NRM_B, transition: 'all .15s' }}>
            <div style={{ width: 34, height: 34, borderRadius: 8, background: 'rgba(255,255,255,0.05)', display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }}>
              <Icon name="clock" size={16} color="var(--text-3)" />
            </div>
            <div style={{ fontSize: 13, fontWeight: 600, color: 'var(--text-2)' }}>هنوز هیچ‌کدوم رو ندارم</div>
          </div>
        </div>
      )}

      {/* ── Step 5: نام و تأیید ── */}
      {step === 5 && (
        <div className="col gap-16">
          <div className="semi" style={{ marginBottom: 2 }}>یه نام برای کمپین بذار</div>

          <input
            className="input" autoFocus
            value={w.name}
            onChange={e => set('name', e.target.value)}
            placeholder="نام کمپین..."
            style={{ width: '100%', fontSize: 14 }}
          />

          {/* خلاصه */}
          <div style={{ background: 'var(--surface)', border: '1px solid var(--border-soft)', borderRadius: 10, padding: '14px 16px' }}>
            <div className="text-xs text-3" style={{ marginBottom: 10, fontWeight: 600 }}>خلاصه تنظیمات</div>
            {[
              { icon: 'target',  label: 'هدف',    val: { product:'فروش محصول', lead:'جمع‌آوری لید', followup:'پیگیری لیدها', other:'هدف دیگه' }[w.goal_type] },
              { icon: 'layers',  label: 'پلتفرم', val: { bale:'بله', telegram:'تلگرام', rubika:'روبیکا', instagram:'اینستاگرام', eitaa:'ایتا', multi:'چند پلتفرم' }[w.platform] },
              { icon: 'play',    label: 'شروع',   val: w.trigger_type === 'keyword' ? `کلمه کلیدی «${w.keyword}»` : w.trigger_type === 'new_user' ? 'هر کاربر جدید' : 'دستی' },
              { icon: 'package', label: 'محتوا',  val: [w.has_script && 'اسکریپت', w.has_files && 'فایل'].filter(Boolean).join(' + ') || 'هنوز ندارم' },
            ].map(row => (
              <div key={row.label} style={{ display: 'flex', gap: 10, alignItems: 'center', marginBottom: 8 }}>
                <Icon name={row.icon} size={13} color="var(--text-3)" />
                <span className="text-xs text-3" style={{ width: 50, flexShrink: 0 }}>{row.label}</span>
                <span className="text-xs" style={{ color: '#818CF8' }}>{row.val}</span>
              </div>
            ))}
          </div>

          {/* قدم بعدی */}
          <div style={{ padding: '12px 14px', borderRadius: 10, background: 'rgba(251,191,36,0.06)', border: '1px solid rgba(251,191,36,0.2)' }}>
            <div className="text-xs" style={{ color: '#FBBF24', fontWeight: 600, marginBottom: 6 }}>📋 بعد از ساخت کمپین باید:</div>
            <div className="text-xs text-3" style={{ lineHeight: 2 }}>
              {!w.has_script && '۱. برو اسکریپت بساز (منوی اسکریپت‌ها)\n'}
              {w.trigger_type === 'keyword' && `${!w.has_script ? '۲' : '۱'}. تریگر «${w.keyword}» رو به این اسکریپت وصل کن (منوی تریگرها)\n`}
              {!w.has_files && w.has_script && '۲. فایل‌هات رو آپلود کن (منوی کتابخانه)\n'}
              {'✅ بعدش کمپین رو فعال کن'}
            </div>
          </div>
        </div>
      )}

      {/* ── دکمه‌های ناوبری ── */}
      <div className="row between" style={{ marginTop: 24 }}>
        <button onClick={back} disabled={step === 1} style={{ padding: '8px 16px', borderRadius: 8, border: '1px solid var(--border-soft)', background: 'transparent', color: step === 1 ? 'var(--text-3)' : 'var(--text-2)', cursor: step === 1 ? 'default' : 'pointer', fontSize: 13, fontFamily: 'inherit', opacity: step === 1 ? .4 : 1 }}>
          ← قبلی
        </button>
        {step < 5 ? (
          <Button kind="primary" onClick={next} disabled={!canNext()}>
            بعدی ←
          </Button>
        ) : (
          <Button kind="primary" onClick={create} disabled={saving || !w.name.trim()}>
            {saving ? 'در حال ساخت...' : '🚀 ساخت کمپین'}
          </Button>
        )}
      </div>
    </div>
  );
};

// ══════════════════════════════════════════════════════════
// ── صفحه جزئیات کمپین ────────────────────────────────────
// ══════════════════════════════════════════════════════════
// ── ویرایشگر بصری فلو (داخل کمپین) ──────────────────────
// ══════════════════════════════════════════════════════════

const NODE_TYPES = {
  trigger:   { label:'تریگر',    icon:'⚡', color:'#34D399', ports:{ out:['out'] } },
  script:    { label:'اسکریپت', icon:'📝', color:'#A78BFA', ports:{ out:['out','else'] } },
  delay:     { label:'تأخیر',   icon:'⏱', color:'#FBBF24', ports:{ out:['out'] } },
  condition: { label:'شرط',     icon:'❓', color:'#FB923C', ports:{ out:['yes','no'] } },
  action:    { label:'اکشن',    icon:'📤', color:'#60A5FA', ports:{ out:['out'] } },
  end:       { label:'پایان',   icon:'🛑', color:'#F87171', ports:{ out:[] } },
};

const mkId = () => 'n_' + Math.random().toString(36).slice(2,10);
const eId  = () => 'e_' + Math.random().toString(36).slice(2,10);

const CampaignFlowBuilder = ({ campaignId, initialFlow, onSave, scripts=[], flowFields={} }) => {
  const openMainDesigner = () => {
    window.SB_openCampaign = campaignId;
    window.SB_setPage && window.SB_setPage('flow');
  };

  return (
    <div style={{ border:'1px solid var(--border-soft)', borderRadius:12, background:'var(--surface)', padding:22, display:'flex', alignItems:'center', justifyContent:'space-between', gap:18, direction:'rtl' }}>
      <div style={{ minWidth:0 }}>
        <div style={{ fontSize:15, fontWeight:800, marginBottom:7 }}>طراحی فلو در طراح اصلی انجام می‌شود</div>
        <div style={{ fontSize:12, color:'var(--text-3)', lineHeight:1.9 }}>
          برای جلوگیری از دو نسخه شدن فلو، ادیتور داخلی کمپین غیرفعال شده و همین کمپین در طراح اصلی باز می‌شود.
        </div>
      </div>
      <button onClick={openMainDesigner}
        style={{ padding:'10px 16px', borderRadius:9, border:'1px solid rgba(129,140,248,0.35)', background:'rgba(129,140,248,0.16)', color:'#C4B5FD', cursor:'pointer', fontSize:12, fontFamily:'inherit', fontWeight:800, whiteSpace:'nowrap' }}>
        باز کردن طراح فلو
      </button>
    </div>
  );

  const { fa } = window.SB_DATA;
  const [nodes,    setNodes]    = useState(() => { try { const f=typeof initialFlow==='string'?JSON.parse(initialFlow||'{}'):initialFlow||{}; return Array.isArray(f.nodes)?f.nodes:Object.values(f.nodes||{}); } catch{return[];} });
  const [edges,    setEdges]    = useState(() => { try { const f=typeof initialFlow==='string'?JSON.parse(initialFlow||'{}'):initialFlow||{}; return f.edges||[]; } catch{return[];} });
  const [sel,      setSel]      = useState(null);  // selected node id
  const [drag,     setDrag]     = useState(null);  // { nodeId, ox, oy }
  const [linking,  setLinking]  = useState(null);  // { from, fromPort }
  const [simResult,setSimResult]= useState(null);
  const [saving,   setSaving]   = useState(false);
  const svgRef  = useRef(null);
  const canvRef = useRef(null);

  const selNode = nodes.find(n => n.id === sel);

  // ── helpers ───────────────────────────────────────────
  const updNode = (id, patch) => setNodes(ns => ns.map(n => n.id===id ? {...n,...patch} : n));
  const updCfg  = (id, patch) => setNodes(ns => ns.map(n => n.id===id ? {...n, config:{...n.config,...patch}} : n));

  const addNode = (type) => {
    const id = mkId();
    setNodes(ns => [...ns, { id, type, label: NODE_TYPES[type].label, x: 80 + ns.length * 20, y: 80 + ns.length * 20, config:{} }]);
    setSel(id);
  };

  const removeNode = (id) => {
    setNodes(ns => ns.filter(n => n.id !== id));
    setEdges(es => es.filter(e => e.from !== id && e.to !== id));
    if (sel === id) setSel(null);
  };

  const addEdge = (from, fromPort, to) => {
    if (from === to) return;
    // پاک کردن edge قبلی از همین port
    setEdges(es => { const clean = es.filter(e => !(e.from===from && e.fromPort===fromPort)); return [...clean, { id:eId(), from, fromPort, to }]; });
  };

  const removeEdge = (id) => setEdges(es => es.filter(e => e.id !== id));

  const getPortPos = (node, portName, side='out') => {
    const W=160, H=56;
    if (side === 'in')  return { x: node.x,     y: node.y + H/2 };
    const ports = NODE_TYPES[node.type].ports.out;
    const idx   = ports.indexOf(portName);
    const total = ports.length;
    if (total === 0) return { x: node.x + W, y: node.y + H/2 };
    const step = H / (total+1);
    return { x: node.x + W, y: node.y + step*(idx+1) };
  };

  // ── drag node ─────────────────────────────────────────
  const onNodeMouseDown = (e, id) => {
    if (linking) return;
    e.stopPropagation();
    const node = nodes.find(n => n.id === id);
    const rect = canvRef.current.getBoundingClientRect();
    setDrag({ nodeId: id, ox: e.clientX - rect.left - node.x, oy: e.clientY - rect.top - node.y });
    setSel(id);
  };

  const onCanvasMouseMove = (e) => {
    if (!drag) return;
    const rect = canvRef.current.getBoundingClientRect();
    updNode(drag.nodeId, { x: Math.max(0, e.clientX-rect.left-drag.ox), y: Math.max(0, e.clientY-rect.top-drag.oy) });
  };

  const onCanvasMouseUp = () => { setDrag(null); };

  // ── linking ───────────────────────────────────────────
  const onPortClick = (e, nodeId, port) => {
    e.stopPropagation();
    if (!linking) { setLinking({ from: nodeId, fromPort: port }); return; }
    if (linking.from !== nodeId) { addEdge(linking.from, linking.fromPort, nodeId); }
    setLinking(null);
  };

  const onCanvasClick = () => { if (linking) setLinking(null); };

  // ── simulate ──────────────────────────────────────────
  const simulate = () => {
    const flow = { nodes, edges };
    window.api('/campaigns/' + campaignId + '/flow/simulate', { method:'POST', body:{ _flow: flow } })
      .then(d => setSimResult(d));
  };

  // ── save ──────────────────────────────────────────────
  const save = () => {
    setSaving(true);
    window.api('/campaigns/' + campaignId + '/flow', { method:'PUT', body:{ nodes, edges } })
      .then(d => { if (onSave) onSave({ nodes, edges }); })
      .finally(() => setSaving(false));
  };

  const portColors = { out:'#34D399', yes:'#34D399', no:'#F87171', else:'#FBBF24' };
  const portLabels = { out:'', yes:'بله', no:'خیر', else:'بقیه' };

  // ── helpers شرط (checks array) ────────────────────────
  const chId     = () => 'ch_' + Math.random().toString(36).slice(2,8);
  const getChecks = (node) => (node && node.config && Array.isArray(node.config.checks)) ? node.config.checks : [];
  const setChecks = (nodeId, checks) => setNodes(ns => ns.map(n => n.id===nodeId ? {...n, config:{...n.config, checks}} : n));
  const addCheck  = (nodeId) => setChecks(nodeId, [...getChecks(nodes.find(n=>n.id===nodeId)), { id:chId(), type:'lead', kind:'has_phone' }]);
  const removeCheck = (nodeId, chId2) => setChecks(nodeId, getChecks(nodes.find(n=>n.id===nodeId)).filter(c=>c.id!==chId2));
  const updateCheck = (nodeId, chId2, patch) => setChecks(nodeId, getChecks(nodes.find(n=>n.id===nodeId)).map(c=>c.id===chId2?{...c,...patch}:c));

  // ── رندر یک check item ────────────────────────────────
  const renderCheck = (ch, nodeId) => {
    const inp = (style) => ({ ...style, padding:'4px 6px', borderRadius:5, border:'1px solid var(--border-soft)', background:'rgba(255,255,255,0.04)', color:'var(--text-1)', fontSize:10, fontFamily:'inherit', width:'100%', boxSizing:'border-box' });
    const sel2 = (style) => ({ ...style, padding:'4px 6px', borderRadius:5, border:'1px solid var(--border-soft)', background:'#111125', color:'var(--text-1)', fontSize:10, fontFamily:'inherit', width:'100%' });
    const typeColor = { lead:'#A5B4FC', field:'#60A5FA', state:'#FBBF24' };
    return (
      <div key={ch.id} style={{ marginBottom:8, padding:'8px', borderRadius:8, background:'rgba(255,255,255,0.03)', border:`1px solid ${typeColor[ch.type]||'#333'}40` }}>
        {/* نوع + حذف */}
        <div style={{ display:'flex', alignItems:'center', gap:4, marginBottom:6 }}>
          <select value={ch.type} onChange={e=>updateCheck(nodeId,ch.id,{type:e.target.value,kind:'has_phone',field:'',value:'',op:'exists'})} style={sel2({flex:1})}>
            <option value="lead">📋 وضعیت لید</option>
            <option value="field">📝 فیلد جمع‌آوری</option>
            <option value="state">🔵 مرحله اسکریپت</option>
          </select>
          <span onClick={()=>removeCheck(nodeId,ch.id)} style={{ fontSize:12, color:'#F87171', cursor:'pointer', padding:'0 4px', flexShrink:0 }}>✕</span>
        </div>

        {/* ── وضعیت لید ── */}
        {ch.type === 'lead' && (
          <select value={ch.kind||'has_phone'} onChange={e=>updateCheck(nodeId,ch.id,{kind:e.target.value})} style={sel2({})}>
            <option value="has_phone">📱 تلفن دارد</option>
            <option value="purchased">💰 خرید کرد</option>
            <option value="not_interested">🙅 علاقه نداشت</option>
            <option value="replied">💬 پاسخ داد</option>
          </select>
        )}

        {/* ── فیلد جمع‌آوری ── */}
        {ch.type === 'field' && (
          <div style={{ display:'flex', flexDirection:'column', gap:4 }}>
            <select value={ch.field||''} onChange={e=>updateCheck(nodeId,ch.id,{field:e.target.value})} style={sel2({})}>
              <option value="">انتخاب فیلد...</option>
              {(flowFields.fields||[]).map(f=><option key={f} value={f}>{f}</option>)}
            </select>
            <select value={ch.op||'exists'} onChange={e=>updateCheck(nodeId,ch.id,{op:e.target.value})} style={sel2({})}>
              <option value="exists">داده شده</option>
              <option value="empty">خالیه</option>
              <option value="eq">برابر است با</option>
              <option value="contains">شامل می‌شود</option>
              <option value="gt">بیشتر از</option>
              <option value="lt">کمتر از</option>
            </select>
            {(ch.op==='eq'||ch.op==='contains'||ch.op==='gt'||ch.op==='lt') && (
              <input placeholder="مقدار..." value={ch.value||''} onChange={e=>updateCheck(nodeId,ch.id,{value:e.target.value})} style={inp({})} />
            )}
          </div>
        )}

        {/* ── مرحله اسکریپت ── */}
        {ch.type === 'state' && (
          <div style={{ display:'flex', flexDirection:'column', gap:4 }}>
            <select value={ch.op||'is'} onChange={e=>updateCheck(nodeId,ch.id,{op:e.target.value})} style={sel2({})}>
              <option value="is">در این مرحله‌ست</option>
              <option value="neq">در این مرحله نیست</option>
              <option value="stuck">گیر کرده در این مرحله</option>
            </select>
            <select value={ch.value||''} onChange={e=>updateCheck(nodeId,ch.id,{value:e.target.value})} style={sel2({})}>
              <option value="">انتخاب مرحله...</option>
              {(flowFields.states||[]).map(s=><option key={s} value={s}>{s}</option>)}
            </select>
            {ch.op==='stuck' && (
              <div style={{ display:'flex', alignItems:'center', gap:4 }}>
                <input type="number" min="0" placeholder="ساعت" value={ch.hours||''} onChange={e=>updateCheck(nodeId,ch.id,{hours:Number(e.target.value)})} style={inp({direction:'ltr'})} />
                <span style={{ fontSize:10, color:'var(--text-3)', flexShrink:0 }}>ساعت</span>
              </div>
            )}
          </div>
        )}
      </div>
    );
  };

  return (
    <div style={{ display:'flex', gap:0, height:540, border:'1px solid var(--border-soft)', borderRadius:12, overflow:'hidden' }}>

      {/* ── پنل چپ: اضافه کردن نود ── */}
      <div style={{ width:110, background:'var(--surface)', borderLeft:'1px solid var(--border-soft)', flexShrink:0, padding:'10px 8px', overflowY:'auto' }}>
        <div style={{ fontSize:9, color:'var(--text-3)', marginBottom:6, fontWeight:600, textAlign:'center', letterSpacing:'.5px', textTransform:'uppercase' }}>+ اضافه کن</div>
        {Object.entries(NODE_TYPES).map(([type, def]) => (
          <button key={type}
            onClick={() => addNode(type)}
            onMouseEnter={e => { e.currentTarget.style.background=`${def.color}18`; e.currentTarget.style.borderColor=`${def.color}60`; }}
            onMouseLeave={e => { e.currentTarget.style.background=`${def.color}06`; e.currentTarget.style.borderColor=`${def.color}25`; }}
            style={{ display:'flex', alignItems:'center', gap:5, padding:'6px 7px', borderRadius:7, cursor:'pointer', marginBottom:4, border:`1px solid ${def.color}25`, background:`${def.color}06`, fontSize:11, width:'100%', fontFamily:'inherit', color:def.color, transition:'all .1s' }}>
            <span style={{ fontSize:13 }}>{def.icon}</span>
            <span style={{ fontWeight:600 }}>{def.label}</span>
          </button>
        ))}
        <div style={{ marginTop:12, borderTop:'1px solid var(--border-soft)', paddingTop:10, display:'flex', flexDirection:'column', gap:5 }}>
          <button onClick={save} disabled={saving}
            style={{ padding:'7px', borderRadius:7, border:'none', background:saving?'#1a1a2e':'#34D399', color:saving?'var(--text-3)':'#000', cursor:saving?'default':'pointer', fontSize:11, fontWeight:700, fontFamily:'inherit' }}>
            {saving ? '...' : '💾 ذخیره'}
          </button>
          <button onClick={simulate}
            style={{ padding:'7px', borderRadius:7, border:'1px solid rgba(99,102,241,0.35)', background:'rgba(99,102,241,0.07)', color:'#818CF8', cursor:'pointer', fontSize:11, fontFamily:'inherit', fontWeight:600 }}>
            ▶ تست
          </button>
        </div>
        {linking && (
          <div style={{ marginTop:8, padding:'6px 7px', borderRadius:6, background:'rgba(251,191,36,0.08)', border:'1px solid rgba(251,191,36,0.3)', fontSize:9, color:'#FBBF24', textAlign:'center' }}>
            روی نود مقصد کلیک کن
          </div>
        )}
      </div>

      {/* ── canvas ── */}
      <div ref={canvRef} style={{ flex:1, position:'relative', overflow:'hidden', background:'#0d0d14', cursor: linking ? 'crosshair' : 'default' }}
        onMouseMove={onCanvasMouseMove} onMouseUp={onCanvasMouseUp} onClick={onCanvasClick}>

        {/* SVG edges */}
        <svg ref={svgRef} style={{ position:'absolute', top:0, left:0, width:'100%', height:'100%', pointerEvents:'none', overflow:'visible' }}>
          <defs>
            <marker id="arr" markerWidth="6" markerHeight="6" refX="5" refY="3" orient="auto">
              <path d="M0,0 L0,6 L6,3 z" fill="rgba(255,255,255,0.25)" />
            </marker>
          </defs>
          {edges.map(e => {
            const fn = nodes.find(n => n.id === e.from);
            const tn = nodes.find(n => n.id === e.to);
            if (!fn || !tn) return null;
            const fp = getPortPos(fn, e.fromPort, 'out');
            const tp = getPortPos(tn, null, 'in');
            const cx = (fp.x + tp.x) / 2;
            const clr = portColors[e.fromPort] || '#818CF8';
            return (
              <g key={e.id} style={{ pointerEvents:'all', cursor:'pointer' }} onClick={() => removeEdge(e.id)}>
                <path d={`M${fp.x},${fp.y} C${cx},${fp.y} ${cx},${tp.y} ${tp.x},${tp.y}`}
                  stroke={clr} strokeWidth="2" fill="none" strokeDasharray="5,3" opacity=".7" markerEnd="url(#arr)" />
                {portLabels[e.fromPort] && (
                  <text x={(fp.x+cx)/2} y={fp.y-4} fill={clr} fontSize="9" textAnchor="middle">{portLabels[e.fromPort]}</text>
                )}
              </g>
            );
          })}
        </svg>

        {/* Nodes */}
        {nodes.map(node => {
          const def   = NODE_TYPES[node.type] || NODE_TYPES.end;
          const ports = def.ports.out;
          const isSel = node.id === sel;
          const W=160, H=56;
          return (
            <div key={node.id}
              onMouseDown={e => onNodeMouseDown(e, node.id)}
              style={{ position:'absolute', left:node.x, top:node.y, width:W, height:H, borderRadius:10,
                background:'#1a1a2e', border:`2px solid ${isSel ? def.color : def.color+'60'}`,
                boxShadow: isSel ? `0 0 0 2px ${def.color}40` : 'none',
                cursor:'move', userSelect:'none', zIndex: isSel ? 10 : 5 }}>
              {/* header */}
              <div style={{ display:'flex', alignItems:'center', gap:6, padding:'6px 10px', borderBottom:`1px solid ${def.color}30` }}>
                <span style={{ fontSize:14 }}>{def.icon}</span>
                <span style={{ fontSize:11, fontWeight:600, color:def.color, flex:1, minWidth:0, overflow:'hidden', textOverflow:'ellipsis', whiteSpace:'nowrap' }}>{node.label || def.label}</span>
                <span onClick={e=>{e.stopPropagation();removeNode(node.id);}} style={{ fontSize:10, color:'var(--text-3)', cursor:'pointer', padding:'1px 4px' }}>✕</span>
              </div>
              {/* body */}
              <div style={{ padding:'4px 10px', fontSize:10, color:'var(--text-3)', overflow:'hidden', textOverflow:'ellipsis', whiteSpace:'nowrap' }}>
                {node.config && (node.config.event || node.config.script_id || node.config.hours!=null ? `${node.config.event||node.config.script_id||(node.config.hours+'h')||''}` : node.config.kind||node.config.value||'')}
              </div>
              {/* in port */}
              {node.type !== 'trigger' && (
                <div onClick={e=>onPortClick(e,node.id,'in')}
                  style={{ position:'absolute', left:-7, top:H/2-7, width:14, height:14, borderRadius:'50%', background:'#1a1a2e', border:'2px solid rgba(255,255,255,0.3)', cursor:'crosshair', zIndex:20 }} />
              )}
              {/* out ports */}
              {ports.map((port, idx) => {
                const step = H/(ports.length+1);
                return (
                  <div key={port} onClick={e=>onPortClick(e,node.id,port)}
                    title={portLabels[port]||''}
                    style={{ position:'absolute', right:-7, top:step*(idx+1)-7, width:14, height:14, borderRadius:'50%', background: portColors[port]||def.color, border:'2px solid #1a1a2e', cursor:'crosshair', zIndex:20 }} />
                );
              })}
            </div>
          );
        })}

        {nodes.length === 0 && (
          <div style={{ position:'absolute', inset:0, display:'flex', flexDirection:'column', alignItems:'center', justifyContent:'center', color:'var(--text-3)', pointerEvents:'none' }}>
            <div style={{ fontSize:32, marginBottom:8 }}>🔀</div>
            <div style={{ fontSize:12 }}>از پنل چپ نود اضافه کن</div>
            <div style={{ fontSize:11, marginTop:4, opacity:.6 }}>⚡ با تریگر شروع کن</div>
          </div>
        )}
      </div>

      {/* ── پنل راست: config ── */}
      {selNode && (
        <div style={{ width:200, background:'var(--surface)', borderRight:'1px solid var(--border-soft)', flexShrink:0, padding:'12px 10px', overflowY:'auto' }}>
          <div style={{ fontSize:11, fontWeight:700, color:NODE_TYPES[selNode.type].color, marginBottom:12 }}>
            {NODE_TYPES[selNode.type].icon} {NODE_TYPES[selNode.type].label}
          </div>

          {/* label */}
          <div style={{ marginBottom:10 }}>
            <div style={{ fontSize:10, color:'var(--text-3)', marginBottom:3 }}>برچسب</div>
            <input value={selNode.label||''} onChange={e=>updNode(sel,{label:e.target.value})}
              style={{ width:'100%', padding:'5px 8px', borderRadius:6, border:'1px solid var(--border-soft)', background:'rgba(255,255,255,0.04)', color:'var(--text-1)', fontSize:11, boxSizing:'border-box', fontFamily:'inherit' }} />
          </div>

          {/* trigger config */}
          {selNode.type === 'trigger' && (
            <div>
              <div style={{ fontSize:10, color:'var(--text-3)', marginBottom:3 }}>رویداد</div>
              <select value={selNode.config.event||'new_lead'} onChange={e=>updCfg(sel,{event:e.target.value})}
                style={{ width:'100%', padding:'5px 8px', borderRadius:6, border:'1px solid var(--border-soft)', background:'#1a1a2e', color:'var(--text-1)', fontSize:11, fontFamily:'inherit' }}>
                <option value="new_lead">لید جدید</option>
                <option value="keyword">کلمه کلیدی</option>
                <option value="no_reply">جواب نداد</option>
                <option value="status_change">تغییر وضعیت</option>
                <option value="manual">دستی</option>
              </select>
              {selNode.config.event === 'keyword' && (
                <input placeholder="کلمه کلیدی" value={selNode.config.keyword||''} onChange={e=>updCfg(sel,{keyword:e.target.value})}
                  style={{ width:'100%', marginTop:6, padding:'5px 8px', borderRadius:6, border:'1px solid var(--border-soft)', background:'rgba(255,255,255,0.04)', color:'var(--text-1)', fontSize:11, boxSizing:'border-box', fontFamily:'inherit' }} />
              )}
            </div>
          )}

          {/* script config */}
          {selNode.type === 'script' && (
            <div>
              <div style={{ fontSize:10, color:'var(--text-3)', marginBottom:3 }}>اسکریپت</div>
              <select value={selNode.config.script_id||''} onChange={e=>updCfg(sel,{script_id:e.target.value})}
                style={{ width:'100%', padding:'5px 8px', borderRadius:6, border:'1px solid var(--border-soft)', background:'#1a1a2e', color:'var(--text-1)', fontSize:11, fontFamily:'inherit' }}>
                <option value="">انتخاب کن...</option>
                {scripts.map(s => <option key={s.id} value={s.id}>{s.name}</option>)}
              </select>
            </div>
          )}

          {/* delay config */}
          {selNode.type === 'delay' && (
            <div>
              <div style={{ fontSize:10, color:'var(--text-3)', marginBottom:3 }}>ساعت تأخیر</div>
              <input type="number" min="0" value={selNode.config.hours||0} onChange={e=>updCfg(sel,{hours:Number(e.target.value)})}
                style={{ width:'100%', padding:'5px 8px', borderRadius:6, border:'1px solid var(--border-soft)', background:'rgba(255,255,255,0.04)', color:'var(--text-1)', fontSize:11, boxSizing:'border-box', fontFamily:'inherit', direction:'ltr' }} />
            </div>
          )}

          {/* condition config — multi-check */}
          {selNode.type === 'condition' && (
            <div>
              {/* AND / OR */}
              <div style={{ marginBottom:10 }}>
                <div style={{ fontSize:10, color:'var(--text-3)', marginBottom:4 }}>اگر شرط‌ها...</div>
                <div style={{ display:'flex', borderRadius:6, overflow:'hidden', border:'1px solid var(--border-soft)' }}>
                  {[['all','همه برقرار بودن (AND)'],['any','یکی برقرار بود (OR)']].map(([v,l]) => (
                    <button key={v} onClick={()=>updCfg(sel,{match:v})}
                      style={{ flex:1, padding:'5px 2px', border:'none', background:(selNode.config.match||'all')===v?'rgba(251,191,36,0.15)':'transparent', color:(selNode.config.match||'all')===v?'#FBBF24':'var(--text-3)', cursor:'pointer', fontSize:9, fontFamily:'inherit', fontWeight:(selNode.config.match||'all')===v?700:400 }}>
                      {l}
                    </button>
                  ))}
                </div>
              </div>

              {/* لیست شرط‌ها */}
              <div style={{ fontSize:10, color:'var(--text-3)', marginBottom:6, display:'flex', alignItems:'center', justifyContent:'space-between' }}>
                <span style={{ fontWeight:600 }}>شرط‌ها ({getChecks(selNode).length})</span>
                <button onClick={()=>addCheck(sel)}
                  style={{ padding:'2px 8px', borderRadius:5, border:'1px solid rgba(52,211,153,0.4)', background:'rgba(52,211,153,0.08)', color:'#34D399', cursor:'pointer', fontSize:10, fontFamily:'inherit', fontWeight:600 }}>
                  + افزودن
                </button>
              </div>

              {getChecks(selNode).length === 0 && (
                <div style={{ padding:'12px', borderRadius:7, border:'1px dashed rgba(255,255,255,0.1)', textAlign:'center', color:'var(--text-3)', fontSize:10 }}>
                  هنوز شرطی ندارد<br/>
                  <span style={{ color:'#34D399' }}>+ افزودن</span> رو بزن
                </div>
              )}

              {getChecks(selNode).map(ch => renderCheck(ch, sel))}
            </div>
          )}

          {/* action config */}
          {selNode.type === 'action' && (
            <div>
              <div style={{ fontSize:10, color:'var(--text-3)', marginBottom:3 }}>نوع اکشن</div>
              <select value={selNode.config.kind||'send_text'} onChange={e=>updCfg(sel,{kind:e.target.value})}
                style={{ width:'100%', padding:'5px 8px', borderRadius:6, border:'1px solid var(--border-soft)', background:'#1a1a2e', color:'var(--text-1)', fontSize:11, fontFamily:'inherit', marginBottom:6 }}>
                <option value="send_text">ارسال پیام متنی</option>
                <option value="send_link">ارسال لینک</option>
                <option value="change_status">تغییر وضعیت</option>
                <option value="add_tag">افزودن تگ</option>
              </select>
              {(selNode.config.kind === 'send_text' || selNode.config.kind === 'send_link') && (
                <textarea placeholder="متن پیام..." value={selNode.config.text||''} onChange={e=>updCfg(sel,{text:e.target.value})} rows={3}
                  style={{ width:'100%', padding:'5px 8px', borderRadius:6, border:'1px solid var(--border-soft)', background:'rgba(255,255,255,0.04)', color:'var(--text-1)', fontSize:11, resize:'vertical', boxSizing:'border-box', fontFamily:'inherit' }} />
              )}
              {selNode.config.kind === 'send_link' && (
                <input placeholder="https://..." value={selNode.config.url||''} onChange={e=>updCfg(sel,{url:e.target.value})}
                  style={{ width:'100%', marginTop:4, padding:'5px 8px', borderRadius:6, border:'1px solid var(--border-soft)', background:'rgba(255,255,255,0.04)', color:'var(--text-1)', fontSize:11, boxSizing:'border-box', fontFamily:'inherit', direction:'ltr' }} />
              )}
              {(selNode.config.kind === 'change_status' || selNode.config.kind === 'add_tag') && (
                <input placeholder={selNode.config.kind==='change_status'?'مثال: buyer':'نام تگ'} value={selNode.config.value||''} onChange={e=>updCfg(sel,{value:e.target.value})}
                  style={{ width:'100%', padding:'5px 8px', borderRadius:6, border:'1px solid var(--border-soft)', background:'rgba(255,255,255,0.04)', color:'var(--text-1)', fontSize:11, boxSizing:'border-box', fontFamily:'inherit' }} />
              )}
            </div>
          )}
        </div>
      )}

      {/* simulate result overlay */}
      {simResult && (
        <div style={{ position:'absolute', bottom:0, left:120, right: selNode?200:0, background:'rgba(0,0,0,0.92)', padding:'10px 14px', borderTop:'1px solid var(--border-soft)', maxHeight:120, overflowY:'auto' }}>
          <div style={{ display:'flex', justifyContent:'space-between', alignItems:'center', marginBottom:6 }}>
            <span style={{ fontSize:11, color: simResult.ok?'#34D399':'#F87171', fontWeight:600 }}>{simResult.ok ? '✅ مسیر شبیه‌سازی' : '❌ خطا: '+simResult.error}</span>
            <span onClick={()=>setSimResult(null)} style={{ fontSize:11, color:'var(--text-3)', cursor:'pointer' }}>✕</span>
          </div>
          {simResult.ok && simResult.path && (
            <div style={{ display:'flex', gap:4, flexWrap:'wrap' }}>
              {simResult.path.map((step, i) => (
                <span key={i} style={{ padding:'2px 8px', borderRadius:10, background:'rgba(129,140,248,0.15)', color:'#A5B4FC', fontSize:10 }}>
                  {step.label}{step.note?' — '+step.note:''}
                </span>
              ))}
            </div>
          )}
        </div>
      )}
    </div>
  );
};

// ══════════════════════════════════════════════════════════
const CampaignDetail = ({ campaign, onBack, headers }) => {
  const { Button, useToast } = window.SB_UI;
  const { fa } = window.SB_DATA;

  const STATUS_LABEL = { new:'جدید', follow_up:'پیگیری', interested:'علاقه‌مند', scheduled:'زمان‌بندی', buyer:'خریدار', lost:'از دست رفته', expired:'منقضی' };
  const STATUS_COLOR = { new:'#A5B4FC', follow_up:'#818CF8', interested:'#38BDF8', scheduled:'#A78BFA', buyer:'#34D399', lost:'#6B7280', expired:'#6B7280' };
  const TRIGGER_LABELS = { script_drop:'🔴 مکالمه رها شد', no_reply:'⏳ جواب نداد', consultation_done:'✅ مشاوره شد', payment_expired:'⌛ پرداخت منقضی', free_content_sent:'📤 محتوای رایگان ارسال شد', keyword:'🔑 کلیدواژه', manual:'👆 دستی' };
  const ACTION_LABELS = { send_message:'ارسال پیام', send_link:'ارسال لینک', change_status:'تغییر وضعیت', add_tag:'افزودن تگ' };
  const PLAT_ICON    = { bale:'💬', telegram:'✈️', rubika:'🔵', instagram:'📷', eitaa:'🟢', manual:'📋' };

  const [tab,        setTab]        = useState('flow');
  const [loading,    setLoading]    = useState(true);
  const [scripts,    setScripts]    = useState([]);
  const [flowFields, setFlowFields] = useState({});
  const [flowData,   setFlowData]   = useState(campaign.flow_json || null);
  const [stats,      setStats]      = useState(null);
  const toast = useToast();

  // ── Leads tab ───────────────────────────────────────────
  const [leads,       setLeads]       = useState([]);
  const [leadsLoading,setLeadsLoading]= useState(false);
  const [leadsLoaded, setLeadsLoaded] = useState(false);
  const [addLeadOpen, setAddLeadOpen] = useState(false);
  const [allLeads,    setAllLeads]    = useState([]);
  const [leadSearch,  setLeadSearch]  = useState('');
  const [addingLead,  setAddingLead]  = useState(false);


  const [newSeqTrig,  setNewSeqTrig]  = useState('script_drop');
  const [addStepId,   setAddStepId]   = useState(null);
  const [stepDelay,   setStepDelay]   = useState(24);
  const [stepType,    setStepType]    = useState('send_message');
  const [stepText,    setStepText]    = useState('');

  // ── Templates tab ───────────────────────────────────────
  const [templates,     setTemplates]     = useState([]);
  const [tmplLoaded,    setTmplLoaded]    = useState(false);
  const [tmplLoading,   setTmplLoading]   = useState(false);
  const [tmplModal,     setTmplModal]     = useState(null); // null | 'new' | {id,...}
  const [tmplForm,      setTmplForm]      = useState({ name:'', channel:'all', content:'' });
  const [tmplSaving,    setTmplSaving]    = useState(false);

  // ── Tasks tab (صف فالوآپ) ────────────────────────────────
  const [tasks,         setTasks]         = useState([]);
  const [taskCounts,    setTaskCounts]    = useState({});
  const [tasksLoading,  setTasksLoading]  = useState(false);
  const [tasksLoaded,   setTasksLoaded]   = useState(false);
  const [taskFilter,    setTaskFilter]    = useState('pending');

  const loadTemplates = () => {
    if (tmplLoaded) return;
    setTmplLoading(true);
    window.api('/campaigns/templates')
      .then(rows => { if (Array.isArray(rows)) setTemplates(rows); setTmplLoaded(true); })
      .finally(() => setTmplLoading(false));
  };

  const loadTasks = (forceStatus) => {
    const st = forceStatus !== undefined ? forceStatus : taskFilter;
    setTasksLoading(true);
    window.api('/campaigns/campaigns/' + campaign.id + '/tasks?status=' + st + '&limit=100')
      .then(d => {
        if (d && d.success) {
          setTasks(d.items || []);
          setTaskCounts(d.counts || {});
          setTasksLoaded(true);
        }
      }).finally(() => setTasksLoading(false));
  };

  const saveTmpl = () => {
    if (!tmplForm.name.trim() || !tmplForm.content.trim()) return;
    setTmplSaving(true);
    const isNew = tmplModal === 'new';
    const method = isNew ? 'POST' : 'PUT';
    const path = isNew ? '/campaigns/templates' : '/campaigns/templates/' + tmplModal.id;
    window.api(path, { method, body: tmplForm })
      .then(d => {
        if (d && (d.success || d.id)) {
          toast(isNew ? 'قالب ساخته شد ✓' : 'قالب ذخیره شد ✓', 'success');
          setTmplLoaded(false); loadTemplates();
          setTmplModal(null);
        } else toast('خطا در ذخیره', 'error');
      }).finally(() => setTmplSaving(false));
  };

  const deleteTmpl = (id) => {
    if (!confirm('این قالب حذف شود؟')) return;
    window.api('/campaigns/templates/' + id, { method: 'DELETE' })
      .then(d => {
        if (d && d.success) { toast('قالب حذف شد', 'success'); setTemplates(p => p.filter(t => t.id !== id)); }
        else toast('خطا', 'error');
      });
  };

  // ── Live tab ────────────────────────────────────────────
  const [liveData,    setLiveData]    = useState(null);
  const [liveLoading, setLiveLoading] = useState(false);
  const [liveAuto,    setLiveAuto]    = useState(false);

  // ── Lab tab ─────────────────────────────────────────────
  const [labCount,    setLabCount]    = useState(1);
  const [labRunning,  setLabRunning]  = useState(false);
  const [labResult,   setLabResult]   = useState(null);
  const [labExpPath,  setLabExpPath]  = useState(null);

  const loadLive = () => {
    setLiveLoading(true);
    window.api('/campaigns/campaigns/' + campaign.id + '/live')
      .then(d => { if (d && d.ok !== false) setLiveData(d); })
      .finally(() => setLiveLoading(false));
  };

  useEffect(() => {
    if (!liveAuto) return;
    const t = setInterval(loadLive, 15000);
    return () => clearInterval(t);
  }, [liveAuto]);

  const runLab = () => {
    setLabRunning(true); setLabResult(null);
    window.api('/campaigns/campaigns/' + campaign.id + '/lab', {
      method: 'POST', body: { count: labCount },
    }).then(d => { if (d && d.ok !== false) setLabResult(d); })
      .finally(() => setLabRunning(false));
  };

  useEffect(() => {
    setLoading(true);
    Promise.all([
      window.api('/campaigns/campaigns/' + campaign.id + '/stats'),
      window.api('/scripts').catch(() => ({ data: { scripts: [] } })),
      window.api('/campaigns/flow-fields').catch(() => ({})),
    ]).then(([st, sc, ff]) => {
      if (st && !st.error) setStats(st);
      setScripts((sc && sc.data && sc.data.scripts) ? sc.data.scripts : []);
      if (ff && !ff.error) setFlowFields(ff);
    }).finally(() => setLoading(false));
  }, [campaign.id]);

  const loadLeads = () => {
    if (leadsLoaded) return;
    setLeadsLoading(true);
    Promise.all([
      window.api('/campaigns/campaigns/' + campaign.id + '/leads?limit=100'),
      window.api('/leads?limit=300').catch(() => ({})),
    ]).then(([cl, all]) => {
      setLeads(cl && cl.leads ? cl.leads : []);
      const raw = all && all.data && all.data.leads ? all.data.leads : (Array.isArray(all) ? all : []);
      setAllLeads(raw);
      setLeadsLoaded(true);
    }).finally(() => setLeadsLoading(false));
  };



  const addLead = (leadId) => {
    if (addingLead) return;
    setAddingLead(true);
    window.api('/campaigns/leads/' + leadId + '/campaigns', { method: 'POST', body: { campaign_id: campaign.id } })
      .then(d => {
        if (d && d.success) {
          toast(d.already_exists ? 'این لید قبلاً اضافه شده' : 'لید اضافه شد ✓', d.already_exists ? 'info' : 'success');
          if (!d.already_exists) { setLeadsLoaded(false); loadLeads(); }
        } else toast('خطا در اضافه کردن', 'error');
      }).finally(() => setAddingLead(false));
  };

  const removeLead = (clId) => {
    if (!confirm('این لید از کمپین حذف شود؟')) return;
    window.api('/campaigns/campaigns/' + campaign.id + '/leads/' + clId, { method: 'DELETE' })
      .then(d => {
        if (d && d.success) { toast('لید از کمپین حذف شد', 'success'); setLeads(prev => prev.filter(l => l.id !== clId)); }
        else toast('خطا در حذف', 'error');
      });
  };

  const switchTab = (k) => {
    setTab(k);
    if (k === 'leads')     loadLeads();
    if (k === 'live')      loadLive();
    if (k === 'templates') loadTemplates();
    if (k === 'tasks')     loadTasks();
  };

  const filteredLeads = allLeads.filter(l => {
    const q = leadSearch.trim().toLowerCase();
    return !q || (l.full_name||"").toLowerCase().includes(q) || (l.phone||"").includes(q);
  });

  return (
    <div>
      <div className="row between" style={{ marginBottom:16 }}>
        <div className="row gap-12">
          <button onClick={onBack} style={{ padding:"6px 12px", borderRadius:8, border:"1px solid var(--border-soft)", background:"transparent", color:"var(--text-2)", cursor:"pointer", fontSize:12, fontFamily:"inherit" }}>← بازگشت</button>
          <div>
            <div className="semi">{campaign.name}</div>
            {campaign.goal && <div className="text-xs text-3">{campaign.goal}</div>}
          </div>
        </div>
        <span style={{ fontSize:10, padding:"3px 10px", borderRadius:10, background:campaign.is_active?"rgba(52,211,153,0.15)":"rgba(255,255,255,0.06)", color:campaign.is_active?"#34D399":"var(--text-3)" }}>
          {campaign.is_active ? "فعال" : "غیرفعال"}
        </span>
      </div>

      <div style={{ display:"flex", gap:0, borderRadius:8, overflow:"hidden", border:"1px solid var(--border-soft)", marginBottom:16 }}>
        {[['flow','🔀 فلو'],['leads','👥 لیدها'],['templates','📝 قالب‌ها'],['tasks','📋 صف']].map(([k,l]) => (
          <button key={k} onClick={() => switchTab(k)}
            style={{ padding:"6px 14px", border:"none", background:tab===k?"rgba(129,140,248,0.15)":"transparent", color:tab===k?"#818CF8":"var(--text-3)", cursor:"pointer", fontSize:11, fontFamily:"inherit", fontWeight:tab===k?600:400, position:'relative' }}>
            {l}
            {k==='tasks' && (taskCounts.pending||0) > 0 && (
              <span style={{ position:'absolute', top:3, left:3, minWidth:16, height:16, borderRadius:8, background:'#F87171', color:'#fff', fontSize:9, display:'flex', alignItems:'center', justifyContent:'center', padding:'0 3px' }}>
                {fa(taskCounts.pending)}
              </span>
            )}
          </button>
        ))}
      </div>

      <div>
        {tab === 'flow' ? (
          <div style={{ margin:"-16px", height:"calc(100vh - 160px)", minHeight:520 }}>
            {window.FlowBuilder
              ? React.createElement(window.FlowBuilder, { key: campaign.id, initialCampId: campaign.id, embedded: true })
              : <div style={{ padding:40, textAlign:"center", color:"var(--text-3)" }}>در حال بارگذاری...</div>
            }
          </div>

        ) : tab === 'leads' ? (
          <div>
            <div className="row between" style={{ marginBottom:12 }}>
              <div className="text-xs text-3">{leadsLoading ? "..." : fa(leads.length) + " لید"}</div>
              <button onClick={() => setAddLeadOpen(p => !p)}
                style={{ padding:"6px 14px", borderRadius:8, border:"1px solid rgba(99,102,241,0.3)", background:"rgba(99,102,241,0.07)", color:"#818CF8", cursor:"pointer", fontSize:12, fontFamily:"inherit" }}>
                + افزودن لید
              </button>
            </div>
            {addLeadOpen && (
              <div style={{ marginBottom:12, padding:"12px 14px", borderRadius:10, background:"var(--surface)", border:"1px solid var(--border-soft)" }}>
                <input className="input" placeholder="جستجوی لید..." value={leadSearch} onChange={e => setLeadSearch(e.target.value)} style={{ marginBottom:8 }} />
                <div style={{ maxHeight:200, overflowY:"auto", display:"flex", flexDirection:"column", gap:5 }}>
                  {filteredLeads.slice(0,50).map(l => (
                    <div key={l.id} className="row between" style={{ padding:"7px 10px", borderRadius:7, background:"rgba(255,255,255,0.03)", border:"1px solid var(--border-soft)" }}>
                      <div>
                        <span style={{ fontSize:12 }}>{l.full_name||"—"}</span>
                        {l.phone && <span style={{ fontSize:11, color:"var(--text-3)", marginRight:8 }}>{l.phone}</span>}
                      </div>
                      <button onClick={() => addLead(l.id)} disabled={addingLead}
                        style={{ padding:"3px 10px", borderRadius:6, border:"none", background:"#6366F1", color:"#fff", cursor:"pointer", fontSize:11, fontFamily:"inherit" }}>+</button>
                    </div>
                  ))}
                </div>
              </div>
            )}
            {leadsLoading ? (
              <div style={{ textAlign:"center", padding:40, color:"var(--text-3)" }}>در حال بارگذاری...</div>
            ) : leads.length === 0 ? (
              <div style={{ textAlign:"center", padding:50, color:"var(--text-3)" }}>
                <div style={{ fontSize:36, marginBottom:12 }}>👥</div>
                <div>هنوز لیدی اضافه نشده</div>
              </div>
            ) : (
              <div style={{ display:"flex", flexDirection:"column", gap:7 }}>
                {leads.map(cl => (
                  <div key={cl.id} style={{ display:"flex", alignItems:"center", gap:12, padding:"12px 14px", borderRadius:11, background:"var(--surface)", border:"1px solid var(--border-soft)" }}>
                    <div style={{ width:34, height:34, borderRadius:"50%", background:"rgba(129,140,248,0.1)", display:"flex", alignItems:"center", justifyContent:"center", flexShrink:0, fontSize:16 }}>{PLAT_ICON[cl.platform]||"👤"}</div>
                    <div style={{ flex:1, minWidth:0 }}>
                      <div style={{ fontSize:13, fontWeight:600 }}>{cl.full_name||"—"}</div>
                      <div style={{ display:"flex", gap:10, marginTop:3, flexWrap:"wrap" }}>
                        {cl.phone && <span style={{ fontSize:11, color:"var(--text-3)", direction:"ltr" }}>📱 {cl.phone}</span>}
                        <span style={{ fontSize:10, padding:"1px 7px", borderRadius:10, background:(STATUS_COLOR[cl.status]||"#6B7280")+"22", color:STATUS_COLOR[cl.status]||"#6B7280" }}>{STATUS_LABEL[cl.status]||cl.status}</span>
                      </div>
                    </div>
                    <div style={{ display:'flex', alignItems:'center', gap:8 }}>
                      <div style={{ fontSize:10, color:"var(--text-3)" }}>{cl.entry_at?cl.entry_at.slice(0,10):""}</div>
                      <button onClick={() => removeLead(cl.id)} title="حذف از کمپین"
                        style={{ width:26, height:26, borderRadius:6, border:'1px solid rgba(248,113,113,0.2)', background:'transparent', color:'#F87171', cursor:'pointer', display:'flex', alignItems:'center', justifyContent:'center', fontSize:12, flexShrink:0 }}>
                        ×
                      </button>
                    </div>
                  </div>
                ))}
              </div>
            )}
          </div>
      ) : tab === 'templates' ? (
        /* ── قالب‌های پیام ── */
        <div>
          <div className="row between" style={{ marginBottom:12 }}>
            <div className="text-xs text-3">{tmplLoading ? '...' : `${fa(templates.length)} قالب`}</div>
            <button onClick={() => { setTmplForm({ name:'', channel:'all', content:'' }); setTmplModal('new'); }}
              style={{ padding:'6px 14px', borderRadius:8, border:'1px solid rgba(99,102,241,0.3)', background:'rgba(99,102,241,0.07)', color:'#818CF8', cursor:'pointer', fontSize:12, fontFamily:'inherit' }}>
              + قالب جدید
            </button>
          </div>

          {tmplLoading ? (
            <div style={{ textAlign:'center', padding:40, color:'var(--text-3)' }}>در حال بارگذاری...</div>
          ) : templates.length === 0 ? (
            <div style={{ textAlign:'center', padding:50, color:'var(--text-3)' }}>
              <div style={{ fontSize:32, marginBottom:10 }}>📝</div>
              <div>هنوز قالبی نساختی</div>
            </div>
          ) : (
            <div style={{ display:'flex', flexDirection:'column', gap:7 }}>
              {templates.map(t => (
                <div key={t.id} style={{ display:'flex', alignItems:'flex-start', gap:12, padding:'12px 14px', borderRadius:10, background:'var(--surface)', border:'1px solid var(--border-soft)' }}>
                  <div style={{ flex:1, minWidth:0 }}>
                    <div style={{ fontSize:13, fontWeight:600, marginBottom:4 }}>{t.name}</div>
                    <div style={{ fontSize:11, color:'var(--text-3)', whiteSpace:'pre-wrap', lineHeight:1.5,
                      maxHeight:48, overflow:'hidden', textOverflow:'ellipsis' }}>
                      {t.content}
                    </div>
                    <div style={{ marginTop:6, display:'flex', gap:6 }}>
                      <span style={{ fontSize:10, padding:'2px 8px', borderRadius:10, background:'rgba(129,140,248,0.12)', color:'#818CF8' }}>
                        {t.channel === 'all' ? '📡 همه کانال‌ها' : t.channel}
                      </span>
                      {t.category && <span style={{ fontSize:10, padding:'2px 8px', borderRadius:10, background:'rgba(255,255,255,0.05)', color:'var(--text-3)' }}>{t.category}</span>}
                    </div>
                  </div>
                  <div style={{ display:'flex', gap:6, flexShrink:0 }}>
                    <button onClick={() => { setTmplForm({ name:t.name, channel:t.channel||'all', content:t.content }); setTmplModal(t); }}
                      style={{ padding:'5px 10px', borderRadius:7, border:'1px solid rgba(99,102,241,0.25)', background:'transparent', color:'#818CF8', cursor:'pointer', fontSize:11 }}>
                      ✏️
                    </button>
                    <button onClick={() => deleteTmpl(t.id)}
                      style={{ padding:'5px 10px', borderRadius:7, border:'1px solid rgba(248,113,113,0.2)', background:'transparent', color:'#F87171', cursor:'pointer', fontSize:11 }}>
                      ×
                    </button>
                  </div>
                </div>
              ))}
            </div>
          )}

          {/* ─── مودال ساخت/ویرایش قالب ─── */}
          {tmplModal && (
            <div style={{ position:'fixed', inset:0, background:'rgba(0,0,0,0.6)', zIndex:9999, display:'flex', alignItems:'center', justifyContent:'center', padding:16 }}
              onClick={e => e.target === e.currentTarget && setTmplModal(null)}>
              <div style={{ width:'100%', maxWidth:500, background:'#111118', border:'1px solid rgba(99,102,241,0.3)', borderRadius:14, padding:24 }}>
                <div style={{ fontSize:15, fontWeight:700, marginBottom:18 }}>
                  {tmplModal === 'new' ? '➕ قالب جدید' : '✏️ ویرایش قالب'}
                </div>
                <div style={{ display:'flex', flexDirection:'column', gap:12 }}>
                  <div>
                    <div style={{ fontSize:12, color:'var(--text-3)', marginBottom:5 }}>نام قالب</div>
                    <input value={tmplForm.name} onChange={e => setTmplForm(p => ({...p, name:e.target.value}))}
                      placeholder="مثال: پیام خوش‌آمدگویی"
                      style={{ width:'100%', background:'rgba(255,255,255,0.05)', border:'1px solid rgba(255,255,255,0.1)', borderRadius:8, padding:'8px 12px', color:'#e2e8f0', fontSize:13, outline:'none', boxSizing:'border-box' }} />
                  </div>
                  <div>
                    <div style={{ fontSize:12, color:'var(--text-3)', marginBottom:5 }}>کانال</div>
                    <select value={tmplForm.channel} onChange={e => setTmplForm(p => ({...p, channel:e.target.value}))}
                      style={{ width:'100%', background:'rgba(255,255,255,0.05)', border:'1px solid rgba(255,255,255,0.1)', borderRadius:8, padding:'8px 12px', color:'#e2e8f0', fontSize:13, outline:'none' }}>
                      <option value="all">📡 همه کانال‌ها</option>
                      <option value="telegram">✈️ تلگرام</option>
                      <option value="bale">💬 بله</option>
                      <option value="instagram">📸 اینستاگرام</option>
                      <option value="sms">📱 پیامک</option>
                    </select>
                  </div>
                  <div>
                    <div style={{ fontSize:12, color:'var(--text-3)', marginBottom:5 }}>
                      متن پیام
                      <span style={{ marginRight:8, fontSize:10, color:'#818CF8' }}>{'{{name}}'} = نام مشتری</span>
                    </div>
                    <textarea value={tmplForm.content} onChange={e => setTmplForm(p => ({...p, content:e.target.value}))}
                      rows={5} placeholder="سلام {{name}} عزیز..."
                      style={{ width:'100%', background:'rgba(255,255,255,0.05)', border:'1px solid rgba(255,255,255,0.1)', borderRadius:8, padding:'8px 12px', color:'#e2e8f0', fontSize:13, outline:'none', resize:'vertical', boxSizing:'border-box', fontFamily:'inherit' }} />
                  </div>
                </div>
                <div style={{ display:'flex', gap:8, marginTop:16, justifyContent:'flex-end' }}>
                  <button onClick={() => setTmplModal(null)}
                    style={{ padding:'8px 18px', borderRadius:8, border:'1px solid rgba(255,255,255,0.1)', background:'transparent', color:'var(--text-3)', cursor:'pointer', fontSize:12, fontFamily:'inherit' }}>
                    انصراف
                  </button>
                  <button onClick={saveTmpl} disabled={tmplSaving || !tmplForm.name.trim() || !tmplForm.content.trim()}
                    style={{ padding:'8px 18px', borderRadius:8, border:'none', background:tmplSaving?'rgba(99,102,241,0.4)':'#6366F1', color:'#fff', cursor:'pointer', fontSize:12, fontFamily:'inherit', fontWeight:600 }}>
                    {tmplSaving ? '⏳ ذخیره...' : '✓ ذخیره'}
                  </button>
                </div>
              </div>
            </div>
          )}
        </div>

      ) : tab === 'tasks' ? (
        /* ── صف فالوآپ ── */
        <div>
          {/* فیلتر وضعیت + خلاصه */}
          <div style={{ display:'flex', gap:8, marginBottom:12, flexWrap:'wrap', alignItems:'center' }}>
            {[
              { v:'pending',   l:'⏳ در انتظار', c:'#FBBF24' },
              { v:'done',      l:'✅ انجام شده', c:'#34D399' },
              { v:'failed',    l:'❌ خطا',        c:'#F87171' },
              { v:'cancelled', l:'🚫 کنسل',       c:'#6B7280' },
            ].map(f => {
              const cnt = taskCounts[f.v] || 0;
              return (
                <button key={f.v} onClick={() => { setTaskFilter(f.v); setTasksLoaded(false); loadTasks(f.v); }}
                  style={{ padding:'5px 12px', borderRadius:8, border:`1px solid ${taskFilter===f.v ? f.c : 'rgba(255,255,255,0.08)'}`,
                    background: taskFilter===f.v ? f.c+'22' : 'transparent',
                    color: taskFilter===f.v ? f.c : 'var(--text-3)',
                    cursor:'pointer', fontSize:11, fontFamily:'inherit', display:'flex', alignItems:'center', gap:6 }}>
                  {f.l}
                  <span style={{ fontSize:10, fontFamily:'monospace', fontWeight:700 }}>{fa(cnt)}</span>
                </button>
              );
            })}
            <button onClick={() => { setTasksLoaded(false); loadTasks(); }}
              style={{ marginRight:'auto', padding:'5px 10px', borderRadius:7, border:'1px solid rgba(99,102,241,0.25)', background:'transparent', color:'#818CF8', cursor:'pointer', fontSize:11 }}>
              🔄
            </button>
          </div>

          {tasksLoading ? (
            <div style={{ textAlign:'center', padding:40, color:'var(--text-3)' }}>در حال بارگذاری...</div>
          ) : tasks.length === 0 ? (
            <div style={{ textAlign:'center', padding:50, color:'var(--text-3)' }}>
              <div style={{ fontSize:36, marginBottom:10 }}>📋</div>
              <div>هیچ تسکی با این وضعیت یافت نشد</div>
            </div>
          ) : (
            <div style={{ display:'flex', flexDirection:'column', gap:6 }}>
              {tasks.map(t => {
                const nodeId = t.source_ref ? t.source_ref.replace(campaign.id + ':', '') : '—';
                const ST_COLOR = { pending:'#FBBF24', done:'#34D399', failed:'#F87171', cancelled:'#6B7280', sent:'#818CF8' };
                const fmtDate = (d) => {
                  if (!d) return '—';
                  try { return new Date(d).toLocaleDateString('fa-IR', { month:'short', day:'numeric', hour:'2-digit', minute:'2-digit' }); }
                  catch { return d.slice(0,16); }
                };
                return (
                  <div key={t.id} style={{ display:'flex', alignItems:'center', gap:12, padding:'10px 14px', borderRadius:10,
                    background:'var(--surface)', border:'1px solid var(--border-soft)' }}>
                    <span style={{ width:8, height:8, borderRadius:'50%', background:ST_COLOR[t.status]||'#6B7280', flexShrink:0 }} />
                    <div style={{ flex:1, minWidth:0 }}>
                      <div style={{ fontSize:13, fontWeight:600 }}>{t.lead_name || t.lead_id || '—'}</div>
                      <div style={{ display:'flex', gap:10, marginTop:3, flexWrap:'wrap' }}>
                        {t.lead_phone && <span style={{ fontSize:11, color:'var(--text-3)', direction:'ltr' }}>📱 {t.lead_phone}</span>}
                        <span style={{ fontSize:10, color:'#818CF8', background:'rgba(129,140,248,0.1)', padding:'1px 6px', borderRadius:4 }}>گره: {nodeId.slice(0,16)}</span>
                        {t.action_type && <span style={{ fontSize:10, color:'var(--text-3)' }}>{t.action_type}</span>}
                      </div>
                    </div>
                    <div style={{ textAlign:'left', flexShrink:0 }}>
                      <div style={{ fontSize:10, color:'var(--text-3)' }}>{t.status === 'done' ? fmtDate(t.executed_at) : fmtDate(t.due_at)}</div>
                      {t.result && t.status === 'failed' && (
                        <div style={{ fontSize:10, color:'#F87171', marginTop:2, maxWidth:120, overflow:'hidden', textOverflow:'ellipsis', whiteSpace:'nowrap' }} title={t.result}>{t.result}</div>
                      )}
                    </div>
                  </div>
                );
              })}
            </div>
          )}
        </div>

      ) : tab === 'live' ? (
        /* ── Live: نقشه لایو لیدها روی گره‌ها ── */
        <div>
          <div className="row between" style={{ marginBottom:14 }}>
            <div className="text-xs text-3">{liveLoading ? '...' : liveData ? `${fa(liveData.total)} لید — ${fa(liveData.done)} تکمیل شده` : 'بارگذاری نشده'}</div>
            <div className="row gap-8">
              <button onClick={() => setLiveAuto(p => !p)}
                style={{ padding:'5px 12px', borderRadius:7, border:`1px solid ${liveAuto?'#34D399':'rgba(99,102,241,0.3)'}`, background:liveAuto?'rgba(52,211,153,0.1)':'transparent', color:liveAuto?'#34D399':'#818CF8', cursor:'pointer', fontSize:11, fontFamily:'inherit' }}>
                {liveAuto ? '⏸ خودکار' : '▶ خودکار ۱۵ث'}
              </button>
              <button onClick={loadLive}
                style={{ padding:'5px 12px', borderRadius:7, border:'1px solid rgba(99,102,241,0.3)', background:'rgba(99,102,241,0.07)', color:'#818CF8', cursor:'pointer', fontSize:11, fontFamily:'inherit' }}>
                🔄 بروزرسانی
              </button>
            </div>
          </div>

          {!liveData ? (
            <div style={{ textAlign:'center', padding:50, color:'var(--text-3)' }}>
              <div style={{ fontSize:32, marginBottom:10 }}>🟢</div>
              <div className="semi" style={{ marginBottom:6 }}>نمای لایو</div>
              <div className="text-xs text-3">بروزرسانی کن تا ببینی کدام لید روی کدام گره است</div>
              <button onClick={loadLive} style={{ marginTop:14, padding:'8px 20px', borderRadius:8, border:'none', background:'#6366F1', color:'#fff', cursor:'pointer', fontSize:12, fontFamily:'inherit' }}>بارگذاری</button>
            </div>
          ) : (
            <div className="col gap-8">
              {/* خلاصه */}
              <div style={{ display:'grid', gridTemplateColumns:'repeat(3,1fr)', gap:10, marginBottom:8 }}>
                {[
                  { label:'کل لیدها', val: liveData.total, color:'#818CF8' },
                  { label:'تکمیل شده', val: liveData.done,  color:'#34D399' },
                  { label:'در جریان', val: Math.max(0,(liveData.total||0)-(liveData.done||0)), color:'#FBBF24' },
                ].map(s => (
                  <div key={s.label} style={{ padding:'12px 14px', borderRadius:10, background:'var(--surface)', border:'1px solid var(--border-soft)', textAlign:'center' }}>
                    <div className="mono semi" style={{ fontSize:22, color:s.color }}>{fa(s.val||0)}</div>
                    <div className="text-xs text-3" style={{ marginTop:4 }}>{s.label}</div>
                  </div>
                ))}
              </div>

              {/* گره‌ها */}
              {Object.keys(liveData.nodeStats||{}).length === 0 ? (
                <div style={{ textAlign:'center', padding:30, color:'var(--text-3)', fontSize:12 }}>هنوز هیچ لیدی وارد گره‌ها نشده</div>
              ) : (
                <div className="col gap-6">
                  {Object.entries(liveData.nodeStats||{})
                    .sort(([,a],[,b]) => b.count - a.count)
                    .map(([nodeId, stat]) => {
                      const nodeDef = (liveData.nodes||[]).find(n => n.id === nodeId);
                      const label = nodeDef?.label || nodeId;
                      const type  = nodeDef?.type  || '?';
                      const TYPE_COLOR = { trigger:'#FBBF24', action:'#34D399', condition:'#818CF8', delay:'#94A3B8', script:'#C084FC', followup:'#FB923C', end:'#6B7280' };
                      const pct = liveData.total > 0 ? Math.round(stat.count / liveData.total * 100) : 0;
                      return (
                        <div key={nodeId} style={{ padding:'10px 14px', borderRadius:10, background:'var(--surface)', border:'1px solid var(--border-soft)' }}>
                          <div className="row between" style={{ marginBottom:6 }}>
                            <div className="row gap-8">
                              <span style={{ width:8, height:8, borderRadius:'50%', background:TYPE_COLOR[type]||'#6B7280', display:'inline-block', marginTop:3 }} />
                              <span className="semi" style={{ fontSize:12 }}>{label}</span>
                              <span style={{ fontSize:10, color:'var(--text-3)', background:'rgba(255,255,255,0.06)', padding:'1px 6px', borderRadius:4 }}>{type}</span>
                            </div>
                            <span className="mono semi" style={{ fontSize:13, color:TYPE_COLOR[type]||'#818CF8' }}>{fa(stat.count)} نفر — {pct}٪</span>
                          </div>
                          {/* نوار پیشرفت */}
                          <div style={{ height:4, borderRadius:2, background:'rgba(255,255,255,0.06)', overflow:'hidden', marginBottom: stat.leads?.length ? 8 : 0 }}>
                            <div style={{ width:pct+'%', height:'100%', background:TYPE_COLOR[type]||'#6366F1', borderRadius:2, transition:'width .4s' }} />
                          </div>
                          {/* نمونه لیدها */}
                          {(stat.leads||[]).length > 0 && (
                            <div className="row gap-6" style={{ flexWrap:'wrap', marginTop:2 }}>
                              {stat.leads.slice(0,5).map((l,i) => (
                                <span key={i} style={{ fontSize:10, color:'var(--text-3)', background:'rgba(255,255,255,0.04)', padding:'2px 7px', borderRadius:4 }}>
                                  {l.name || l.phone || '?'}
                                </span>
                              ))}
                            </div>
                          )}
                        </div>
                      );
                    })}
                </div>
              )}
            </div>
          )}
        </div>

      ) : tab === 'lab' ? (
        /* ── Lab: آزمایشگاه انبوه پرسونا ── */
        <div>
          {/* کنفیگ */}
          <div style={{ padding:'14px 16px', borderRadius:12, background:'var(--surface)', border:'1px solid var(--border-soft)', marginBottom:14 }}>
            <div className="semi" style={{ marginBottom:12, fontSize:13 }}>🧪 آزمایشگاه — اجرای پرسونا</div>
            <div className="row gap-12" style={{ flexWrap:'wrap' }}>
              <div>
                <div className="text-xs text-3" style={{ marginBottom:4 }}>تعداد دور برای هر پرسونا</div>
                <div className="row gap-6">
                  {[1,5,10,50].map(n => (
                    <button key={n} onClick={() => setLabCount(n)}
                      style={{ padding:'5px 12px', borderRadius:7, border:`1px solid ${labCount===n?'#6366F1':'rgba(255,255,255,0.1)'}`, background:labCount===n?'rgba(99,102,241,0.15)':'transparent', color:labCount===n?'#818CF8':'var(--text-3)', cursor:'pointer', fontSize:12, fontFamily:'inherit' }}>
                      {fa(n)}×
                    </button>
                  ))}
                  <input type="number" value={labCount} onChange={e => setLabCount(Math.max(1,Math.min(200,+e.target.value)))}
                    style={{ width:60, padding:'4px 8px', borderRadius:7, border:'1px solid var(--border-soft)', background:'var(--bg)', color:'var(--text)', fontSize:12, fontFamily:'inherit' }} />
                </div>
              </div>
              <div className="text-xs text-3" style={{ alignSelf:'flex-end', paddingBottom:4 }}>
                ۱۵ پرسونا پیش‌فرض × {fa(labCount)} = <strong style={{ color:'#818CF8' }}>{fa(15 * labCount)} اجرا</strong>
              </div>
            </div>
            <div style={{ marginTop:12 }}>
              <div className="text-xs text-3" style={{ marginBottom:8 }}>پرسوناهای پیش‌فرض:</div>
              <div style={{ display:'flex', flexWrap:'wrap', gap:6 }}>
                {['جدید+تلفن','جدید+بی‌تلفن','پیگیری+تلفن','پیگیری+بی‌تلفن','خریدار','از دست رفته','بودجه بالا','بودجه پایین','دوره رایگان','اعتراض قیمت','اعتراض زمان','امتیاز بالا','امتیاز پایین','گیرکرده ۵۰h','بدون استیت'].map(p => (
                  <span key={p} style={{ fontSize:10, padding:'3px 8px', borderRadius:5, background:'rgba(99,102,241,0.1)', color:'#818CF8', border:'1px solid rgba(99,102,241,0.2)' }}>{p}</span>
                ))}
              </div>
            </div>
            <button onClick={runLab} disabled={labRunning}
              style={{ marginTop:14, padding:'9px 24px', borderRadius:9, border:'none', background:labRunning?'rgba(99,102,241,0.4)':'#6366F1', color:'#fff', cursor:labRunning?'not-allowed':'pointer', fontSize:13, fontFamily:'inherit', fontWeight:600, display:'flex', alignItems:'center', gap:8 }}>
              {labRunning ? '⏳ در حال اجرا...' : '🚀 اجرای آزمایشگاه'}
            </button>
          </div>

          {/* نتایج */}
          {labResult && (() => {
            const { fa: F } = window.SB_DATA;
            const OUTCOME_COLOR = { end:'#34D399', buyer:'#FBBF24', stopped:'#F87171' };
            const OUTCOME_LABEL = { end:'به پایان رسید', buyer:'تبدیل به خریدار', stopped:'متوقف شد' };
            const maxNode = Math.max(...(labResult.node_hits||[]).map(n=>n.count), 1);
            return (
              <div className="col gap-12">
                {/* خلاصه */}
                <div style={{ display:'grid', gridTemplateColumns:'repeat(auto-fit,minmax(110px,1fr))', gap:8 }}>
                  <div style={{ padding:'12px', borderRadius:10, background:'var(--surface)', border:'1px solid var(--border-soft)', textAlign:'center' }}>
                    <div className="mono semi" style={{ fontSize:20, color:'#818CF8' }}>{F(labResult.total_runs)}</div>
                    <div className="text-xs text-3" style={{ marginTop:4 }}>کل اجراها</div>
                  </div>
                  {Object.entries(labResult.by_outcome||{}).map(([k,v]) => (
                    <div key={k} style={{ padding:'12px', borderRadius:10, background:'var(--surface)', border:'1px solid var(--border-soft)', textAlign:'center' }}>
                      <div className="mono semi" style={{ fontSize:20, color:OUTCOME_COLOR[k]||'#94A3B8' }}>{F(v)}</div>
                      <div className="text-xs text-3" style={{ marginTop:4 }}>{OUTCOME_LABEL[k]||k}</div>
                    </div>
                  ))}
                  {labResult.errors_count > 0 && (
                    <div style={{ padding:'12px', borderRadius:10, background:'rgba(248,113,113,0.08)', border:'1px solid rgba(248,113,113,0.2)', textAlign:'center' }}>
                      <div className="mono semi" style={{ fontSize:20, color:'#F87171' }}>{F(labResult.errors_count)}</div>
                      <div className="text-xs text-3" style={{ marginTop:4 }}>خطا</div>
                    </div>
                  )}
                </div>

                {/* توزیع گره‌ها */}
                <div style={{ padding:'14px 16px', borderRadius:12, background:'var(--surface)', border:'1px solid var(--border-soft)' }}>
                  <div className="semi" style={{ marginBottom:10, fontSize:12 }}>🎯 توزیع روی گره‌ها</div>
                  <div className="col gap-5">
                    {(labResult.node_hits||[]).map(n => {
                      const pct = Math.round(n.count / labResult.total_runs * 100);
                      return (
                        <div key={n.name}>
                          <div className="row between" style={{ marginBottom:2 }}>
                            <span style={{ fontSize:11 }}>{n.name}</span>
                            <span className="mono" style={{ fontSize:11, color:'#818CF8' }}>{F(n.count)} ({pct}٪)</span>
                          </div>
                          <div style={{ height:5, borderRadius:3, background:'rgba(255,255,255,0.06)' }}>
                            <div style={{ width:(n.count/maxNode*100)+'%', height:'100%', background:'#6366F1', borderRadius:3 }} />
                          </div>
                        </div>
                      );
                    })}
                  </div>
                </div>

                {/* مسیرهای برتر */}
                <div style={{ padding:'14px 16px', borderRadius:12, background:'var(--surface)', border:'1px solid var(--border-soft)' }}>
                  <div className="semi" style={{ marginBottom:10, fontSize:12 }}>🛤 مسیرهای برتر</div>
                  <div className="col gap-5">
                    {(labResult.top_paths||[]).slice(0,10).map((p,i) => {
                      const isOpen = labExpPath === i;
                      const pct = Math.round(p.count / labResult.total_runs * 100);
                      return (
                        <div key={i} style={{ borderRadius:9, border:'1px solid var(--border-soft)', overflow:'hidden' }}>
                          <div onClick={() => setLabExpPath(isOpen ? null : i)}
                            className="row between" style={{ padding:'8px 12px', cursor:'pointer', background:isOpen?'rgba(99,102,241,0.08)':'transparent' }}>
                            <div className="row gap-8">
                              <span className="mono" style={{ fontSize:10, color:'#818CF8', minWidth:22 }}>#{i+1}</span>
                              <span style={{ fontSize:11, color:isOpen?'#fff':'var(--text-2)' }}>
                                {p.sig.length > 60 ? p.sig.slice(0,60)+'…' : p.sig}
                              </span>
                            </div>
                            <div className="row gap-8">
                              <span className="mono semi" style={{ fontSize:11, color:'#34D399' }}>{F(p.count)} ({pct}٪)</span>
                              <span style={{ fontSize:10, color:'var(--text-3)' }}>{isOpen?'▲':'▼'}</span>
                            </div>
                          </div>
                          {isOpen && (
                            <div style={{ padding:'8px 12px', borderTop:'1px solid var(--border-soft)', background:'rgba(0,0,0,0.2)' }}>
                              <div className="text-xs text-3" style={{ marginBottom:6 }}>گام‌ها:</div>
                              <div style={{ display:'flex', flexWrap:'wrap', gap:4 }}>
                                {(p.path||[]).map((step,j) => (
                                  <span key={j} style={{ fontSize:10, padding:'2px 8px', borderRadius:4, background:'rgba(99,102,241,0.12)', color:'#A5B4FC', border:'1px solid rgba(99,102,241,0.2)' }}>
                                    {j+1}. {step.label||step.type} {step.note ? `(${step.note.slice(0,30)})` : ''}
                                  </span>
                                ))}
                              </div>
                              <div className="text-xs text-3" style={{ marginTop:6 }}>مثال: {p.example}</div>
                            </div>
                          )}
                        </div>
                      );
                    })}
                  </div>
                </div>

                {/* خطاها */}
                {labResult.errors?.length > 0 && (
                  <div style={{ padding:'12px 14px', borderRadius:10, background:'rgba(248,113,113,0.06)', border:'1px solid rgba(248,113,113,0.15)' }}>
                    <div className="semi" style={{ marginBottom:8, fontSize:12, color:'#F87171' }}>❌ خطاها</div>
                    {labResult.errors.slice(0,5).map((e,i) => (
                      <div key={i} style={{ fontSize:11, color:'var(--text-3)', marginBottom:3 }}>{e.profile}: {e.error}</div>
                    ))}
                  </div>
                )}
              </div>
            );
          })()}
        </div>

      ) : /* stats */ (
        <div className="col gap-16">
          {stats && (stats.statusBreakdown||[]).length > 0 && (
            <div style={{ display:'grid', gridTemplateColumns:'repeat(auto-fit, minmax(100px, 1fr))', gap:10 }}>
              {stats.statusBreakdown.map(s => (
                <div key={s.status} style={{ padding:'12px 14px', borderRadius:10, background:'var(--surface)', border:'1px solid var(--border-soft)', textAlign:'center' }}>
                  <div className="mono semi" style={{ fontSize:20, color:STATUS_COLOR[s.status]||'#6B7280' }}>{fa(s.cnt)}</div>
                  <div className="text-xs text-3 mt-4">{STATUS_LABEL[s.status]||s.status}</div>
                </div>
              ))}
            </div>
          )}
          {stats && (stats.followupStats||[]).length > 0 && (
            <div>
              <div style={{ fontSize:12, color:'var(--text-3)', fontWeight:600, marginBottom:8 }}>📤 وضعیت ارسال پیام‌ها</div>
              <div style={{ display:'flex', gap:8, flexWrap:'wrap' }}>
                {stats.followupStats.map(s => (
                  <div key={s.status} style={{ padding:'10px 16px', borderRadius:10, background:'var(--surface)', border:'1px solid var(--border-soft)', textAlign:'center', minWidth:90 }}>
                    <div className="mono semi" style={{ fontSize:18, color:'#818CF8' }}>{fa(s.cnt)}</div>
                    <div style={{ fontSize:11, color:'var(--text-3)', marginTop:3 }}>{s.status}</div>
                  </div>
                ))}
              </div>
            </div>
          )}
          {stats && stats.responseRate && stats.responseRate.total_sent > 0 && (
            <div style={{ padding:'12px 16px', borderRadius:10, background:'var(--surface)', border:'1px solid var(--border-soft)' }}>
              <div style={{ fontSize:12, color:'var(--text-3)', marginBottom:6 }}>📊 نرخ پاسخ</div>
              <div className="mono semi" style={{ fontSize:24, color:'#34D399' }}>
                {fa(Math.round(stats.responseRate.responded / stats.responseRate.total_sent * 100))}٪
              </div>
              <div style={{ fontSize:11, color:'var(--text-3)', marginTop:2 }}>
                {fa(stats.responseRate.responded)} از {fa(stats.responseRate.total_sent)} پیام پاسخ گرفت
              </div>
            </div>
          )}
          {(!stats || (!(stats.statusBreakdown||[]).length && !(stats.followupStats||[]).length)) && (
            <div style={{ padding:40, textAlign:'center', color:'var(--text-3)' }}>
              <div style={{ fontSize:36, marginBottom:12 }}>📊</div>
              هنوز آماری ثبت نشده
            </div>
          )}
        </div>
      )}
      </div>
    </div>
  );
};

// ══════════════════════════════════════════════════════════
// ── قیف اسکریپت — دسته‌بندی بر اساس استیت‌های بات ──────────
// ══════════════════════════════════════════════════════════
const ScriptSegments = ({ headers, onBack }) => {
  const { fa } = window.SB_DATA;
  const [data,       setData]       = useState(null);
  const [loading,    setLoading]    = useState(true);
  const [err,        setErr]        = useState(null);
  const [activeScript, setActiveScript] = useState(0); // index
  const [drill,      setDrill]      = useState(null);  // { title, leads }

  useEffect(() => {
    window.api('/campaigns/script-segments')
      .then(d => {
        if (d.error || d.message) { setErr(d.error || d.message); return; }
        if (!d.scripts) { setErr('پاسخ نامعتبر'); return; }
        setData(d);
      })
      .catch(e => setErr(e.message))
      .finally(() => setLoading(false));
  }, []);

  const ago = (d) => {
    if (!d) return null;
    const diff = Math.floor((Date.now() - new Date(d)) / 86400000);
    if (diff === 0) return 'امروز';
    if (diff === 1) return 'دیروز';
    return `${fa(diff)} روز پیش`;
  };

  const statusLabel = { new:'جدید', follow_up:'پیگیری', buyer:'خریدار', lost:'از دست رفته', expired:'منقضی' };
  const statusColor = { new:'#A5B4FC', follow_up:'#FBBF24', buyer:'#34D399', lost:'#F87171', expired:'#6B7280' };
  const platIcon    = { bale:'💬', telegram:'✈️', rubika:'🔵', instagram:'📷', eitaa:'🟢', manual:'📋' };

  // ── Drill-down ──────────────────────────────────────────
  if (drill) {
    return (
      <div>
        <div style={{ display:'flex', alignItems:'center', gap:10, marginBottom:20 }}>
          <button onClick={() => setDrill(null)} style={{ padding:'7px 14px', borderRadius:8, border:'1px solid var(--border-soft)', background:'transparent', color:'var(--text-2)', cursor:'pointer', fontSize:12, fontFamily:'inherit' }}>← بازگشت</button>
          <div>
            <span className="semi" style={{ fontSize:14 }}>{drill.stateIcon} {drill.title}</span>
            {drill.desc && <div className="text-xs text-3 mt-2">{drill.desc}</div>}
          </div>
          <span className="mono semi" style={{ fontSize:16, color: drill.color || '#818CF8', marginRight:'auto' }}>{fa(drill.leads.length)} نفر</span>
        </div>
        {drill.leads.length === 0 ? (
          <div style={{ textAlign:'center', padding:60, color:'var(--text-3)' }}>
            <div style={{ fontSize:36, marginBottom:12 }}>🔍</div>
            <div>لیدی در این مرحله نیست</div>
          </div>
        ) : (
          <div style={{ display:'flex', flexDirection:'column', gap:7 }}>
            {drill.leads.map((l, i) => (
              <div key={l.id||i} style={{ display:'flex', alignItems:'flex-start', gap:12, padding:'12px 14px', borderRadius:11, background:'var(--surface)', border:'1px solid var(--border-soft)' }}>
                <div style={{ width:22, textAlign:'center', fontSize:11, color:'var(--text-3)', flexShrink:0, paddingTop:2 }}>{fa(i+1)}</div>
                <div style={{ width:34, height:34, borderRadius:'50%', background:`${drill.color||'#818CF8'}20`, display:'flex', alignItems:'center', justifyContent:'center', flexShrink:0, fontSize:16 }}>
                  {platIcon[l.platform]||'👤'}
                </div>
                <div style={{ flex:1, minWidth:0 }}>
                  <div style={{ display:'flex', alignItems:'center', gap:8, flexWrap:'wrap' }}>
                    <span style={{ fontSize:13, fontWeight:600 }}>{l.full_name||'—'}</span>
                    {l.status && <span style={{ padding:'1px 7px', borderRadius:10, background:`${statusColor[l.status]||'#818CF8'}22`, color:statusColor[l.status]||'#818CF8', fontSize:10 }}>{statusLabel[l.status]||l.status}</span>}
                  </div>
                  <div style={{ display:'flex', gap:10, marginTop:4, flexWrap:'wrap' }}>
                    {l.phone && <span style={{ fontSize:11, color:'var(--text-2)', direction:'ltr' }}>📱 {l.phone}</span>}
                    {l.last_user_msg && <span style={{ fontSize:11, color:'var(--text-3)' }} title={l.last_user_msg}>💬 {l.last_user_msg.slice(0,30)}{l.last_user_msg.length>30?'...':''}</span>}
                  </div>
                  {l.last_bot_msg && <div style={{ fontSize:10, color:'var(--text-3)', marginTop:3 }} title={l.last_bot_msg}>🤖 {l.last_bot_msg.slice(0,50)}{l.last_bot_msg.length>50?'...':''}</div>}
                </div>
                <div style={{ textAlign:'right', flexShrink:0 }}>
                  {l.stuck_hours != null && <div style={{ fontSize:10, color:'#F87171', fontWeight:600 }}>⏳ {fa(Math.round(l.stuck_hours))} ساعت</div>}
                  {l.last_msg_at  && <div style={{ fontSize:10, color:'var(--text-3)', marginTop:2 }}>{ago(l.last_msg_at)}</div>}
                  {l.created_at   && !l.last_msg_at && <div style={{ fontSize:10, color:'var(--text-3)' }}>{ago(l.created_at)}</div>}
                </div>
              </div>
            ))}
          </div>
        )}
      </div>
    );
  }

  if (loading) return <div style={{ textAlign:'center', padding:80, color:'var(--text-3)' }}><div style={{ fontSize:32, marginBottom:12 }}>🔀</div>در حال بارگذاری...</div>;

  if (err || !data || !data.scripts || !data.scripts.length) return (
    <div style={{ padding:30 }}>
      <button onClick={onBack} style={{ padding:'7px 14px', borderRadius:8, border:'1px solid var(--border-soft)', background:'transparent', color:'var(--text-2)', cursor:'pointer', fontSize:12, fontFamily:'inherit', marginBottom:20 }}>← بازگشت</button>
      <div style={{ padding:'16px', borderRadius:10, background:'rgba(248,113,113,0.06)', border:'1px solid rgba(248,113,113,0.2)', color:'#F87171', fontSize:12 }}>
        {err ? ('⚠️ خطا: ' + err) : 'اسکریپتی پیدا نشد یا هنوز لود نشده'}
      </div>
      {err && err.indexOf('Unauthorized') !== -1 && (
        <div style={{ marginTop:12, fontSize:11, color:'var(--text-3)' }}>
          💡 توکن منقضی شده — از صفحه logout کن و دوباره login کن.
        </div>
      )}
    </div>
  );

  const scripts = data.scripts;
  const cur     = scripts[activeScript] || scripts[0];
  const maxCount = Math.max(...(cur.states.map(s => s.count)), 1, cur.no_state_count || 0);

  return (
    <div>
      {/* هدر */}
      <div className="row between" style={{ marginBottom:16 }}>
        <div>
          <div className="semi" style={{ fontSize:15 }}>🔀 قیف اسکریپت</div>
          <div className="text-xs text-3 mt-2">هر مرحله اسکریپت = یه دسته از لیدها</div>
        </div>
        <button onClick={onBack} style={{ padding:'6px 12px', borderRadius:8, border:'1px solid var(--border-soft)', background:'transparent', color:'var(--text-2)', cursor:'pointer', fontSize:12, fontFamily:'inherit' }}>← بازگشت</button>
      </div>

      {/* انتخاب اسکریپت */}
      {scripts.length > 1 && (
        <div style={{ display:'flex', gap:8, marginBottom:16, flexWrap:'wrap' }}>
          {scripts.map((s, i) => (
            <button key={s.script_id} onClick={() => setActiveScript(i)}
              style={{ padding:'7px 16px', borderRadius:20, border:'none', cursor:'pointer', fontSize:12, fontFamily:'inherit', fontWeight:600,
                background: i===activeScript ? `rgba(52,211,153,0.15)` : 'var(--surface)',
                color:      i===activeScript ? '#34D399' : 'var(--text-3)',
                border:     i===activeScript ? '1px solid rgba(52,211,153,0.4)' : '1px solid var(--border-soft)',
              }}>
              {s.is_active ? '🟢' : '⚫'} {s.script_name}
              <span className="mono" style={{ marginRight:6, fontSize:11 }}>({fa(s.total_assigned)})</span>
            </button>
          ))}
        </div>
      )}

      {/* کارت خلاصه اسکریپت */}
      <div style={{ display:'grid', gridTemplateColumns:'repeat(3,1fr)', gap:8, marginBottom:16 }}>
        {[
          { label:'کل لیدهای assign شده', val: cur.total_assigned, color:'#818CF8' },
          { label:'در حال عبور از مراحل', val: cur.states.reduce((s,x)=>s+x.count,0), color:'#34D399' },
          { label:'گیر کردن (stuck)', val: cur.stuck_count, color:'#F87171' },
        ].map(it => (
          <div key={it.label} style={{ padding:'12px', borderRadius:10, background:'var(--surface)', border:'1px solid var(--border-soft)', textAlign:'center' }}>
            <div className="mono semi" style={{ fontSize:22, color:it.color }}>{fa(it.val)}</div>
            <div style={{ fontSize:10, color:'var(--text-3)', marginTop:3 }}>{it.label}</div>
          </div>
        ))}
      </div>

      {/* ── قیف مراحل ── */}
      <div style={{ padding:'16px', borderRadius:12, background:'var(--surface)', border:'1px solid var(--border-soft)', marginBottom:12 }}>
        <div className="text-xs text-3" style={{ marginBottom:14, fontWeight:600 }}>مسیر مشتری در اسکریپت «{cur.script_name}»</div>

        {/* تازه‌واردها — هنوز مرحله ندارن */}
        {cur.no_state_count > 0 && (
          <div
            onClick={() => setDrill({ title:'تازه assign شده — هنوز شروع نکرده', desc:'به اسکریپت وصل شدن ولی هنوز مرحله‌ای طی نکردن', color:'#94A3B8', stateIcon:'🆕', leads: cur.no_state_leads })}
            style={{ display:'flex', alignItems:'center', gap:12, padding:'10px 14px', borderRadius:10, marginBottom:10, background:'rgba(148,163,184,0.06)', border:'1px dashed rgba(148,163,184,0.3)', cursor:'pointer', transition:'all .15s' }}
            onMouseEnter={e=>e.currentTarget.style.background='rgba(148,163,184,0.12)'}
            onMouseLeave={e=>e.currentTarget.style.background='rgba(148,163,184,0.06)'}
          >
            <span style={{ fontSize:20 }}>🆕</span>
            <div style={{ flex:1 }}>
              <div style={{ fontSize:12, fontWeight:600, color:'var(--text-2)' }}>تازه assign شده — هنوز شروع نکرده</div>
            </div>
            <div className="mono semi" style={{ fontSize:20, color:'#94A3B8' }}>{fa(cur.no_state_count)}</div>
          </div>
        )}

        {/* مراحل اسکریپت */}
        <div style={{ display:'flex', flexDirection:'column', gap:6 }}>
          {cur.states.map((st, idx) => {
            const pct = maxCount > 0 ? Math.min(100, Math.round(st.count * 100 / maxCount)) : 0;
            const isLast = idx === cur.states.length - 1;
            return (
              <div key={st.id}>
                <div
                  onClick={() => setDrill({ title: st.name, desc: st.description || st.exit_condition, color: st.color, stateIcon: `${fa(st.order_num)}.`, leads: st.leads })}
                  style={{ display:'flex', alignItems:'center', gap:12, padding:'12px 14px', borderRadius:10, background:`${st.color}0C`, border:`1px solid ${st.color}30`, cursor:'pointer', transition:'all .15s' }}
                  onMouseEnter={e=>{ e.currentTarget.style.background=`${st.color}1A`; e.currentTarget.style.borderColor=`${st.color}60`; }}
                  onMouseLeave={e=>{ e.currentTarget.style.background=`${st.color}0C`; e.currentTarget.style.borderColor=`${st.color}30`; }}
                >
                  {/* شماره مرحله */}
                  <div style={{ width:28, height:28, borderRadius:'50%', background:`${st.color}25`, display:'flex', alignItems:'center', justifyContent:'center', flexShrink:0, fontSize:12, fontWeight:700, color:st.color }}>
                    {fa(st.order_num)}
                  </div>

                  {/* اطلاعات */}
                  <div style={{ flex:1, minWidth:0 }}>
                    <div style={{ fontSize:12, fontWeight:600, color:'var(--text-2)' }}>{st.name}</div>
                    {st.description && <div style={{ fontSize:10, color:'var(--text-3)', marginTop:1 }}>{st.description}</div>}
                    {/* bar */}
                    <div style={{ height:4, borderRadius:4, background:'rgba(255,255,255,0.05)', marginTop:5 }}>
                      <div style={{ height:'100%', borderRadius:4, background:st.color, width:`${Math.max(st.count?4:0,pct)}%`, transition:'width .4s' }} />
                    </div>
                    {st.exit_condition && <div style={{ fontSize:10, color:'var(--text-3)', marginTop:3 }}>خروج: {st.exit_condition}</div>}
                  </div>

                  {/* تعداد */}
                  <div style={{ textAlign:'center', flexShrink:0 }}>
                    <div className="mono semi" style={{ fontSize:20, color: st.count ? st.color : 'var(--text-3)' }}>{fa(st.count)}</div>
                    {st.count > 0 && <div style={{ fontSize:10, color:st.color }}>مشاهده ←</div>}
                  </div>
                </div>

                {/* فلش بین مراحل */}
                {!isLast && (
                  <div style={{ textAlign:'center', color:'var(--text-3)', fontSize:14, margin:'2px 0', lineHeight:1 }}>↓</div>
                )}
              </div>
            );
          })}
        </div>

        {/* stuck */}
        {cur.stuck_count > 0 && (
          <div
            onClick={() => setDrill({ title:'گیر کرده — نیاز به بررسی', desc:'مدت زیادیه پاسخ نداده یا مکالمه متوقف شده', color:'#F87171', stateIcon:'⏳', leads: cur.stuck_leads })}
            style={{ display:'flex', alignItems:'center', gap:12, padding:'10px 14px', borderRadius:10, marginTop:10, background:'rgba(248,113,113,0.06)', border:'1px solid rgba(248,113,113,0.2)', cursor:'pointer', transition:'all .15s' }}
            onMouseEnter={e=>e.currentTarget.style.background='rgba(248,113,113,0.12)'}
            onMouseLeave={e=>e.currentTarget.style.background='rgba(248,113,113,0.06)'}
          >
            <span style={{ fontSize:20 }}>⏳</span>
            <div style={{ flex:1 }}>
              <div style={{ fontSize:12, fontWeight:600, color:'#F87171' }}>گیر کرده — پاسخ نمیده</div>
              <div style={{ fontSize:10, color:'var(--text-3)', marginTop:1 }}>مکالمه متوقف شده</div>
            </div>
            <div className="mono semi" style={{ fontSize:20, color:'#F87171' }}>{fa(cur.stuck_count)}</div>
          </div>
        )}
      </div>

      {/* راهنما */}
      <div style={{ padding:'10px 14px', borderRadius:8, background:'rgba(52,211,153,0.04)', border:'1px solid rgba(52,211,153,0.15)', fontSize:11, color:'var(--text-3)', lineHeight:1.7 }}>
        💡 هر مرحله = یه استیت از اسکریپت بات — لیدها با جواب دادن از مرحله‌ای به مرحله بعد میرن.
        کلیک روی هر مرحله برای دیدن اسامی.
        {cur.total_assigned === 0 && ' · هنوز لیدی به این اسکریپت assign نشده.'}
      </div>
    </div>
  );
};

// ══════════════════════════════════════════════════════════
// ── پروفایل جمعیتی لیدها ─────────────────────────────────
// ══════════════════════════════════════════════════════════
const LeadProfile = ({ headers, onBack }) => {
  const { fa } = window.SB_DATA;
  const [data,     setData]     = useState(null);
  const [loading,  setLoading]  = useState(true);
  const [drillSec, setDrillSec] = useState(null); // 'no_phone' | 'with_phone' | product key
  const [drillList, setDrillList] = useState([]);
  const [drillTitle, setDrillTitle] = useState('');

  useEffect(() => {
    window.api('/campaigns/profile')
      .then(d => { if (!d.error && !d.message) setData(d); })
      .finally(() => setLoading(false));
  }, []);

  const openDrill = (title, list) => { setDrillTitle(title); setDrillList(list || []); setDrillSec(title); };

  const productNames = { sim_ins: '📋 بیمه سیم‌کارت', sim_loan: '💳 وام سیم‌کارت', '—': '❓ بدون محصول ثبت‌شده' };
  const statusLabel  = { new:'جدید', follow_up:'پیگیری', buyer:'خریدار', lost:'از دست رفته', expired:'منقضی' };
  const statusColor  = { new:'#A5B4FC', follow_up:'#FBBF24', buyer:'#34D399', lost:'#F87171', expired:'#6B7280' };
  const platIcon     = { bale:'💬', telegram:'✈️', rubika:'🔵', instagram:'📷', eitaa:'🟢', manual:'📋', '—':'❓', 'نامشخص':'❓' };
  const platLabel    = { bale:'بله', telegram:'تلگرام', rubika:'روبیکا', instagram:'اینستاگرام', eitaa:'ایتا', manual:'دستی (وارد شده)' };
  const outcomeName  = { answered:'✅ جواب داد', no_answer:'📵 جواب نداد', follow_up:'🔄 پیگیری', not_interested:'🙅 علاقه نداشت', sold:'💰 خرید کرد' };
  const outcomeColor = { answered:'#34D399', no_answer:'#FB923C', follow_up:'#FBBF24', not_interested:'#94A3B8', sold:'#10B981' };

  // ── Drill-down ──────────────────────────────────────────
  if (drillSec && drillList.length > 0) {
    return (
      <div>
        <div style={{ display:'flex', alignItems:'center', gap:10, marginBottom:20 }}>
          <button onClick={() => setDrillSec(null)} style={{ padding:'7px 14px', borderRadius:8, border:'1px solid var(--border-soft)', background:'transparent', color:'var(--text-2)', cursor:'pointer', fontSize:12, fontFamily:'inherit' }}>
            ← بازگشت
          </button>
          <span className="semi" style={{ fontSize:14 }}>{drillTitle}</span>
          <span className="text-xs text-3">({fa(drillList.length)} نفر)</span>
        </div>
        <div style={{ display:'flex', flexDirection:'column', gap:7 }}>
          {drillList.map((l, i) => (
            <div key={l.id||i} style={{ display:'flex', alignItems:'center', gap:12, padding:'11px 14px', borderRadius:11, background:'var(--surface)', border:'1px solid var(--border-soft)' }}>
              <div style={{ width:22, textAlign:'center', fontSize:11, color:'var(--text-3)', flexShrink:0 }}>{fa(i+1)}</div>
              <div style={{ flex:1, minWidth:0 }}>
                <div style={{ fontSize:13, fontWeight:600 }}>{l.full_name || '—'}</div>
                <div style={{ display:'flex', gap:10, marginTop:3, flexWrap:'wrap' }}>
                  {l.phone && <span style={{ fontSize:11, color:'var(--text-2)', direction:'ltr' }}>📱 {l.phone}</span>}
                  {l.platform && <span style={{ fontSize:11, color:'var(--text-3)' }}>{platIcon[l.platform]||'👤'} {platLabel[l.platform]||l.platform}</span>}
                  {l.status && <span style={{ padding:'1px 7px', borderRadius:10, background:`${statusColor[l.status]||'#6B7280'}20`, color:statusColor[l.status]||'#6B7280', fontSize:10 }}>{statusLabel[l.status]||l.status}</span>}
                </div>
              </div>
              {l.sale_amount > 0 && <div style={{ fontSize:12, color:'#34D399', fontWeight:600, flexShrink:0 }}>💰 {fa(Math.round(l.sale_amount/1000000))}M</div>}
              {l.free_courses_count > 0 && <div style={{ fontSize:11, color:'#60A5FA', flexShrink:0 }}>🎓 {fa(l.free_courses_count)}</div>}
            </div>
          ))}
        </div>
      </div>
    );
  }

  if (loading) return <div style={{ textAlign:'center', padding:80, color:'var(--text-3)' }}><div style={{ fontSize:32, marginBottom:12 }}>👥</div>در حال تحلیل لیدها...</div>;
  if (!data)   return <div style={{ padding:40, color:'var(--text-3)' }}>خطا در بارگذاری</div>;

  const { total, phone, products, sale_amounts, consultation, free_courses, statuses, platforms, call_outcomes, answered_leads, never_called, tags, monthly_entry=[], call_freq={}, opportunities=[], lead_types=[] } = data;

  // تابع progress bar
  const Bar = ({ value, max, color='#818CF8' }) => {
    const pct = max > 0 ? Math.min(100, Math.round(value*100/max)) : 0;
    return (
      <div style={{ height:5, borderRadius:5, background:'rgba(255,255,255,0.06)', marginTop:6 }}>
        <div style={{ height:'100%', borderRadius:5, background:color, width:`${Math.max(2,pct)}%`, transition:'width .4s' }} />
      </div>
    );
  };

  // تابع section card
  const SCard = ({ title, children }) => (
    <div style={{ padding:'14px 16px', borderRadius:12, background:'var(--surface)', border:'1px solid var(--border-soft)', marginBottom:12 }}>
      <div className="text-xs text-3" style={{ fontWeight:600, marginBottom:12 }}>{title}</div>
      {children}
    </div>
  );

  const totalCalls = call_outcomes.reduce((s,c) => s+(c.n||0), 0);

  return (
    <div>
      {/* هدر */}
      <div className="row between" style={{ marginBottom:16 }}>
        <div>
          <div className="semi" style={{ fontSize:15 }}>👥 پروفایل لیدها</div>
          <div className="text-xs text-3 mt-2">آنالیز {fa(total)} لید — کلیک روی هر بخش برای دیدن نام‌ها</div>
        </div>
        <button onClick={onBack} style={{ padding:'6px 12px', borderRadius:8, border:'1px solid var(--border-soft)', background:'transparent', color:'var(--text-2)', cursor:'pointer', fontSize:12, fontFamily:'inherit' }}>← بازگشت</button>
      </div>

      {/* ── ۱) شماره تلفن ── */}
      <SCard title="📱 شماره تلفن — کیا دادن، کیا ندادن؟">
        <div style={{ display:'grid', gridTemplateColumns:'1fr 1fr', gap:10 }}>
          <div
            onClick={() => openDrill('با شماره تلفن', phone.with_phone_leads)}
            style={{ padding:'14px', borderRadius:10, background:'rgba(129,140,248,0.08)', border:'1px solid rgba(129,140,248,0.2)', cursor:'pointer', textAlign:'center', transition:'all .15s' }}
            onMouseEnter={e=>e.currentTarget.style.background='rgba(129,140,248,0.15)'}
            onMouseLeave={e=>e.currentTarget.style.background='rgba(129,140,248,0.08)'}
          >
            <div className="mono semi" style={{ fontSize:28, color:'#818CF8' }}>{fa(phone.with_phone)}</div>
            <div style={{ fontSize:11, color:'var(--text-3)', marginTop:4 }}>شماره دادن</div>
            <div style={{ fontSize:10, color:'#818CF8', marginTop:2 }}>{fa(Math.round(phone.with_phone*100/total))}٪ · مشاهده ←</div>
          </div>
          <div
            onClick={() => openDrill('بدون شماره تلفن', phone.no_phone_leads)}
            style={{ padding:'14px', borderRadius:10, background:'rgba(248,113,113,0.08)', border:'1px solid rgba(248,113,113,0.2)', cursor:'pointer', textAlign:'center', transition:'all .15s' }}
            onMouseEnter={e=>e.currentTarget.style.background='rgba(248,113,113,0.15)'}
            onMouseLeave={e=>e.currentTarget.style.background='rgba(248,113,113,0.08)'}
          >
            <div className="mono semi" style={{ fontSize:28, color:'#F87171' }}>{fa(phone.without_phone)}</div>
            <div style={{ fontSize:11, color:'var(--text-3)', marginTop:4 }}>شماره ندادن</div>
            <div style={{ fontSize:10, color:'#F87171', marginTop:2 }}>{fa(Math.round(phone.without_phone*100/total))}٪ · مشاهده ←</div>
          </div>
        </div>
      </SCard>

      {/* ── ۲) دوره‌ها / محصولات خریداری ── */}
      <SCard title="🛒 دوره/محصول خریداری شده — چه دوره‌ای خریدن؟">
        {products.length === 0 ? (
          <div style={{ fontSize:12, color:'var(--text-3)', textAlign:'center', padding:20 }}>داده‌ای ثبت نشده</div>
        ) : (
          <div style={{ display:'flex', flexDirection:'column', gap:8 }}>
            {products.map(p => (
              <div
                key={p.name}
                onClick={() => openDrill(productNames[p.name] || p.name, p.leads)}
                style={{ display:'flex', alignItems:'center', gap:12, padding:'12px 14px', borderRadius:10, background:'rgba(52,211,153,0.05)', border:'1px solid rgba(52,211,153,0.15)', cursor:'pointer', transition:'all .15s' }}
                onMouseEnter={e=>e.currentTarget.style.background='rgba(52,211,153,0.12)'}
                onMouseLeave={e=>e.currentTarget.style.background='rgba(52,211,153,0.05)'}
              >
                <div style={{ flex:1, minWidth:0 }}>
                  <div style={{ fontSize:13, fontWeight:600, color:'var(--text-2)' }}>{productNames[p.name] || p.name}</div>
                  {p.revenue > 0 && <div style={{ fontSize:11, color:'#34D399', marginTop:2 }}>جمع فروش: {fa(Math.round(p.revenue/1000000))} میلیون تومان</div>}
                  <Bar value={p.count} max={total} color='#34D399' />
                </div>
                <div style={{ textAlign:'center', flexShrink:0 }}>
                  <div className="mono semi" style={{ fontSize:22, color:'#34D399' }}>{fa(p.count)}</div>
                  <div style={{ fontSize:10, color:'var(--text-3)' }}>مشاهده ←</div>
                </div>
              </div>
            ))}
          </div>
        )}

        {/* توزیع مبلغ فروش */}
        {sale_amounts.length > 0 && (
          <div style={{ marginTop:14 }}>
            <div style={{ fontSize:11, color:'var(--text-3)', fontWeight:600, marginBottom:8 }}>توزیع مبلغ خرید:</div>
            <div style={{ display:'flex', gap:8, flexWrap:'wrap' }}>
              {sale_amounts.map(s => (
                <div key={s.label} style={{ padding:'8px 12px', borderRadius:8, background:'rgba(52,211,153,0.08)', border:'1px solid rgba(52,211,153,0.2)', textAlign:'center', minWidth:70 }}>
                  <div className="mono semi" style={{ fontSize:16, color:'#34D399' }}>{fa(s.count)}</div>
                  <div style={{ fontSize:10, color:'var(--text-3)', marginTop:2 }}>{s.label} تومان</div>
                </div>
              ))}
            </div>
          </div>
        )}
      </SCard>

      {/* ── ۳) مشاوره ── */}
      <SCard title="📞 مشاوره — کیا مشاوره شدن، کیا نشدن؟">
        {!consultation.tracked ? (
          <div>
            <div style={{ padding:'10px 14px', borderRadius:8, background:'rgba(251,191,36,0.06)', border:'1px solid rgba(251,191,36,0.2)', fontSize:12, color:'#FBBF24', marginBottom:12 }}>
              ⚠️ فیلد <code style={{background:'rgba(255,255,255,0.07)',padding:'1px 5px',borderRadius:4}}>consultation_at</code> در سیستم ثبت نمی‌شه — بر اساس نتیجه تماس تخمین زدیم
            </div>
            <div style={{ display:'grid', gridTemplateColumns:'1fr 1fr', gap:10 }}>
              <div style={{ padding:'14px', borderRadius:10, background:'rgba(52,211,153,0.08)', border:'1px solid rgba(52,211,153,0.2)', textAlign:'center' }}>
                <div className="mono semi" style={{ fontSize:24, color:'#34D399' }}>{fa(answered_leads)}</div>
                <div style={{ fontSize:11, color:'var(--text-3)', marginTop:4 }}>مشاوره شدن</div>
                <div style={{ fontSize:10, color:'var(--text-3)', marginTop:2 }}>آخرین تماس: جواب داد یا پیگیری</div>
              </div>
              <div style={{ padding:'14px', borderRadius:10, background:'rgba(148,163,184,0.08)', border:'1px solid rgba(148,163,184,0.2)', textAlign:'center' }}>
                <div className="mono semi" style={{ fontSize:24, color:'#94A3B8' }}>{fa(never_called)}</div>
                <div style={{ fontSize:11, color:'var(--text-3)', marginTop:4 }}>اصلاً تماس نگرفتیم</div>
                <div style={{ fontSize:10, color:'#F87171', marginTop:2 }}>فرصت از دست رفته</div>
              </div>
            </div>
          </div>
        ) : (
          <div style={{ display:'grid', gridTemplateColumns:'1fr 1fr', gap:10 }}>
            <div style={{ padding:'14px', borderRadius:10, background:'rgba(52,211,153,0.08)', textAlign:'center' }}>
              <div className="mono semi" style={{ fontSize:24, color:'#34D399' }}>{fa(consultation.consulted)}</div>
              <div style={{ fontSize:11, color:'var(--text-3)' }}>مشاوره شدن</div>
            </div>
            <div style={{ padding:'14px', borderRadius:10, background:'rgba(148,163,184,0.08)', textAlign:'center' }}>
              <div className="mono semi" style={{ fontSize:24, color:'#94A3B8' }}>{fa(consultation.not_consulted)}</div>
              <div style={{ fontSize:11, color:'var(--text-3)' }}>مشاوره نشدن</div>
            </div>
          </div>
        )}

        {/* جزئیات نتایج تماس */}
        {call_outcomes.length > 0 && (
          <div style={{ marginTop:12 }}>
            <div style={{ fontSize:11, color:'var(--text-3)', fontWeight:600, marginBottom:8 }}>جزئیات {fa(totalCalls)} تماس CRM:</div>
            <div style={{ display:'flex', gap:8, flexWrap:'wrap' }}>
              {call_outcomes.map(c => (
                <div key={c.outcome} style={{ padding:'8px 12px', borderRadius:8, background:`${outcomeColor[c.outcome]||'#818CF8'}10`, border:`1px solid ${outcomeColor[c.outcome]||'#818CF8'}30`, textAlign:'center', minWidth:90 }}>
                  <div className="mono semi" style={{ fontSize:16, color:outcomeColor[c.outcome]||'#818CF8' }}>{fa(c.n)}</div>
                  <div style={{ fontSize:10, color:'var(--text-3)', marginTop:2 }}>{outcomeName[c.outcome]||c.outcome}</div>
                  <div style={{ fontSize:10, color:outcomeColor[c.outcome]||'#818CF8' }}>{fa(totalCalls?Math.round(c.n*100/totalCalls):0)}٪</div>
                </div>
              ))}
            </div>
          </div>
        )}
      </SCard>

      {/* ── ۴) دوره رایگان ── */}
      <SCard title="🎓 دوره رایگان — کیا دیدن؟">
        {!free_courses.tracked ? (
          <div style={{ padding:'12px 14px', borderRadius:8, background:'rgba(248,113,113,0.06)', border:'1px solid rgba(248,113,113,0.2)', fontSize:12, color:'#94A3B8' }}>
            ⚠️ فیلد <code style={{background:'rgba(255,255,255,0.07)',padding:'1px 5px',borderRadius:4}}>free_courses_count</code> ثبت نشده —
            فقط <strong style={{color:'#FBBF24'}}>{fa(free_courses.total)} نفر</strong> در دیتابیس این فیلد رو دارن.
            برای فعال‌سازی این آمار، هنگام ثبت مشاوره عدد دوره رایگان رو وارد کن.
          </div>
        ) : (
          <div>
            <div style={{ display:'flex', gap:10, flexWrap:'wrap' }}>
              {Object.entries(free_courses.distribution).map(([k,v]) => (
                <div key={k} style={{ padding:'10px 14px', borderRadius:10, background:'rgba(96,165,250,0.08)', border:'1px solid rgba(96,165,250,0.2)', textAlign:'center' }}>
                  <div className="mono semi" style={{ fontSize:18, color:'#60A5FA' }}>{fa(v)}</div>
                  <div style={{ fontSize:10, color:'var(--text-3)', marginTop:2 }}>{fa(k)} دوره رایگان</div>
                </div>
              ))}
            </div>
            {free_courses.leads.length > 0 && (
              <button onClick={() => openDrill('دوره رایگان دیدن', free_courses.leads)} style={{ marginTop:10, padding:'7px 14px', borderRadius:8, border:'1px solid rgba(96,165,250,0.3)', background:'rgba(96,165,250,0.06)', color:'#60A5FA', cursor:'pointer', fontSize:12, fontFamily:'inherit' }}>
                مشاهده لیست ←
              </button>
            )}
          </div>
        )}
      </SCard>

      {/* ── ۵) وضعیت لیدها ── */}
      <SCard title="📊 وضعیت کلی لیدها">
        <div style={{ display:'flex', gap:8, flexWrap:'wrap' }}>
          {statuses.map(s => {
            const c = statusColor[s.status]||'#818CF8';
            const pct = Math.round(s.count*100/total);
            return (
              <div key={s.status} style={{ flex:'1 1 100px', padding:'12px', borderRadius:10, background:`${c}0D`, border:`1px solid ${c}30`, textAlign:'center' }}>
                <div className="mono semi" style={{ fontSize:22, color:c }}>{fa(s.count)}</div>
                <div style={{ fontSize:11, color:'var(--text-3)', marginTop:3 }}>{statusLabel[s.status]||s.status}</div>
                <Bar value={s.count} max={total} color={c} />
                <div style={{ fontSize:10, color:c, marginTop:3 }}>{fa(pct)}٪</div>
              </div>
            );
          })}
        </div>
      </SCard>

      {/* ── ۶) پلتفرم ورودی ── */}
      <SCard title="🌐 از کجا وارد شدن؟">
        <div style={{ display:'flex', gap:8, flexWrap:'wrap' }}>
          {platforms.map(p => {
            const pct = Math.round(p.count*100/total);
            return (
              <div key={p.name} style={{ flex:'1 1 100px', padding:'12px', borderRadius:10, background:'rgba(129,140,248,0.06)', border:'1px solid rgba(129,140,248,0.15)', textAlign:'center' }}>
                <div style={{ fontSize:20, marginBottom:4 }}>{platIcon[p.name]||'💬'}</div>
                <div className="mono semi" style={{ fontSize:20, color:'var(--text-2)' }}>{fa(p.count)}</div>
                <div style={{ fontSize:11, color:'var(--text-3)', marginTop:3 }}>{platLabel[p.name]||p.name}</div>
                <Bar value={p.count} max={total} color='#818CF8' />
                <div style={{ fontSize:10, color:'var(--text-3)', marginTop:3 }}>{fa(pct)}٪</div>
              </div>
            );
          })}
        </div>
      </SCard>

      {/* ── ۷) فرصت‌های اقدام فوری ── */}
      <SCard title="🎯 فرصت‌های اقدام فوری — ترکیب وضعیت × تلفن">
        <div style={{ fontSize:11, color:'var(--text-3)', marginBottom:10 }}>هر لید می‌تونه در چند دسته باشه — کلیک برای دیدن اسامی</div>
        <div style={{ display:'flex', flexDirection:'column', gap:8 }}>
          {opportunities.map(op => (
            <div
              key={op.key}
              onClick={() => op.count > 0 && openDrill(op.label, op.leads)}
              style={{ display:'flex', alignItems:'center', gap:12, padding:'12px 14px', borderRadius:10, background:`${op.color}0A`, border:`1px solid ${op.color}25`, cursor:op.count>0?'pointer':'default', opacity:op.count?1:.4, transition:'all .15s' }}
              onMouseEnter={e => { if(op.count>0){ e.currentTarget.style.background=`${op.color}18`; e.currentTarget.style.borderColor=`${op.color}50`; }}}
              onMouseLeave={e => { e.currentTarget.style.background=`${op.color}0A`; e.currentTarget.style.borderColor=`${op.color}25`; }}
            >
              <span style={{ fontSize:22, flexShrink:0 }}>{op.icon}</span>
              <div style={{ flex:1, minWidth:0 }}>
                <div style={{ fontSize:13, fontWeight:600, color:'var(--text-2)' }}>{op.label}</div>
                <div style={{ fontSize:11, color:'var(--text-3)', marginTop:2 }}>{op.desc}</div>
              </div>
              <div style={{ textAlign:'center', flexShrink:0 }}>
                <div className="mono semi" style={{ fontSize:22, color:op.color }}>{fa(op.count)}</div>
                {op.count>0 && <div style={{ fontSize:10, color:op.color }}>مشاهده ←</div>}
              </div>
            </div>
          ))}
        </div>
      </SCard>

      {/* ── ۸) ورودی ماه به ماه ── */}
      {monthly_entry.length > 0 && (
        <SCard title="📅 ورودی لیدها — ماه به ماه">
          {(() => {
            const maxVal = Math.max(...monthly_entry.map(m => m.count), 1);
            const persianMonths = { '01':'فروردین','02':'اردیبهشت','03':'خرداد','04':'تیر','05':'مرداد','06':'شهریور','07':'مهر','08':'آبان','09':'آذر','10':'دی','11':'بهمن','12':'اسفند' };
            return (
              <div style={{ display:'flex', flexDirection:'column', gap:8 }}>
                {monthly_entry.map(m => {
                  const [yr, mo] = m.month.split('-');
                  const label = `${persianMonths[mo]||mo} ${yr}`;
                  const pct = Math.round(m.count*100/maxVal);
                  return (
                    <div key={m.month} style={{ display:'flex', alignItems:'center', gap:10 }}>
                      <div style={{ width:90, fontSize:11, color:'var(--text-3)', flexShrink:0, textAlign:'right' }}>{label}</div>
                      <div style={{ flex:1, height:22, background:'rgba(255,255,255,0.04)', borderRadius:6, overflow:'hidden' }}>
                        <div style={{ height:'100%', width:`${Math.max(2,pct)}%`, background:'rgba(129,140,248,0.5)', borderRadius:6, display:'flex', alignItems:'center', justifyContent:'flex-end', paddingLeft:6, transition:'width .5s' }}>
                        </div>
                      </div>
                      <div className="mono semi" style={{ width:36, fontSize:13, color:'#818CF8', flexShrink:0 }}>{fa(m.count)}</div>
                    </div>
                  );
                })}
              </div>
            );
          })()}
        </SCard>
      )}

      {/* ── ۹) تعداد تماس per lead ── */}
      <SCard title="📞 چند بار با هر لید تماس گرفتیم؟">
        <div style={{ display:'grid', gridTemplateColumns:'1fr 1fr', gap:10 }}>
          {Object.entries(call_freq).map(([key, cf]) => {
            const colors = { zero:'#F87171', one:'#FBBF24', few:'#818CF8', many:'#34D399' };
            const c = colors[key] || '#818CF8';
            const pct = total ? Math.round(cf.count*100/total) : 0;
            return (
              <div
                key={key}
                onClick={() => cf.count > 0 && openDrill(cf.label, cf.leads)}
                style={{ padding:'12px', borderRadius:10, background:`${c}0A`, border:`1px solid ${c}25`, cursor:cf.count>0?'pointer':'default', textAlign:'center', transition:'all .15s' }}
                onMouseEnter={e=>{if(cf.count>0){e.currentTarget.style.background=`${c}18`;}}}
                onMouseLeave={e=>{e.currentTarget.style.background=`${c}0A`;}}
              >
                <div className="mono semi" style={{ fontSize:24, color:c }}>{fa(cf.count)}</div>
                <div style={{ fontSize:11, color:'var(--text-3)', marginTop:3 }}>{cf.label}</div>
                <Bar value={cf.count} max={total} color={c} />
                <div style={{ fontSize:10, color:c, marginTop:3 }}>{fa(pct)}٪ {cf.count>0&&'— مشاهده ←'}</div>
              </div>
            );
          })}
        </div>
      </SCard>

      {/* ── ۱۰) نوع ورود ── */}
      {lead_types.length > 0 && (
        <SCard title="🚪 از کجا وارد سیستم شدن؟">
          <div style={{ display:'flex', gap:10, flexWrap:'wrap' }}>
            {lead_types.map(lt => {
              const icon = lt.type === 'bot' ? '🤖' : lt.type === 'manual_customer' ? '📋' : '❓';
              const label = lt.type === 'bot' ? 'از طریق بات' : lt.type === 'manual_customer' ? 'وارد شده توسط ادمین' : lt.type;
              const c = lt.type === 'bot' ? '#60A5FA' : '#818CF8';
              const pct = Math.round(lt.count*100/total);
              return (
                <div key={lt.type} style={{ flex:'1 1 140px', padding:'14px', borderRadius:10, background:`${c}0A`, border:`1px solid ${c}25`, textAlign:'center' }}>
                  <div style={{ fontSize:24, marginBottom:4 }}>{icon}</div>
                  <div className="mono semi" style={{ fontSize:22, color:c }}>{fa(lt.count)}</div>
                  <div style={{ fontSize:11, color:'var(--text-3)', marginTop:3 }}>{label}</div>
                  <Bar value={lt.count} max={total} color={c} />
                  <div style={{ fontSize:10, color:c, marginTop:3 }}>{fa(pct)}٪</div>
                </div>
              );
            })}
          </div>
        </SCard>
      )}

      {/* ── ۱۱) تگ‌ها ── */}
      {tags.length > 0 && (
        <SCard title="🏷️ تگ‌های لیدها">
          <div style={{ display:'flex', gap:8, flexWrap:'wrap' }}>
            {tags.map(t => (
              <div key={t.tag} style={{ padding:'6px 14px', borderRadius:20, background:'rgba(192,132,252,0.1)', border:'1px solid rgba(192,132,252,0.25)', fontSize:12, color:'#C084FC' }}>
                {t.tag} <span className="mono" style={{ marginRight:4, fontSize:13, fontWeight:700 }}>{fa(t.count)}</span>
              </div>
            ))}
          </div>
        </SCard>
      )}
    </div>
  );
};

// ══════════════════════════════════════════════════════════
// ── دستیار AI طراحی کمپین ──────────────────────────────────
// ══════════════════════════════════════════════════════════
const CampaignAIDesigner = ({ headers, onBack, onCreated }) => {
  const { Icon, Button } = window.SB_UI;
  const { fa } = window.SB_DATA;

  const GOAL_LABELS = { product: 'فروش محصول', followup: 'پیگیری لید', lead: 'جذب لید' };
  const DELAY_LABELS = [
    { h: 0, label: 'همزمان با شروع' }, { h: 1, label: '۱ ساعت بعد' },
    { h: 6, label: '۶ ساعت بعد' }, { h: 24, label: '۱ روز بعد' },
    { h: 48, label: '۲ روز بعد' }, { h: 72, label: '۳ روز بعد' },
    { h: 120, label: '۵ روز بعد' }, { h: 168, label: '۱ هفته بعد' },
  ];

  const [messages, setMessages] = useState([
    { role: 'assistant', content: 'سلام! من اینجام تا کمک کنم یه کمپین حرفه‌ای طراحی کنیم.\n\nبگو هدفت از این کمپین چیه؟ مثلاً:\n— «می‌خوام مشتریایی که مدتیه خرید نکردن رو برگردونم»\n— «می‌خوام لیدهای جدید رو گرم کنم»\n— «می‌خوام برای محصول جدیدم پیام بدم»' }
  ]);
  const [input,    setInput]    = useState('');
  const [loading,  setLoading]  = useState(false);
  const [proposal, setProposal] = useState(null);
  const [applying, setApplying] = useState(false);
  const bottomRef = useRef(null);
  const inputRef  = useRef(null);

  useEffect(() => { bottomRef.current?.scrollIntoView({ behavior: 'smooth' }); }, [messages]);

  const send = async () => {
    if (!input.trim() || loading) return;
    const userMsg = { role: 'user', content: input.trim() };
    const newMessages = [...messages, userMsg];
    setMessages(newMessages);
    setInput('');
    setLoading(true);

    try {
      const res = await fetch('/api/campaigns/ai-design-chat', {
        method: 'POST', headers,
        body: JSON.stringify({
          messages: newMessages.map(m => ({ role: m.role, content: m.content })),
          currentProposal: proposal,
        }),
      });
      const d = await res.json();
      if (d.success) {
        setMessages(prev => [...prev, {
          role: 'assistant',
          content: d.data.reply,
          hasProposal: !!d.data.proposal,
        }]);
        if (d.data.proposal) setProposal(d.data.proposal);
      } else {
        setMessages(prev => [...prev, { role: 'assistant', content: '❌ خطا: ' + (d.error || 'مشکلی پیش اومد') }]);
      }
    } catch (e) {
      setMessages(prev => [...prev, { role: 'assistant', content: '❌ خطا در ارتباط با سرور' }]);
    } finally {
      setLoading(false);
      setTimeout(() => inputRef.current?.focus(), 100);
    }
  };

  const handleKey = (e) => {
    if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); send(); }
  };

  const apply = async () => {
    if (!proposal || applying) return;
    setApplying(true);
    try {
      const res = await fetch('/api/campaigns/ai-design-apply', {
        method: 'POST', headers,
        body: JSON.stringify({ proposal }),
      });
      const d = await res.json();
      if (d.success) {
        onCreated && onCreated(d.data);
      } else {
        alert('خطا: ' + (d.error || 'مشکلی پیش اومد'));
      }
    } finally {
      setApplying(false);
    }
  };

  // ── ویرایش step ──
  const updateStep = (idx, key, val) => {
    setProposal(p => {
      const steps = p.steps.map((s, i) => i === idx ? { ...s, [key]: val } : s);
      return { ...p, steps };
    });
  };
  const addStep = () => {
    setProposal(p => {
      const last = p.steps[p.steps.length - 1];
      return { ...p, steps: [...p.steps, { order: p.steps.length + 1, delay_h: (last?.delay_h || 0) + 24, label: 'مرحله جدید', message: '' }] };
    });
  };
  const removeStep = (idx) => {
    setProposal(p => ({ ...p, steps: p.steps.filter((_, i) => i !== idx).map((s, i) => ({ ...s, order: i + 1 })) }));
  };

  // ── UI ──
  const chatBg     = '#0f0f1e';
  const proposalBg = '#13132a';
  const borderSoft = 'rgba(255,255,255,0.07)';
  const accent     = '#6C63FF';

  return (
    <div style={{ position: 'fixed', inset: 0, zIndex: 1000, background: 'rgba(0,0,0,0.9)', display: 'flex', flexDirection: 'row-reverse' }}>

      {/* ── پنل چت (راست) ─────────────────── */}
      <div style={{ width: 400, flexShrink: 0, display: 'flex', flexDirection: 'column', background: chatBg, borderLeft: `1px solid ${borderSoft}` }}>

        {/* هدر */}
        <div style={{ padding: '14px 16px', borderBottom: `1px solid ${borderSoft}`, display: 'flex', alignItems: 'center', gap: 12 }}>
          <div style={{ width: 36, height: 36, borderRadius: 10, background: `linear-gradient(135deg,${accent},#4F46E5)`, display: 'grid', placeItems: 'center', flexShrink: 0 }}>
            <Icon name="bot" size={17} color="#fff" />
          </div>
          <div style={{ flex: 1 }}>
            <div className="semi" style={{ fontSize: 14 }}>دستیار طراحی کمپین</div>
            <div style={{ fontSize: 11, color: 'var(--text-3)' }}>هدفت رو بگو، کمپین می‌سازم</div>
          </div>
          <button onClick={onBack} style={{ width: 30, height: 30, borderRadius: 8, border: 'none', background: 'rgba(255,255,255,0.06)', color: 'var(--text-2)', cursor: 'pointer', display: 'grid', placeItems: 'center' }}>
            <Icon name="x" size={14} />
          </button>
        </div>

        {/* پیام‌ها */}
        <div style={{ flex: 1, overflowY: 'auto', padding: '14px 12px', display: 'flex', flexDirection: 'column', gap: 10 }}>
          {messages.map((m, i) => (
            <div key={i} style={{ display: 'flex', justifyContent: m.role === 'user' ? 'flex-start' : 'flex-end' }}>
              <div style={{
                maxWidth: '88%', padding: '10px 13px',
                borderRadius: m.role === 'user' ? '12px 12px 12px 3px' : '12px 12px 3px 12px',
                background: m.role === 'user' ? 'rgba(255,255,255,0.07)' : `rgba(108,99,255,0.18)`,
                fontSize: 13, lineHeight: 1.75, whiteSpace: 'pre-wrap', direction: 'rtl',
              }}>
                {m.content}
                {m.hasProposal && (
                  <div style={{ marginTop: 8, paddingTop: 8, borderTop: '1px solid rgba(255,255,255,0.1)', fontSize: 11, color: '#34D399' }}>
                    ✓ پیشنهاد کمپین در پنل چپ آپدیت شد
                  </div>
                )}
              </div>
            </div>
          ))}
          {loading && (
            <div style={{ display: 'flex', justifyContent: 'flex-end' }}>
              <div style={{ padding: '10px 14px', borderRadius: '12px 12px 3px 12px', background: `rgba(108,99,255,0.18)`, fontSize: 13, color: 'var(--text-3)' }}>
                ⟳ در حال فکر کردن...
              </div>
            </div>
          )}
          <div ref={bottomRef} />
        </div>

        {/* ورودی */}
        <div style={{ padding: '12px', borderTop: `1px solid ${borderSoft}` }}>
          <div style={{ display: 'flex', gap: 8, alignItems: 'flex-end' }}>
            <textarea
              ref={inputRef}
              value={input}
              onChange={e => setInput(e.target.value)}
              onKeyDown={handleKey}
              placeholder="هدفت رو بنویس..."
              rows={2}
              style={{ flex: 1, resize: 'none', padding: '9px 12px', borderRadius: 10, border: `1px solid ${borderSoft}`, background: 'rgba(255,255,255,0.05)', color: 'var(--text-1)', fontSize: 13, fontFamily: 'inherit', direction: 'rtl', lineHeight: 1.6, outline: 'none' }}
            />
            <button
              onClick={send}
              disabled={loading || !input.trim()}
              style={{ width: 40, height: 40, borderRadius: 10, border: 'none', background: loading || !input.trim() ? 'rgba(108,99,255,0.2)' : accent, color: '#fff', cursor: loading || !input.trim() ? 'not-allowed' : 'pointer', display: 'grid', placeItems: 'center', flexShrink: 0, transition: 'background .15s' }}
            >
              <Icon name="send" size={16} />
            </button>
          </div>
          <div style={{ fontSize: 10, color: 'var(--text-3)', marginTop: 6, textAlign: 'center' }}>Enter برای ارسال | Shift+Enter برای خط جدید</div>
        </div>
      </div>

      {/* ── پنل پیشنهاد (چپ) ──────────────── */}
      <div style={{ flex: 1, display: 'flex', flexDirection: 'column', background: proposalBg, overflow: 'hidden' }}>

        {/* هدر پنل پیشنهاد */}
        <div style={{ padding: '14px 20px', borderBottom: `1px solid ${borderSoft}`, display: 'flex', alignItems: 'center', gap: 12 }}>
          <div style={{ flex: 1 }}>
            <div className="semi" style={{ fontSize: 14 }}>پیشنهاد کمپین</div>
            <div style={{ fontSize: 11, color: 'var(--text-3)' }}>{proposal ? 'می‌تونی مستقیم ویرایش کنی' : 'هنوز پیشنهادی نداریم — با دستیار صحبت کن'}</div>
          </div>
          {proposal && (
            <button
              onClick={apply}
              disabled={applying}
              style={{ padding: '8px 18px', borderRadius: 10, border: 'none', background: applying ? 'rgba(52,211,153,0.2)' : '#34D399', color: applying ? '#34D399' : '#000', cursor: applying ? 'wait' : 'pointer', fontSize: 13, fontWeight: 700, fontFamily: 'inherit', display: 'flex', alignItems: 'center', gap: 6 }}
            >
              {applying ? '⟳ در حال ساخت...' : '✓ تایید و ساخت کمپین'}
            </button>
          )}
        </div>

        {/* محتوای پیشنهاد */}
        <div style={{ flex: 1, overflowY: 'auto', padding: '20px' }}>
          {!proposal ? (
            <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', height: '100%', gap: 16, color: 'var(--text-3)' }}>
              <div style={{ fontSize: 48 }}>🤖</div>
              <div style={{ fontSize: 15, textAlign: 'center' }}>با دستیار صحبت کن</div>
              <div style={{ fontSize: 12, textAlign: 'center', maxWidth: 280, lineHeight: 1.8 }}>
                بگو هدفت چیه — AI از تریگرها، اسکریپت‌ها، فالوآپ‌ها و کتابخانه‌ات استفاده می‌کنه و یه کمپین کامل پیشنهاد می‌ده.
              </div>
            </div>
          ) : (
            <div style={{ display: 'flex', flexDirection: 'column', gap: 16, maxWidth: 700 }}>

              {/* اطلاعات پایه */}
              <div style={{ padding: '16px 18px', borderRadius: 12, background: 'rgba(255,255,255,0.04)', border: `1px solid ${borderSoft}` }}>
                <div style={{ fontSize: 11, color: 'var(--text-3)', marginBottom: 12, display: 'flex', alignItems: 'center', gap: 6 }}>
                  <span>🎯</span> اطلاعات کمپین
                </div>
                <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>

                  <div>
                    <div style={{ fontSize: 11, color: 'var(--text-3)', marginBottom: 4 }}>نام کمپین</div>
                    <input
                      value={proposal.name || ''}
                      onChange={e => setProposal(p => ({ ...p, name: e.target.value }))}
                      style={{ width: '100%', padding: '8px 12px', borderRadius: 8, border: `1px solid ${borderSoft}`, background: 'rgba(255,255,255,0.05)', color: 'var(--text-1)', fontSize: 14, fontFamily: 'inherit', direction: 'rtl', outline: 'none', boxSizing: 'border-box' }}
                    />
                  </div>

                  <div style={{ display: 'flex', gap: 10 }}>
                    <div style={{ flex: 1 }}>
                      <div style={{ fontSize: 11, color: 'var(--text-3)', marginBottom: 4 }}>هدف</div>
                      <select
                        value={proposal.goal || 'product'}
                        onChange={e => setProposal(p => ({ ...p, goal: e.target.value }))}
                        style={{ width: '100%', padding: '8px 12px', borderRadius: 8, border: `1px solid ${borderSoft}`, background: 'rgba(255,255,255,0.05)', color: 'var(--text-1)', fontSize: 13, fontFamily: 'inherit', direction: 'rtl', outline: 'none' }}
                      >
                        {Object.entries(GOAL_LABELS).map(([v, l]) => <option key={v} value={v}>{l}</option>)}
                      </select>
                    </div>
                  </div>

                  <div>
                    <div style={{ fontSize: 11, color: 'var(--text-3)', marginBottom: 4 }}>توضیح کمپین</div>
                    <textarea
                      value={proposal.description || ''}
                      onChange={e => setProposal(p => ({ ...p, description: e.target.value }))}
                      rows={2}
                      style={{ width: '100%', padding: '8px 12px', borderRadius: 8, border: `1px solid ${borderSoft}`, background: 'rgba(255,255,255,0.05)', color: 'var(--text-1)', fontSize: 13, fontFamily: 'inherit', direction: 'rtl', resize: 'none', outline: 'none', boxSizing: 'border-box' }}
                    />
                  </div>

                  <div>
                    <div style={{ fontSize: 11, color: 'var(--text-3)', marginBottom: 4 }}>🔍 چه لیدهایی وارد این کمپین بشن؟</div>
                    <textarea
                      value={proposal.filter_suggestion || ''}
                      onChange={e => setProposal(p => ({ ...p, filter_suggestion: e.target.value }))}
                      rows={2}
                      style={{ width: '100%', padding: '8px 12px', borderRadius: 8, border: `1px solid rgba(251,191,36,0.2)`, background: 'rgba(251,191,36,0.04)', color: '#FBBF24', fontSize: 12, fontFamily: 'inherit', direction: 'rtl', resize: 'none', outline: 'none', boxSizing: 'border-box' }}
                    />
                  </div>
                </div>
              </div>

              {/* مراحل سکانس */}
              <div>
                <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 10 }}>
                  <div style={{ fontSize: 12, color: 'var(--text-2)', display: 'flex', alignItems: 'center', gap: 6 }}>
                    <span>📨</span>
                    <span className="semi">سکانس پیام‌ها ({fa(proposal.steps?.length || 0)} مرحله)</span>
                  </div>
                  <button
                    onClick={addStep}
                    style={{ padding: '5px 12px', borderRadius: 8, border: `1px solid rgba(108,99,255,0.3)`, background: 'rgba(108,99,255,0.08)', color: accent, cursor: 'pointer', fontSize: 11, fontFamily: 'inherit', display: 'flex', alignItems: 'center', gap: 4 }}
                  >
                    + مرحله جدید
                  </button>
                </div>

                <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
                  {(proposal.steps || []).map((step, idx) => (
                    <div key={idx} style={{ padding: '14px 16px', borderRadius: 12, background: 'rgba(255,255,255,0.03)', border: `1px solid ${borderSoft}`, position: 'relative' }}>

                      {/* سربرگ step */}
                      <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: 10 }}>
                        <div style={{ width: 26, height: 26, borderRadius: 8, background: `${accent}22`, border: `1px solid ${accent}44`, display: 'grid', placeItems: 'center', fontSize: 12, color: accent, fontWeight: 700, flexShrink: 0 }}>
                          {fa(idx + 1)}
                        </div>
                        <input
                          value={step.label || ''}
                          onChange={e => updateStep(idx, 'label', e.target.value)}
                          placeholder="عنوان مرحله..."
                          style={{ flex: 1, padding: '5px 10px', borderRadius: 7, border: `1px solid ${borderSoft}`, background: 'rgba(255,255,255,0.05)', color: 'var(--text-1)', fontSize: 12, fontFamily: 'inherit', direction: 'rtl', outline: 'none' }}
                        />
                        <select
                          value={String(step.delay_h || 0)}
                          onChange={e => updateStep(idx, 'delay_h', Number(e.target.value))}
                          style={{ padding: '5px 8px', borderRadius: 7, border: `1px solid ${borderSoft}`, background: 'rgba(255,255,255,0.05)', color: 'var(--text-3)', fontSize: 11, fontFamily: 'inherit', direction: 'rtl', outline: 'none', flexShrink: 0 }}
                        >
                          {DELAY_LABELS.map(d => <option key={d.h} value={String(d.h)}>{d.label}</option>)}
                        </select>
                        {proposal.steps.length > 1 && (
                          <button
                            onClick={() => removeStep(idx)}
                            style={{ width: 24, height: 24, borderRadius: 6, border: 'none', background: 'rgba(248,113,113,0.1)', color: '#F87171', cursor: 'pointer', display: 'grid', placeItems: 'center', flexShrink: 0, fontSize: 12 }}
                          >×</button>
                        )}
                      </div>

                      {/* متن پیام */}
                      <textarea
                        value={step.message || ''}
                        onChange={e => updateStep(idx, 'message', e.target.value)}
                        placeholder="متن پیام این مرحله..."
                        rows={3}
                        style={{ width: '100%', padding: '8px 12px', borderRadius: 8, border: `1px solid ${borderSoft}`, background: 'rgba(255,255,255,0.04)', color: 'var(--text-1)', fontSize: 13, fontFamily: 'inherit', direction: 'rtl', resize: 'vertical', outline: 'none', boxSizing: 'border-box', lineHeight: 1.7 }}
                      />
                    </div>
                  ))}
                </div>
              </div>

              {/* دکمه تایید پایین */}
              <div style={{ padding: '16px 0', borderTop: `1px solid ${borderSoft}`, display: 'flex', justifyContent: 'center' }}>
                <button
                  onClick={apply}
                  disabled={applying || !proposal.name?.trim()}
                  style={{ padding: '12px 32px', borderRadius: 12, border: 'none', background: applying || !proposal.name?.trim() ? 'rgba(52,211,153,0.15)' : '#34D399', color: applying || !proposal.name?.trim() ? '#34D399' : '#000', cursor: applying || !proposal.name?.trim() ? 'not-allowed' : 'pointer', fontSize: 14, fontWeight: 700, fontFamily: 'inherit' }}
                >
                  {applying ? '⟳ در حال ساخت کمپین...' : '✓ تایید و ساخت کمپین'}
                </button>
              </div>
            </div>
          )}
        </div>
      </div>
    </div>
  );
};


// ─── تریگرها ─────────────────────────────────────────────────────────────
// triggers.jsx — keyword triggers (free-course or AI script)
// این فایل از campaigns.jsx جدا شد تا نام‌گذاری درست باشه
const Triggers = () => {
  const { Icon, Button, Modal, Field, Toggle, useToast } = window.SB_UI;
  const { fa } = window.SB_DATA;

  const [triggers, setTriggers] = useState([]);
  const [scripts,  setScripts]  = useState([]);
  const [files,    setFiles]    = useState([]);
  const [open,     setOpen]     = useState(false);   // مودال ساخت
  const [editId,   setEditId]   = useState(null);    // مودال ادیت
  const [loading,  setLoading]  = useState(true);
  const toast = useToast();

  // فرم ساخت
  const [mode,    setMode]    = useState('free_course');
  const [form,    setForm]    = useState({ name: '', keyword: '', script_id: '', platform: 'all', welcome_msg: '', followup_msg: '', file_ids: [] });
  // فرم ادیت
  const [eform,   setEform]   = useState({ keyword: '', name: '', welcome_msg: '', followup_msg: '', file_ids: [], script_id: '' });

  const [libOpen,  setLibOpen]  = useState(false);  // پیکر کتابخانه (ساخت)
  const [elibOpen, setElibOpen] = useState(false);  // پیکر کتابخانه (ادیت)

  const token   = localStorage.getItem(window.TOKEN_KEY);
  const headers = { 'Content-Type': 'application/json', Authorization: `Bearer ${token}` };

  const load = () => {
    setLoading(true);
    Promise.all([
      fetch('/api/scripts/campaigns/triggers', { headers }).then(r => r.json()),
      fetch('/api/scripts',                    { headers }).then(r => r.json()),
      fetch('/api/library',                    { headers }).then(r => r.json()),
    ]).then(([td, sd, ld]) => {
      if (td.success) setTriggers(td.data.triggers || []);
      if (sd.success && sd.data?.scripts?.length) {
        setScripts(sd.data.scripts);
        setForm(f => ({ ...f, script_id: f.script_id || sd.data.scripts[0]?.id || '' }));
      }
      if (ld.success) setFiles(ld.data.files || []);
    }).finally(() => setLoading(false));
  };

  useEffect(() => { load(); }, []);

  // ─── Toggle فعال/غیرفعال ─────────────────────────────────
  const toggleActive = (t) => {
    const newVal = t.is_active ? 0 : 1;
    fetch(`/api/scripts/campaigns/triggers/${t.id}`, {
      method: 'PUT', headers, body: JSON.stringify({ is_active: newVal }),
    }).then(r => r.json()).then(d => {
      if (d.success) {
        setTriggers(prev => prev.map(x => x.id === t.id ? { ...x, is_active: newVal } : x));
        toast(newVal ? 'تریگر فعال شد' : 'تریگر غیرفعال شد', 'success');
      }
    });
  };

  // ─── باز کردن مودال ادیت ────────────────────────────────
  const openEdit = (t) => {
    let fileIds = [];
    try { fileIds = JSON.parse(t.file_ids || '[]'); } catch {}
    setEform({
      keyword:      t.keyword || '',
      name:         t.name || t.keyword,
      welcome_msg:  t.welcome_msg  || '',
      followup_msg: t.followup_msg || '',
      file_ids:     fileIds,
      script_id:    t.is_free_course ? '' : (t.script_id || ''),
    });
    setEditId(t.id);
  };

  // ─── ذخیره ادیت ─────────────────────────────────────────
  const saveEdit = () => {
    const t = triggers.find(x => x.id === editId);
    if (!t) { toast('خطا: تریگر پیدا نشد — صفحه را رفرش کنید', 'error'); return; }

    const newKeyword = eform.keyword.trim();
    if (!newKeyword) return toast('کلمه کلیدی نمی‌تواند خالی باشد', 'error');

    const body = t.is_free_course
      ? { keyword: newKeyword, name: eform.name, welcome_msg: eform.welcome_msg, followup_msg: eform.followup_msg, file_ids: eform.file_ids }
      : { keyword: newKeyword, name: eform.name, script_id: eform.script_id };

    fetch(`/api/scripts/campaigns/triggers/${editId}`, { method: 'PUT', headers, body: JSON.stringify(body) })
      .then(r => r.json())
      .then(d => {
        if (d.success) {
          toast('تریگر آپدیت شد ✓', 'success');
          setEditId(null);

          const isFree = t.is_free_course;
          const newScriptId = isFree ? t.script_id : eform.script_id;
          const scriptObj   = isFree ? null : scripts.find(s => s.id === newScriptId);
          let fileIds = isFree ? eform.file_ids : (t.file_ids ? JSON.parse(t.file_ids) : []);
          try { if (!Array.isArray(fileIds)) fileIds = JSON.parse(fileIds); } catch { fileIds = []; }

          setTriggers(prev => prev.map(x => x.id === editId ? {
            ...x,
            keyword:      eform.keyword.trim() || x.keyword,
            name:         eform.name || eform.keyword.trim() || x.keyword,
            welcome_msg:  isFree ? eform.welcome_msg  : x.welcome_msg,
            followup_msg: isFree ? eform.followup_msg : x.followup_msg,
            file_ids:     isFree ? JSON.stringify(eform.file_ids) : x.file_ids,
            script_id:    newScriptId,
            trigger_name: eform.name || eform.keyword.trim() || x.keyword,
            script_name:  scriptObj?.name || (isFree ? null : '—'),
            file_count:   isFree ? eform.file_ids.length : x.file_count,
          } : x));
        } else {
          toast(d.message || 'خطا در ذخیره', 'error');
        }
      })
      .catch(() => toast('خطای شبکه — سرور در دسترس نیست', 'error'));
  };

  // ─── حذف تریگر ───────────────────────────────────────────
  const deleteTrigger = (id, keyword) => {
    if (!confirm(`تریگر «${keyword}» حذف شود؟`)) return;
    fetch(`/api/scripts/campaigns/triggers/${id}`, { method: 'DELETE', headers })
      .then(r => r.json()).then(d => {
        if (d.success) { toast('تریگر حذف شد', 'success'); setTriggers(prev => prev.filter(t => t.id !== id)); }
      });
  };

  // ─── ساخت تریگر ──────────────────────────────────────────
  const submit = () => {
    if (!form.keyword.trim()) return toast('کلمه کلیدی الزامیه', 'error');
    if (mode === 'script'      && !form.script_id)           return toast('اسکریپت را انتخاب کنید', 'error');
    if (mode === 'free_course' && form.file_ids.length === 0) return toast('حداقل یک فایل انتخاب کنید', 'error');

    const body = mode === 'free_course'
      ? { name: form.name.trim() || form.keyword.trim(), keyword: form.keyword.trim(), platform: form.platform, file_ids: form.file_ids, welcome_msg: form.welcome_msg, followup_msg: form.followup_msg }
      : { name: form.name.trim() || form.keyword.trim(), keyword: form.keyword.trim(), platform: form.platform, script_id: form.script_id };

    fetch('/api/scripts/campaigns/triggers', { method: 'POST', headers, body: JSON.stringify(body) })
      .then(r => r.json()).then(d => {
        if (d.success) {
          toast('تریگر ساخته شد ✓', 'success');
          setOpen(false);
          setForm(f => ({ ...f, name: '', keyword: '', welcome_msg: '', followup_msg: '', file_ids: [] }));
          load();
        } else {
          toast(d.message || 'خطا در ساخت تریگر', 'error');
        }
      });
  };

  // ─── آپلود یک فایل ──────────────────────────────────────
  const uploadOne = async (file) => {
    const fd = new FormData();
    fd.append('file', file);
    fd.append('name', file.name.replace(/\.[^.]+$/, ''));
    const r = await fetch('/api/library/upload', { method: 'POST', headers: { Authorization: `Bearer ${token}` }, body: fd });
    const d = await r.json();
    if (!d.success) throw new Error(d.message || 'آپلود ناموفق');
    return d.data.file;
  };

  const handleUpload = async (fileList, isEdit = false) => {
    const files_ = Array.from(fileList || []);
    if (!files_.length) return;
    const addId = (id) => {
      if (isEdit) setEform(f => ({ ...f, file_ids: [...f.file_ids, id] }));
      else        setForm(f => ({ ...f, file_ids: [...f.file_ids, id] }));
    };
    let ok = 0;
    for (const file of files_) {
      try {
        const uploaded = await uploadOne(file);
        setFiles(prev => [uploaded, ...prev]);
        addId(uploaded.id);
        ok++;
      } catch (e) {
        toast(`خطا در آپلود «${file.name}»`, 'error');
      }
    }
    if (ok > 0) toast(`${ok} فایل آپلود شد ✓`, 'success');
  };

  const platformLabel = (p) => ({ all: 'همه', telegram: 'تلگرام', bale: 'بله', instagram: 'اینستاگرام' }[p] || p);
  const platformColor = (p) => ({ all: '#818CF8', telegram: '#3B82F6', bale: '#10B981', instagram: '#FF6B35' }[p] || '#6B7280');
  const fileIcon = (type) => ({ video: '🎬', audio: '🎧', image: '🖼', pdf: '📄', text: '📝' }[type] || '📎');

  const selectedFiles = files.filter(f => form.file_ids.includes(f.id));
  const editTrigger   = triggers.find(t => t.id === editId);

  const FilePicker = ({ fileIds, onChange, onUpload, isEdit = false }) => {
    const selected = files.filter(f => fileIds.includes(f.id));
    return (
      <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
        {selected.length > 0 && (
          <div style={{ maxHeight: 132, overflowY: 'auto', display: 'flex', flexDirection: 'column', gap: 4 }}>
            {selected.map(f => (
              <div key={f.id} style={{ display: 'flex', alignItems: 'center', gap: 8, padding: '7px 10px', borderRadius: 8, background: 'rgba(16,185,129,0.08)', border: '1px solid rgba(16,185,129,0.2)', flexShrink: 0 }}>
                <span style={{ fontSize: 15, flexShrink: 0 }}>{fileIcon(f.file_type)}</span>
                <span className="text-sm" style={{ flex: 1, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{f.name}</span>
                <button onClick={() => onChange(fileIds.filter(id => id !== f.id))}
                  style={{ border: 'none', background: 'transparent', color: '#F87171', cursor: 'pointer', fontSize: 13, padding: '0 2px', flexShrink: 0 }}>✕</button>
              </div>
            ))}
          </div>
        )}
        <div style={{ display: 'flex', gap: 8 }}>
          <button onClick={onUpload} style={{ flex: 1, padding: '8px', borderRadius: 9, border: '1.5px dashed rgba(108,99,255,0.35)', background: 'transparent', color: '#A5B4FC', cursor: 'pointer', fontSize: 12, fontFamily: 'inherit' }}>
            + انتخاب از کتابخانه
          </button>
          <label style={{ flex: 1, padding: '8px', borderRadius: 9, border: '1.5px dashed rgba(52,211,153,0.35)', background: 'transparent', color: '#34D399', cursor: 'pointer', fontSize: 12, textAlign: 'center', fontFamily: 'inherit' }}>
            ⬆ آپلود فایل
            <input type="file" multiple style={{ display: 'none' }}
              onChange={e => { if (e.target.files?.length) handleUpload(e.target.files, isEdit); }} />
          </label>
        </div>
      </div>
    );
  };

  const LibraryPicker = ({ open: isOpen, onClose, fileIds, onChange }) => (
    <Modal open={isOpen} onClose={onClose} title="انتخاب از کتابخانه" width={600}
      footer={<Button kind="primary" onClick={onClose}>تأیید ({fileIds.length} فایل)</Button>}
    >
      {files.length === 0 ? (
        <div style={{ textAlign: 'center', padding: 40, color: 'var(--text-3)' }}>
          <div style={{ fontSize: 40, marginBottom: 12 }}>📂</div>
          <div>کتابخانه خالی است</div>
        </div>
      ) : (
        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 8 }}>
          {files.map(f => {
            const selected = fileIds.includes(f.id);
            return (
              <button key={f.id} onClick={() => onChange(selected ? fileIds.filter(id => id !== f.id) : [...fileIds, f.id])}
                style={{ display: 'flex', alignItems: 'center', gap: 10, padding: '10px 12px', borderRadius: 10, border: `1.5px solid ${selected ? 'rgba(16,185,129,0.5)' : 'var(--border-soft)'}`, background: selected ? 'rgba(16,185,129,0.09)' : 'var(--bg-2)', cursor: 'pointer', textAlign: 'right', fontFamily: 'inherit', transition: 'all .12s' }}>
                <span style={{ fontSize: 22, flexShrink: 0 }}>{fileIcon(f.file_type)}</span>
                <div style={{ flex: 1, minWidth: 0 }}>
                  <div className="semi text-sm" style={{ overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap', color: selected ? '#34D399' : 'var(--text-1)' }}>{f.name}</div>
                  <div className="text-xs text-3 mt-2">{f.file_type} · {f.original_name}</div>
                </div>
                {selected && <span style={{ color: '#34D399', fontSize: 16, flexShrink: 0 }}>✓</span>}
              </button>
            );
          })}
        </div>
      )}
    </Modal>
  );

  return (
    <div>
      <div className="row between">
        <div>
          <div className="semi" style={{ fontSize: 15 }}>تریگرها</div>
          <div className="text-xs text-3 mt-4">
            {loading ? 'در حال بارگذاری...' : `${fa(triggers.length)} تریگر تعریف شده`}
          </div>
        </div>
        <Button kind="primary" icon="plus" onClick={() => setOpen(true)}>تریگر جدید</Button>
      </div>

      <div style={{ marginTop: 16, padding: '12px 16px', background: 'rgba(108,99,255,0.08)', borderRadius: 10, borderRight: '3px solid var(--primary)' }}>
        <div className="text-sm" style={{ color: 'var(--text-2)', lineHeight: 1.8 }}>
          <strong>تریگر چیه:</strong> کاربر یه کلمه کلیدی می‌فرسته → ربات فایل‌های دوره رایگان ارسال می‌کنه (بدون هوش مصنوعی) یا اسکریپت فروش AI فعال می‌شه.
        </div>
      </div>

      {loading ? (
        <div style={{ textAlign: 'center', padding: 60, color: 'var(--text-3)' }}>در حال بارگذاری...</div>
      ) : triggers.length === 0 ? (
        <div className="card mt-16" style={{ textAlign: 'center', padding: 60 }}>
          <Icon name="zap" size={44} color="var(--text-3)" />
          <div className="semi mt-16">هنوز تریگری تعریف نشده</div>
          <div style={{ marginTop: 20 }}>
            <Button kind="primary" icon="plus" onClick={() => setOpen(true)}>اولین تریگر را بساز</Button>
          </div>
        </div>
      ) : (
        <div className="card mt-16" style={{ padding: 0, overflow: 'hidden' }}>
          <table className="table">
            <thead>
              <tr>
                <th>نام / کلید</th>
                <th>نوع</th>
                <th>پلتفرم</th>
                <th style={{ textAlign: 'center' }}>اجرا</th>
                <th style={{ textAlign: 'center' }}>وضعیت</th>
                <th style={{ width: 72 }}></th>
              </tr>
            </thead>
            <tbody>
              {triggers.map(t => (
                <tr key={t.id} style={{ opacity: t.is_active ? 1 : 0.5 }}>
                  <td>
                    <div className="col gap-2">
                      <span className="semi text-sm">{t.trigger_name || t.name || t.keyword}</span>
                      <span className="mono text-xs text-3">{t.keyword}</span>
                    </div>
                  </td>
                  <td>
                    {t.is_free_course ? (
                      <div className="row gap-6">
                        <span style={{ fontSize: 11, padding: '2px 9px', borderRadius: 6, background: 'rgba(16,185,129,0.12)', color: '#34D399', fontWeight: 600 }}>📦 دوره رایگان</span>
                        <span style={{ fontSize: 11, color: 'var(--text-3)' }}>{fa(t.file_count)} فایل</span>
                      </div>
                    ) : (
                      <div className="row gap-8">
                        <div style={{ width: 26, height: 26, borderRadius: 6, background: 'rgba(108,99,255,0.12)', display: 'grid', placeItems: 'center', flexShrink: 0 }}>
                          <Icon name="file-text" size={12} color="#A5B4FC" />
                        </div>
                        <span className="semi text-sm">{t.script_name || '—'}</span>
                      </div>
                    )}
                  </td>
                  <td>
                    <span style={{ fontSize: 11, padding: '2px 8px', borderRadius: 6, background: platformColor(t.platform) + '22', color: platformColor(t.platform) }}>
                      {platformLabel(t.platform)}
                    </span>
                  </td>
                  <td style={{ textAlign: 'center' }}>
                    <span className="mono semi" style={{ padding: '2px 10px', borderRadius: 20, background: t.trigger_count > 0 ? 'rgba(108,99,255,0.14)' : 'transparent', color: t.trigger_count > 0 ? '#A5B4FC' : 'var(--text-3)' }}>
                      {fa(t.trigger_count || 0)}
                    </span>
                  </td>
                  <td style={{ textAlign: 'center' }}>
                    <button onClick={() => toggleActive(t)}
                      title={t.is_active ? 'غیرفعال کن' : 'فعال کن'}
                      style={{ width: 36, height: 20, borderRadius: 10, border: 'none', cursor: 'pointer', background: t.is_active ? '#34D399' : 'rgba(255,255,255,0.08)', position: 'relative', transition: 'background .2s', flexShrink: 0 }}>
                      <span style={{ position: 'absolute', top: 2, right: t.is_active ? 2 : 18, width: 16, height: 16, borderRadius: 8, background: '#fff', transition: 'right .2s', display: 'block' }} />
                    </button>
                  </td>
                  <td>
                    <div className="row gap-4">
                      <button className="icon-btn" style={{ width: 28, height: 28 }} onClick={() => openEdit(t)} title="ویرایش">
                        <Icon name="pencil" size={12} color="#A5B4FC" />
                      </button>
                      <button className="icon-btn" style={{ width: 28, height: 28 }} onClick={() => deleteTrigger(t.id, t.keyword)} title="حذف">
                        <Icon name="trash-2" size={12} color="#F87171" />
                      </button>
                    </div>
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      )}

      <Modal open={open} onClose={() => setOpen(false)} title="تریگر جدید" width={560}
        footer={<><Button kind="primary" onClick={submit}>ذخیره تریگر</Button><Button kind="ghost" onClick={() => setOpen(false)}>انصراف</Button></>}
      >
        <div className="col gap-16">
          <div style={{ display: 'flex', gap: 8, padding: '4px', background: 'var(--bg-2)', borderRadius: 12 }}>
            {[
              { id: 'free_course', label: '📦 دوره رایگان', desc: 'ارسال فایل بدون AI' },
              { id: 'script',      label: '🤖 اسکریپت فروش', desc: 'فعال‌سازی اسکریپت AI' },
            ].map(m => (
              <button key={m.id} onClick={() => setMode(m.id)} style={{ flex: 1, padding: '10px 12px', borderRadius: 9, border: 'none', cursor: 'pointer', background: mode === m.id ? 'var(--surface)' : 'transparent', boxShadow: mode === m.id ? '0 1px 6px rgba(0,0,0,0.25)' : 'none', transition: 'all .15s', fontFamily: 'inherit' }}>
                <div className="semi text-sm" style={{ color: mode === m.id ? 'var(--text-1)' : 'var(--text-3)' }}>{m.label}</div>
                <div style={{ fontSize: 10, color: 'var(--text-3)', marginTop: 2 }}>{m.desc}</div>
              </button>
            ))}
          </div>
          <Field label="نام دوره / تریگر">
            <input className="input" value={form.name} onChange={e => setForm({ ...form, name: e.target.value })} placeholder="مثلاً: دوره رایگان برنامه‌نویسی پایه" />
          </Field>
          <Field label="کلمه کلیدی (کدی که کاربر می‌فرستد)">
            <input className="input mono" value={form.keyword} onChange={e => setForm({ ...form, keyword: e.target.value })} placeholder="مثلاً: ۱۴۰۴ یا رایگان" onKeyDown={e => e.key === 'Enter' && submit()} autoFocus />
          </Field>
          {mode === 'free_course' && (
            <>
              <Field label="پیام خوش‌آمد (اختیاری — قبل از فایل‌ها)">
                <textarea className="input" rows={2} value={form.welcome_msg} onChange={e => setForm({ ...form, welcome_msg: e.target.value })} placeholder="سلام 🙏 فایل‌های دوره رایگان رو برات فرستادم 👇" style={{ resize: 'vertical', fontFamily: 'inherit', fontSize: 13 }} />
              </Field>
              <Field label={`فایل‌های دوره (${selectedFiles.length} انتخاب شده)`}>
                <FilePicker fileIds={form.file_ids} onChange={ids => setForm(f => ({ ...f, file_ids: ids }))} onUpload={() => setLibOpen(true)} />
              </Field>
              <Field label="پیام پیگیری (اختیاری — بعد از فایل‌ها)">
                <textarea className="input" rows={2} value={form.followup_msg} onChange={e => setForm({ ...form, followup_msg: e.target.value })} placeholder="برای ادامه، عدد ۲ رو بفرست 👇" style={{ resize: 'vertical', fontFamily: 'inherit', fontSize: 13 }} />
              </Field>
            </>
          )}
          {mode === 'script' && (
            <Field label="اسکریپت متصل">
              {scripts.length === 0 ? (
                <div style={{ padding: '12px', borderRadius: 9, background: 'rgba(239,68,68,0.08)', color: '#F87171', fontSize: 12 }}>هیچ اسکریپتی موجود نیست.</div>
              ) : (
                <select className="select" value={form.script_id} onChange={e => setForm({ ...form, script_id: e.target.value })}>
                  {scripts.map(s => <option key={s.id} value={s.id}>{s.name}</option>)}
                </select>
              )}
            </Field>
          )}
          <Field label="پلتفرم">
            <select className="select" value={form.platform} onChange={e => setForm({ ...form, platform: e.target.value })}>
              <option value="all">همه پلتفرم‌ها</option>
              <option value="telegram">تلگرام</option>
              <option value="bale">بله</option>
            </select>
          </Field>
          {form.keyword && (
            <div style={{ padding: '10px 14px', background: mode === 'free_course' ? 'rgba(16,185,129,0.06)' : 'rgba(108,99,255,0.06)', borderRadius: 10, borderRight: `3px solid ${mode === 'free_course' ? '#34D399' : 'var(--primary)'}` }}>
              <div className="text-xs" style={{ color: mode === 'free_course' ? '#34D399' : 'var(--primary)', lineHeight: 1.8 }}>
                {mode === 'free_course'
                  ? `✓ وقتی کاربر «${form.keyword}» بفرستد، ${selectedFiles.length} فایل دوره «${form.name || form.keyword}» بدون هوش مصنوعی ارسال می‌شود`
                  : `✓ وقتی کاربر «${form.keyword}» بفرستد، اسکریپت «${scripts.find(s => s.id === form.script_id)?.name || ''}» فعال می‌شود`}
              </div>
            </div>
          )}
        </div>
      </Modal>

      <Modal open={!!editId} onClose={() => setEditId(null)} title={`ویرایش: ${editTrigger?.trigger_name || editTrigger?.keyword || ''}`} width={520}
        footer={<><Button kind="primary" onClick={saveEdit}>ذخیره تغییرات</Button><Button kind="ghost" onClick={() => setEditId(null)}>انصراف</Button></>}
      >
        {editTrigger && (
          <div className="col gap-16">
            <Field label="کلمه کلیدی">
              <input className="input mono" value={eform.keyword} onChange={e => setEform(f => ({ ...f, keyword: e.target.value }))} placeholder="مثلاً: ۱۴۰۵ یا رایگان" autoFocus />
              <div className="text-xs text-3 mt-4">کاربر وقتی این کلمه رو بفرسته تریگر فعال می‌شه</div>
            </Field>
            <Field label="نام نمایشی">
              <input className="input" value={eform.name} onChange={e => setEform(f => ({ ...f, name: e.target.value }))} placeholder={eform.keyword || editTrigger.keyword} />
            </Field>
            {editTrigger.is_free_course ? (
              <>
                <Field label="پیام خوش‌آمد (قبل از فایل‌ها)">
                  <textarea className="input" rows={2} value={eform.welcome_msg} onChange={e => setEform(f => ({ ...f, welcome_msg: e.target.value }))} placeholder="سلام 🙏 فایل‌های دوره رایگان رو برات فرستادم 👇" style={{ resize: 'vertical', fontFamily: 'inherit', fontSize: 13 }} />
                </Field>
                <Field label={`فایل‌های دوره (${eform.file_ids.length} فایل)`}>
                  <FilePicker fileIds={eform.file_ids} onChange={ids => setEform(f => ({ ...f, file_ids: ids }))} onUpload={() => setElibOpen(true)} isEdit={true} />
                </Field>
                <Field label="پیام پیگیری (بعد از فایل‌ها)">
                  <textarea className="input" rows={2} value={eform.followup_msg} onChange={e => setEform(f => ({ ...f, followup_msg: e.target.value }))} placeholder="برای ادامه، عدد ۲ رو بفرست 👇" style={{ resize: 'vertical', fontFamily: 'inherit', fontSize: 13 }} />
                </Field>
              </>
            ) : (
              <Field label="اسکریپت متصل">
                {scripts.length === 0 ? (
                  <div style={{ padding: '12px', borderRadius: 9, background: 'rgba(239,68,68,0.08)', color: '#F87171', fontSize: 12 }}>هیچ اسکریپتی موجود نیست.</div>
                ) : (
                  <select className="select" value={eform.script_id} onChange={e => setEform(f => ({ ...f, script_id: e.target.value }))}>
                    <option value="">— انتخاب اسکریپت —</option>
                    {scripts.map(s => <option key={s.id} value={s.id}>{s.name}</option>)}
                  </select>
                )}
                {eform.script_id && (
                  <div style={{ marginTop: 6, fontSize: 11, color: '#34D399' }}>
                    ✓ اسکریپت انتخاب‌شده: <strong>{scripts.find(s => s.id === eform.script_id)?.name || eform.script_id}</strong>
                  </div>
                )}
              </Field>
            )}
          </div>
        )}
      </Modal>

      <LibraryPicker open={libOpen} onClose={() => setLibOpen(false)} fileIds={form.file_ids} onChange={ids => setForm(f => ({ ...f, file_ids: ids }))} />
      <LibraryPicker open={elibOpen} onClose={() => setElibOpen(false)} fileIds={eform.file_ids} onChange={ids => setEform(f => ({ ...f, file_ids: ids }))} />
    </div>
  );
};


// ─── اسکریپت‌ها ──────────────────────────────────────────────────────────
// Scripts page (multiple scripts × 4 tabs each)
const Scripts = () => {
  const { Icon, Button, Toggle, Modal, Field, useToast, SlidePanel } = window.SB_UI;
  const { fa } = window.SB_DATA;
  const [scripts, setScripts] = useState([]);
  const [activeId, setActiveId] = useState(null);
  const [tab, setTab] = window.useStickyState('tab_scripts', 'prompt');
  const [addOpen, setAddOpen] = useState(false);
  const [chatOpen, setChatOpen] = useState(false);
  const [newName, setNewName] = useState('');
  const [newDesc, setNewDesc] = useState('');
  const [promptText, setPromptText] = useState('');
  const [saving, setSaving] = useState(false);
  const [distPrompt, setDistPrompt]     = useState('');     // متن هاردکد منطق توزیع مغز اصلی
  const [distUnlocked, setDistUnlocked] = useState(false);  // بعد از وارد کردن رمز درست
  const [distPassword, setDistPassword] = useState('');
  const [distSaving, setDistSaving]     = useState(false);
  const toast = useToast();
  const active = scripts.find(s => s.id === activeId);

  const token = localStorage.getItem(window.TOKEN_KEY);
  const headers = { 'Content-Type': 'application/json', Authorization: `Bearer ${token}` };

  const load = () => {
    fetch('/api/scripts', { headers }).then(r => r.json()).then(d => {
      if (d.success && d.data?.scripts?.length) {
        setScripts(d.data.scripts);
        if (!activeId) {
          setActiveId(d.data.scripts[0].id);
          setPromptText(d.data.scripts[0].system_prompt || '');
        }
      }
    });
  };

  useEffect(() => { load(); }, []);

  useEffect(() => {
    const s = scripts.find(x => x.id === activeId);
    if (s) {
      setPromptText(s.system_prompt || '');
      setDistPrompt(s.distribution_prompt || '');
      setDistUnlocked(false);
      setDistPassword('');
      loadMap(s.id);
      try { setMediaFiles(JSON.parse(s.media_files || '[]')); } catch { setMediaFiles([]); }
      try { setScriptChannels(JSON.parse(s.channels || '["all"]')); } catch { setScriptChannels(['all']); }
      setScriptWorkHours(s.work_hours || '');
    }
  }, [activeId]);

  const [mapData,     setMapData]     = useState([]);
  const [mapBuilding, setMapBuilding] = useState(false);
  const [scriptChannels, setScriptChannels] = useState(['all']);
  const [scriptWorkHours, setScriptWorkHours] = useState('');

  // ─── رسانه‌ها ─────────────────────────────────────────────
  const [mediaFiles,  setMediaFiles]  = useState([]);  // [{id,name,hint}]
  const [libFiles,    setLibFiles]    = useState([]);  // همه فایل‌های کتابخانه
  const [mediaSaving, setMediaSaving] = useState(false);

  const loadLibFiles = () => {
    fetch('/api/library', { headers }).then(r => r.json()).then(d => {
      if (d.success) setLibFiles(d.data.files || []);
    });
  };

  const PLATFORMS = [
    { id: 'telegram',  label: 'تلگرام',    icon: '✈️' },
    { id: 'bale',      label: 'بله',        icon: '🟢' },
    { id: 'rubika',    label: 'روبیکا',     icon: '🔵' },
    { id: 'instagram', label: 'اینستاگرام', icon: '📸' },
  ];

  const saveChannels = () => {
    if (!activeId) return;
    fetch(`/api/scripts/${activeId}`, {
      method: 'PUT', headers,
      body: JSON.stringify({ channels: JSON.stringify(scriptChannels), work_hours: scriptWorkHours })
    }).then(r => r.json()).then(d => {
      if (d.success) {
        setScripts(prev => prev.map(s => s.id === activeId ? { ...s, channels: JSON.stringify(scriptChannels), work_hours: scriptWorkHours } : s));
        toast('تنظیمات کانال ذخیره شد ✓', 'success');
      } else toast('خطا در ذخیره', 'error');
    });
  };

  const toggleChannel = (id) => {
    if (id === 'all') { setScriptChannels(['all']); return; }
    setScriptChannels(prev => {
      const without = prev.filter(c => c !== 'all');
      return without.includes(id) ? without.filter(c => c !== id) : [...without, id];
    });
  };

  const saveMediaFiles = (dataOverride) => {
    if (!activeId) return;
    setMediaSaving(true);
    const payload = dataOverride !== undefined ? dataOverride : mediaFiles;
    fetch(`/api/scripts/${activeId}`, {
      method: 'PUT', headers,
      body: JSON.stringify({ media_files: payload })
    }).then(r => r.json()).then(d => {
      if (d.success) toast('فایل‌های رسانه ذخیره شدن ✓', 'success');
      else toast('خطا در ذخیره', 'error');
    }).finally(() => setMediaSaving(false));
  };

  const loadMap = (id) => {
    fetch(`/api/scripts/${id}/map`, { headers }).then(r => r.json()).then(d => {
      if (d.success) {
        const states = d.data.states || [];
        states.forEach(s => { try { s.data_collect = JSON.parse(s.data_collect); } catch { s.data_collect = []; } });
        setMapData(states);
      }
    });
  };

  const buildMap = async () => {
    if (!activeId) return;
    setMapBuilding(true);
    try {
      const r = await fetch(`/api/scripts/${activeId}/build-map`, { method: 'POST', headers });
      const d = await r.json();
      if (d.success) {
        const states = d.data.states || [];
        states.forEach(s => { try { s.data_collect = JSON.parse(s.data_collect); } catch { s.data_collect = []; } });
        setMapData(states);
        setTab('map');
        toast('نقشه مراحل ساخته شد ✅', 'success');
      } else {
        toast('خطا: ' + d.message, 'error');
      }
    } catch (e) {
      toast('خطا در ارتباط با سرور', 'error');
    } finally {
      setMapBuilding(false);
    }
  };

  const [rulesOpen, setRulesOpen] = useState(false);

  const tabs = [
    { id: 'prompt',     name: 'متن پرامپت',   icon: 'file-text' },
    { id: 'channels',   name: 'کانال‌ها',       icon: 'radio' },
    { id: 'map',        name: 'نقشه مراحل',    icon: 'git-branch' },
    { id: 'media',      name: 'رسانه‌ها',       icon: 'paperclip' },
  ];

  const toggleActive = (id, val) => {
    fetch(`/api/scripts/${id}`, { method: 'PUT', headers, body: JSON.stringify({ is_active: val ? 1 : 0 }) })
      .then(r => r.json()).then(d => {
        if (d.success) setScripts(prev => prev.map(s => s.id === id ? { ...s, is_active: val ? 1 : 0 } : s));
      });
  };

  const deleteScript = (id, name) => {
    if (!confirm(`اسکریپت «${name}» حذف شود؟`)) return;
    fetch(`/api/scripts/${id}`, { method: 'DELETE', headers }).then(() => {
      setScripts(prev => prev.filter(s => s.id !== id));
      if (activeId === id) {
        const remaining = scripts.filter(s => s.id !== id);
        if (remaining.length > 0) setActiveId(remaining[0].id);
      }
      toast('اسکریپت حذف شد', 'success');
    });
  };

  const savePrompt = () => {
    if (!activeId) return;
    setSaving(true);
    fetch(`/api/scripts/${activeId}`, {
      method: 'PUT', headers,
      body: JSON.stringify({ system_prompt: promptText })
    }).then(r => r.json()).then(d => {
      if (d.success) {
        setScripts(prev => prev.map(s => s.id === activeId
          ? { ...s, system_prompt: promptText }
          : s
        ));
        toast('اسکریپت ذخیره شد', 'success');
      } else {
        toast('خطا در ذخیره', 'error');
      }
    }).finally(() => setSaving(false));
  };

  const create = (thenOpenChat = false) => {
    if (!newName.trim()) return toast('نام اسکریپت الزامیه', 'error');
    const initialPrompt = `اسکریپت ${newName.trim()}`;
    fetch('/api/scripts', { method: 'POST', headers, body: JSON.stringify({ name: newName, system_prompt: initialPrompt }) })
      .then(r => r.json()).then(d => {
        if (d.success) {
          setAddOpen(false);
          setNewName('');
          setNewDesc('');
          fetch('/api/scripts', { headers }).then(r => r.json()).then(ld => {
            if (ld.success && ld.data?.scripts?.length) {
              setScripts(ld.data.scripts);
              const created = ld.data.scripts.find(s => s.id === d.data.id);
              if (created) {
                setActiveId(created.id);
                setPromptText(created.system_prompt || '');
                if (thenOpenChat) setTimeout(() => setChatOpen(true), 100);
              }
            }
          });
          if (!thenOpenChat) toast('اسکریپت ساخته شد', 'success');
        } else {
          toast(d.message || 'خطا در ساخت اسکریپت', 'error');
        }
      });
  };

  return (
    <div>
      {/* Script list */}
      <div className="row gap-12" style={{ overflowX: 'auto', paddingBottom: 4 }}>
        {scripts.map(s => {
          const on = activeId === s.id;
          return (
            <div key={s.id}
              className="card card-hover"
              style={{
                padding: 14, minWidth: 240, cursor: 'pointer',
                borderColor: on ? 'var(--primary)' : 'var(--border-soft)',
                background: on ? 'linear-gradient(180deg, rgba(108,99,255,0.16), rgba(108,99,255,0.04))' : undefined,
                position: 'relative', opacity: s.is_active ? 1 : 0.5,
              }}
              onClick={() => setActiveId(s.id)}>
              {on && <span style={{ position: 'absolute', top: 10, left: 10, width: 8, height: 8, borderRadius: 50, background: 'var(--primary-2)', boxShadow: '0 0 10px var(--primary-glow)' }} />}
              <div className="row between" style={{ alignItems: 'flex-start' }}>
                <div style={{ flex: 1, minWidth: 0 }}>
                  <div className="row gap-6">
                    <div className="semi text-sm" style={{ overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{s.name}</div>
                  </div>
                  <div className="text-xs text-3 mt-4">{s.updated_at ? s.updated_at.slice(0, 16) : ''}</div>
                </div>
                <div className="row gap-4" onClick={e => e.stopPropagation()}>
                  <Toggle on={!!s.is_active} onChange={(v) => toggleActive(s.id, v)} />
                  {s.is_default !== 1 && (
                    <button
                      onClick={() => deleteScript(s.id, s.name)}
                      className="icon-btn"
                      style={{ width: 24, height: 24, color: '#F87171' }}
                      title="حذف">
                      <Icon name="trash-2" size={12} />
                    </button>
                  )}
                </div>
              </div>
            </div>
          );
        })}
        <div onClick={() => setAddOpen(true)}
          className="card card-hover"
          style={{ padding: 14, minWidth: 180, cursor: 'pointer', borderStyle: 'dashed', display: 'grid', placeItems: 'center', color: 'var(--text-3)' }}>
          <div style={{ textAlign: 'center' }}>
            <Icon name="plus" size={22} />
            <div className="text-sm semi mt-8">اسکریپت جدید</div>
          </div>
        </div>
      </div>

      {/* Active script header */}
      {active && (
        <div className="card mt-16" style={{ padding: '18px 22px' }}>
          <div className="row between">
            <div>
              <div className="row gap-12">
                <div style={{ width: 44, height: 44, borderRadius: 12, background: 'linear-gradient(135deg, var(--primary), #4F46E5)', display: 'grid', placeItems: 'center' }}>
                  <Icon name="file-text" size={20} color="#fff" />
                </div>
                <div>
                  <div className="bold" style={{ fontSize: 16 }}>{active.name}</div>
                  <div className="text-xs text-3 mt-4">{active.updated_at ? active.updated_at.slice(0, 16) : ''}</div>
                </div>
              </div>
            </div>
            <div className="row gap-8">
              <Button kind="ghost" icon="bot" onClick={() => setChatOpen(true)}>ساخت با AI</Button>
              <button
                onClick={buildMap}
                disabled={mapBuilding}
                style={{
                  padding: '8px 16px', borderRadius: 10, border: 'none', cursor: mapBuilding ? 'wait' : 'pointer',
                  background: mapBuilding ? 'rgba(245,158,11,0.15)' : 'rgba(245,158,11,0.12)',
                  color: '#FBBF24', fontSize: 13, fontFamily: 'inherit', display: 'flex', alignItems: 'center', gap: 6,
                  transition: 'all .2s',
                }}>
                {mapBuilding
                  ? <><span style={{ animation: 'spin 1s linear infinite', display:'inline-block' }}>⟳</span> در حال ساخت نقشه...</>
                  : <>🗺️ ساخت نقشه</>
                }
              </button>
              <Button kind="primary" icon="save" onClick={savePrompt}>{saving ? 'در حال ذخیره...' : 'ذخیره تغییرات'}</Button>
            </div>
          </div>
        </div>
      )}

      {/* Tabs */}
      {!active && (
        <div className="text-sm text-3 mt-24" style={{ textAlign: 'center', padding: 40 }}>در حال بارگذاری...</div>
      )}
      {active && (
        <React.Fragment>
          <div className="row between mt-24" style={{ alignItems: 'center' }}>
            <div className="tabs">
              {tabs.map(t => (
                <button key={t.id} className={`tab ${tab === t.id ? 'active' : ''}`} onClick={() => setTab(t.id)}>
                  <Icon name={t.icon} size={13} />&nbsp;&nbsp;{t.name}
                </button>
              ))}
            </div>
            <button
              onClick={() => setRulesOpen(true)}
              className="icon-btn"
              title="قوانین کلی"
              style={{ width: 32, height: 32, flexShrink: 0 }}>
              <Icon name="settings" size={16} />
            </button>
          </div>

          {rulesOpen && (
            <div onClick={() => setRulesOpen(false)} style={{
              position: 'fixed', inset: 0, zIndex: 1000,
              background: 'rgba(0,0,0,0.6)', display: 'flex', alignItems: 'center', justifyContent: 'center',
            }}>
              <div onClick={e => e.stopPropagation()} className="card" style={{
                width: 560, maxHeight: '80vh', overflowY: 'auto', padding: 20,
              }}>
                <div className="row between" style={{ alignItems: 'center', marginBottom: 12 }}>
                  <div className="bold" style={{ fontSize: 15 }}>⚖️ قوانین کلی</div>
                  <button onClick={() => setRulesOpen(false)} className="icon-btn" style={{ width: 28, height: 28 }}>
                    <Icon name="x" size={14} />
                  </button>
                </div>
                <GlobalRulesTab headers={headers} toast={toast} />
              </div>
            </div>
          )}

          <div className="mt-16">
            {tab === 'prompt' && (
  <div className="col gap-16">
              {active && active.is_default === 1 && (
                <div style={{ border: '1px solid rgba(251,191,36,0.3)', borderRadius: 10, overflow: 'hidden' }}>
                  <div style={{ padding: '8px 16px', background: 'rgba(251,191,36,0.07)', display: 'flex', alignItems: 'center', gap: 6 }}>
                    <span style={{ fontSize: 13 }}>{distUnlocked ? '🔓' : '🔒'}</span>
                    <span style={{ color: '#FCD34D', fontSize: 12, fontWeight: 700, flex: 1 }}>منطق اصلی توزیع — همیشه بالای متن پایین قرار می‌گیرد</span>
                    {!distUnlocked && <span style={{ color: 'var(--text-3)', fontSize: 11 }}>برای ویرایش رمز عبور لازم است</span>}
                  </div>
                  <textarea
                    value={distPrompt}
                    onChange={e => setDistPrompt(e.target.value)}
                    readOnly={!distUnlocked}
                    style={{
                      width: '100%', minHeight: 220, background: distUnlocked ? 'rgba(251,191,36,0.04)' : 'transparent',
                      border: 'none', borderTop: '1px solid rgba(251,191,36,0.15)',
                      padding: '14px 16px', color: distUnlocked ? 'var(--text-1)' : 'var(--text-3)', fontSize: 13, lineHeight: 1.8,
                      resize: 'vertical', outline: 'none', direction: 'rtl', fontFamily: 'Vazirmatn, sans-serif',
                      boxSizing: 'border-box',
                    }}
                  />
                  <div style={{ padding: '8px 16px', background: 'rgba(251,191,36,0.07)', display: 'flex', alignItems: 'center', gap: 8 }}>
                    {!distUnlocked ? (
                      <>
                        <input
                          type="password"
                          value={distPassword}
                          onChange={e => setDistPassword(e.target.value)}
                          placeholder="رمز عبور ادمین"
                          className="input"
                          style={{ flex: 1, fontSize: 12 }}
                        />
                        <Button kind="ghost" onClick={async () => {
                          const r = await fetch('/api/auth/verify-password', { method: 'POST', headers, body: JSON.stringify({ password: distPassword }) }).then(r => r.json());
                          if (r.success) { setDistUnlocked(true); toast('باز شد — حالا می‌تونی ویرایش کنی', 'success'); }
                          else toast(r.error || 'رمز اشتباه است', 'error');
                        }}>باز کردن قفل</Button>
                      </>
                    ) : (
                      <Button kind="primary" disabled={distSaving} onClick={async () => {
                        setDistSaving(true);
                        const r = await fetch(`/api/scripts/${activeId}/distribution`, { method: 'PUT', headers, body: JSON.stringify({ distribution_prompt: distPrompt, password: distPassword }) }).then(r => r.json());
                        setDistSaving(false);
                        if (r.success) {
                          setScripts(prev => prev.map(s => s.id === activeId ? { ...s, distribution_prompt: distPrompt } : s));
                          toast('منطق توزیع ذخیره شد', 'success'); setDistUnlocked(false); setDistPassword('');
                        } else toast(r.error || 'خطا', 'error');
                      }}>{distSaving ? 'در حال ذخیره...' : 'ذخیره منطق توزیع'}</Button>
                    )}
                  </div>
                </div>
              )}
  <div className="card" style={{ padding: 0, overflow: 'hidden' }}>
                {/* هدر بالای textarea */}
                <div style={{ padding: '10px 16px', background: 'rgba(255,255,255,0.03)', borderBottom: '1px solid var(--border-soft)' }} className="row between gap-12">
                  <div className="row gap-8" style={{ alignItems: 'center' }}>
                    {active && active.is_default === 1 && <span className="text-xs text-3">متن آزاد ادمین — زیر بخش بالا اضافه می‌شه</span>}
                  </div>
                  <span className="text-xs text-3 mono">{promptText.length} کاراکتر</span>
                </div>
                <textarea
                  value={promptText}
                  onChange={e => setPromptText(e.target.value)}
                  style={{
                    width: '100%', minHeight: 520, background: 'transparent', border: 'none',
                    padding: '16px 20px', color: 'var(--text-1)', fontSize: 13, lineHeight: 1.8,
                    resize: 'vertical', outline: 'none', direction: 'rtl', fontFamily: 'Vazirmatn, sans-serif',
                    boxSizing: 'border-box',
                  }}
                />
              </div>
  </div>
            )}
            {tab === 'channels' && (
              <div className="card col gap-20">
                <div>
                  <div className="bold mb-8">کانال‌های فعال</div>
                  <div className="text-xs text-3 mb-16">این اسکریپت فقط روی کانال‌های انتخاب‌شده پاسخ می‌دهد</div>
                  <div className="col gap-10">
                    <label className="row gap-12" style={{ cursor: 'pointer', padding: '10px 14px', borderRadius: 10, border: `1px solid ${scriptChannels.includes('all') ? 'var(--primary)' : 'var(--border-soft)'}`, background: scriptChannels.includes('all') ? 'rgba(108,99,255,0.08)' : 'transparent' }}>
                      <input type="checkbox" checked={scriptChannels.includes('all')} onChange={() => toggleChannel('all')} style={{ accentColor: 'var(--primary)', width: 16, height: 16 }} />
                      <span className="semi">🌐 همه کانال‌ها</span>
                    </label>
                    {PLATFORMS.map(p => (
                      <label key={p.id} className="row gap-12" style={{ cursor: 'pointer', padding: '10px 14px', borderRadius: 10, border: `1px solid ${scriptChannels.includes(p.id) ? 'var(--primary)' : 'var(--border-soft)'}`, background: scriptChannels.includes(p.id) ? 'rgba(108,99,255,0.08)' : 'transparent', opacity: scriptChannels.includes('all') ? 0.4 : 1 }}>
                        <input type="checkbox" checked={scriptChannels.includes(p.id)} onChange={() => toggleChannel(p.id)} disabled={scriptChannels.includes('all')} style={{ accentColor: 'var(--primary)', width: 16, height: 16 }} />
                        <span className="semi">{p.icon} {p.label}</span>
                      </label>
                    ))}
                  </div>
                </div>
                <div className="divider" />
                <div>
                  <div className="bold mb-8">ساعت کاری</div>
                  <div className="text-xs text-3 mb-12">خارج از این بازه سکوت کامل (مثال: 09:00-22:00)</div>
                  <div className="row gap-10" style={{ alignItems: 'center' }}>
                    <input className="input" placeholder="09:00-22:00" value={scriptWorkHours} onChange={e => setScriptWorkHours(e.target.value)} style={{ width: 160 }} />
                    <span className="text-xs text-3">{!scriptWorkHours ? '(همیشه فعال)' : ''}</span>
                    <button className="pill" onClick={() => setScriptWorkHours('')}>پاک کن</button>
                  </div>
                </div>
                <div style={{ display: 'flex', justifyContent: 'flex-end' }}>
                  <Button kind="primary" icon="save" onClick={saveChannels}>ذخیره تنظیمات</Button>
                </div>
              </div>
            )}
            {tab === 'map'   && <ScriptMapTab states={mapData} onBuild={buildMap} building={mapBuilding} scriptId={activeId} headers={headers} toast={toast} onStatesUpdated={setMapData} onPromptUpdated={(newPrompt) => { setPromptText(newPrompt); setScripts(prev => prev.map(s => s.id === activeId ? { ...s, system_prompt: newPrompt } : s)); }} />}
            {tab === 'media' && <MediaFilesTab mediaFiles={mediaFiles} setMediaFiles={setMediaFiles} libFiles={libFiles} loadLibFiles={loadLibFiles} onSave={saveMediaFiles} saving={mediaSaving} scriptId={activeId} headers={headers} toast={toast} />}
          </div>
        </React.Fragment>
      )}

      {chatOpen && (
        <ScriptBuilderChat
          scriptId={activeId}
          currentScript={promptText}
          onApply={(newScript) => { setPromptText(newScript); setScripts(prev => prev.map(s => s.id === activeId ? { ...s, system_prompt: newScript } : s)); }}
          onClose={() => setChatOpen(false)}
          headers={{ 'Content-Type': 'application/json', Authorization: `Bearer ${localStorage.getItem(window.TOKEN_KEY)}` }}
        />
      )}

      <Modal open={addOpen} onClose={() => setAddOpen(false)} title="ساخت اسکریپت جدید" footer={
        <>
          <Button kind="primary" icon="bot" onClick={() => create(true)}>ساخت با AI</Button>
          <Button kind="secondary" onClick={() => create(false)}>ساخت خالی</Button>
          <Button kind="ghost" onClick={() => setAddOpen(false)}>انصراف</Button>
        </>
      }>
        <div className="col gap-16">
          <Field label="نام اسکریپت">
            <input
              className="input"
              placeholder="مثلا اسکریپت کمپین تابستان"
              value={newName}
              onChange={e => setNewName(e.target.value)}
              onKeyDown={e => e.key === 'Enter' && create(true)}
            />
          </Field>
          <div style={{ padding: '12px 16px', background: 'rgba(108,99,255,0.08)', borderRadius: 10, borderRight: '3px solid var(--primary)' }}>
            <div className="text-sm" style={{ color: 'var(--text-2)', lineHeight: 1.8 }}>
              با <strong>ساخت با AI</strong> یه چت باز می‌شه — باهاش حرف بزن تا اسکریپتت رو از صفر بسازه.
            </div>
          </div>
        </div>
      </Modal>
    </div>
  );
};


// ─── Script Builder Chat ──────────────────────────────────
const ScriptBuilderChat = ({ scriptId, currentScript, onApply, onClose, headers }) => {
  const { Icon, Button } = window.SB_UI;
  const [messages, setMessages] = useState([
    { role: 'assistant', content: 'سلام! من اینجام تا کمک کنم اسکریپتت رو بسازیم یا بهتر کنیم.\n\nچی می‌خوای تغییر بدی یا بسازی؟' }
  ]);
  const [input, setInput] = useState('');
  const [loading, setLoading] = useState(false);
  const [preview, setPreview] = useState(currentScript);
  const [applied, setApplied] = useState(false);
  const [copied, setCopied] = useState(false);
  const bottomRef = useRef(null);

  useEffect(() => {
    bottomRef.current?.scrollIntoView({ behavior: 'smooth' });
  }, [messages]);

  const send = async () => {
    if (!input.trim() || loading) return;
    const userMsg = { role: 'user', content: input };
    const newMessages = [...messages, userMsg];
    setMessages(newMessages);
    setInput('');
    setLoading(true);
    setApplied(false);

    try {
      const res = await fetch('/api/scripts/build-chat', {
        method: 'POST', headers,
        body: JSON.stringify({
          messages: newMessages.map(m => ({ role: m.role, content: m.content })),
          currentScript: preview,
        }),
      });
      const d = await res.json();
      if (d.success) {
        const reply = d.data.reply;
        const newScript = d.data.suggestedScript;
        setMessages(prev => [...prev, {
          role: 'assistant',
          content: reply,
          hasScript: !!newScript,
        }]);
        if (newScript) {
          setPreview(newScript);
        }
      }
    } finally {
      setLoading(false);
    }
  };

  const handleApply = () => {
    onApply(preview);        // promptText رو در parent آپدیت کن
    setApplied(true);        // نشانگر "اعمال شد" نشون بده
  };

  const handleCopy = () => {
    // روش اول: clipboard API
    if (navigator.clipboard && navigator.clipboard.writeText) {
      navigator.clipboard.writeText(preview).then(() => {
        setCopied(true);
        setTimeout(() => setCopied(false), 2000);
      }).catch(() => fallbackCopy());
    } else {
      fallbackCopy();
    }
  };

  const fallbackCopy = () => {
    const ta = document.createElement('textarea');
    ta.value = preview;
    ta.style.position = 'fixed';
    ta.style.opacity = '0';
    document.body.appendChild(ta);
    ta.focus();
    ta.select();
    document.execCommand('copy');
    document.body.removeChild(ta);
    setCopied(true);
    setTimeout(() => setCopied(false), 2000);
  };

  return (
    <div style={{
      position: 'fixed', inset: 0, zIndex: 1000,
      background: 'rgba(0,0,0,0.85)', display: 'flex', flexDirection: 'row-reverse', alignItems: 'stretch',
    }}>
      <div style={{ flex: 1, display: 'flex', flexDirection: 'row-reverse', maxWidth: '100%', overflow: 'hidden' }}>

        {/* چت */}
        <div style={{ width: 420, flexShrink: 0, display: 'flex', flexDirection: 'column', background: '#13132a' }}>
          {/* هدر */}
          <div style={{ padding: '14px 18px', borderBottom: '1px solid var(--border-soft)', display: 'flex', alignItems: 'center', gap: 12 }}>
            <div style={{ width: 34, height: 34, borderRadius: 10, background: 'linear-gradient(135deg,#6C63FF,#4F46E5)', display: 'grid', placeItems: 'center' }}>
              <Icon name="bot" size={16} color="#fff" />
            </div>
            <div style={{ flex: 1 }}>
              <div className="semi" style={{ fontSize: 14 }}>دستیار ساخت اسکریپت</div>
              <div className="text-xs text-3">باهاش حرف بزن، اسکریپت می‌سازه</div>
            </div>
            <button className="icon-btn" onClick={onClose} style={{ width: 30, height: 30 }}><Icon name="x" size={14} /></button>
          </div>

          {/* پیام‌ها */}
          <div style={{ flex: 1, overflowY: 'auto', padding: '16px 14px', display: 'flex', flexDirection: 'column', gap: 12 }}>
            {messages.map((m, i) => (
              <div key={i} style={{ display: 'flex', justifyContent: m.role === 'user' ? 'flex-start' : 'flex-end' }}>
                <div style={{
                  maxWidth: '85%', padding: '10px 14px', borderRadius: m.role === 'user' ? '12px 12px 12px 2px' : '12px 12px 2px 12px',
                  background: m.role === 'user' ? 'rgba(255,255,255,0.07)' : 'rgba(108,99,255,0.2)',
                  fontSize: 13, lineHeight: 1.7, whiteSpace: 'pre-wrap', direction: 'rtl',
                }}>
                  {m.content}
                  {m.hasScript && (
                    <div style={{ marginTop: 10, paddingTop: 10, borderTop: '1px solid rgba(255,255,255,0.1)' }}>
                      <div style={{ fontSize: 11, color: '#34D399' }}>✓ اسکریپت پیشنهادی در پنل راست آپدیت شد</div>
                    </div>
                  )}
                </div>
              </div>
            ))}
            {loading && (
              <div style={{ display: 'flex', justifyContent: 'flex-end' }}>
                <div style={{ padding: '10px 16px', borderRadius: '12px 12px 2px 12px', background: 'rgba(108,99,255,0.2)', fontSize: 13, color: 'var(--text-3)' }}>
                  در حال فکر کردن...
                </div>
              </div>
            )}
            <div ref={bottomRef} />
          </div>

          {/* ورودی */}
          <div style={{ padding: '12px 14px', borderTop: '1px solid var(--border-soft)', display: 'flex', gap: 8 }}>
            <textarea
              value={input}
              onChange={e => setInput(e.target.value)}
              onKeyDown={e => { if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); send(); } }}
              placeholder="بنویس چی می‌خوای... (Enter برای ارسال)"
              style={{
                flex: 1, background: 'rgba(255,255,255,0.05)', border: '1px solid rgba(255,255,255,0.1)',
                borderRadius: 10, padding: '9px 12px', color: 'var(--text-1)', fontSize: 13,
                resize: 'none', outline: 'none', direction: 'rtl', fontFamily: 'Vazirmatn, sans-serif', rows: 2,
              }}
              rows={2}
            />
            <button
              onClick={send} disabled={loading || !input.trim()}
              style={{ width: 40, borderRadius: 10, border: 'none', background: loading ? 'rgba(108,99,255,0.3)' : 'var(--primary)', color: '#fff', cursor: 'pointer' }}>
              <Icon name="send" size={15} />
            </button>
          </div>
        </div>

        {/* پیش‌نمایش اسکریپت */}
        <div style={{ flex: 1, display: 'flex', flexDirection: 'column', background: '#0c0c1a', borderRight: '1px solid rgba(255,255,255,0.08)' }}>
          {/* هدر */}
          <div style={{ padding: '14px 18px', borderBottom: '1px solid var(--border-soft)', display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 12 }}>
            <div>
              <div className="semi" style={{ fontSize: 14 }}>پیش‌نمایش اسکریپت</div>
              <div className="text-xs text-3">{preview.length} کاراکتر</div>
            </div>
            <div className="row gap-8">
              <button onClick={handleCopy}
                style={{ padding: '6px 14px', borderRadius: 8, border: 'none', cursor: 'pointer', fontSize: 12,
                  background: copied ? 'rgba(52,211,153,0.2)' : 'rgba(255,255,255,0.08)',
                  color: copied ? '#34D399' : 'var(--text-2)', transition: 'all 0.2s' }}>
                {copied ? '✓ کپی شد' : '📋 کپی'}
              </button>
              <button onClick={handleApply}
                style={{ padding: '6px 16px', borderRadius: 8, border: 'none', cursor: 'pointer', fontSize: 12, fontWeight: 600,
                  background: applied ? 'rgba(52,211,153,0.3)' : 'rgba(52,211,153,0.15)',
                  color: '#34D399', transition: 'all 0.2s' }}>
                {applied ? '✓ اعمال شد — ذخیره کنید' : '↩ اعمال روی اسکریپت'}
              </button>
            </div>
          </div>

          {/* نشانگر اعمال شدن */}
          {applied && (
            <div style={{ padding: '8px 18px', background: 'rgba(52,211,153,0.08)', borderBottom: '1px solid rgba(52,211,153,0.2)', display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
              <span className="text-xs" style={{ color: '#34D399' }}>✓ اسکریپت اعمال شد. برای ذخیره دائمی دکمه «ذخیره تغییرات» رو بزن.</span>
              <button onClick={onClose} style={{ padding: '3px 10px', borderRadius: 6, border: 'none', background: 'rgba(52,211,153,0.2)', color: '#34D399', fontSize: 11, cursor: 'pointer' }}>بستن و ذخیره</button>
            </div>
          )}

          <textarea
            value={preview}
            onChange={e => { setPreview(e.target.value); setApplied(false); }}
            style={{
              flex: 1, background: 'transparent', border: 'none', padding: '16px 20px',
              color: 'var(--text-1)', fontSize: 13, lineHeight: 1.8, resize: 'none',
              outline: 'none', direction: 'rtl', fontFamily: 'Vazirmatn, sans-serif',
            }}
          />
        </div>
      </div>
    </div>
  );
};

// ─────────────────────────────────────────────────────────────────
// قوانین کلی ربات — خط قرمز + خط مشی (global system prompt rules)
// ─────────────────────────────────────────────────────────────────
const GlobalRulesTab = ({ headers, toast }) => {
  const { useState, useEffect } = React;
  const [rules,    setRules]   = useState([]);
  const [loading,  setLoading] = useState(true);
  const [newText,  setNewText] = useState('');
  const [newType,  setNewType] = useState('guideline');
  const [editId,   setEditId]  = useState(null);
  const [editText, setEditText] = useState('');

  const TYPES = [
    { id: 'red_line',  label: 'خط قرمز', color: '#F87171', bg: 'rgba(239,68,68,0.1)',  icon: '🔴', desc: 'ربات هرگز این کارها را نمی‌کند' },
    { id: 'guideline', label: 'خط مشی',  color: '#818CF8', bg: 'rgba(99,102,241,0.1)', icon: '🔵', desc: 'شیوه رفتار ربات در همه مکالمات' },
  ];
  const placeholders = {
    red_line:  'مثال: هیچ‌وقت قیمت رقیب رو تأیید نکن...',
    guideline: 'مثال: همیشه با "شما" خطاب کن...',
  };

  const load = () => {
    setLoading(true);
    fetch('/api/rules', { headers })
      .then(r => r.json())
      .then(d => {
        if (d.success) {
          // فقط قوانین ربات (بدون cold/warm/hot که مربوط به لیدهاست)
          const botRules = (d.data && d.data.rules || []).filter(r => r.type === 'red_line' || r.type === 'guideline');
          setRules(botRules);
        }
      })
      .finally(() => setLoading(false));
  };
  useEffect(load, []);

  const add = () => {
    if (!newText.trim()) return;
    fetch('/api/rules', { method: 'POST', headers, body: JSON.stringify({ type: newType, text: newText }) })
      .then(r => r.json()).then(d => {
        if (d.success) { setNewText(''); load(); toast('قانون اضافه شد', 'success'); }
        else toast(d.message || 'خطا', 'error');
      });
  };

  const toggle = (rule) => {
    fetch('/api/rules/' + rule.id, { method: 'PUT', headers, body: JSON.stringify({ is_active: rule.is_active ? 0 : 1 }) })
      .then(() => load());
  };

  const remove = (id) => {
    if (!confirm('این قانون حذف شود؟')) return;
    fetch('/api/rules/' + id, { method: 'DELETE', headers }).then(() => { load(); toast('حذف شد', 'success'); });
  };

  const saveEdit = (id) => {
    if (!editText.trim()) return;
    fetch('/api/rules/' + id, { method: 'PUT', headers, body: JSON.stringify({ text: editText }) })
      .then(() => { setEditId(null); load(); toast('ذخیره شد', 'success'); });
  };

  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 20 }}>
      {/* توضیح */}
      <div style={{ padding: '12px 16px', borderRadius: 10, background: 'rgba(99,102,241,.06)', border: '1px solid rgba(99,102,241,.15)', fontSize: 12, color: '#94a3b8', lineHeight: 1.9 }}>
        ⚖️ این قوانین به <strong style={{ color: '#818CF8' }}>همه اسکریپت‌ها</strong> اعمال می‌شوند و بخشی از system prompt کلی ربات هستند.<br />
        خط قرمز = کارهایی که ربات <strong style={{ color: '#F87171' }}>هرگز</strong> انجام نمی‌دهد. خط مشی = نحوه رفتار در <strong style={{ color: '#818CF8' }}>همه</strong> مکالمات.
      </div>

      {/* فرم افزودن */}
      <div style={{ padding: '16px 18px', borderRadius: 12, background: 'rgba(255,255,255,.03)', border: '1px solid rgba(255,255,255,.08)' }}>
        <div style={{ fontSize: 11, color: '#64748b', marginBottom: 10, fontWeight: 600 }}>قانون جدید</div>
        <div style={{ display: 'flex', gap: 8, marginBottom: 10 }}>
          {TYPES.map(t => (
            <button key={t.id} onClick={() => setNewType(t.id)} style={{
              padding: '6px 16px', borderRadius: 8, fontSize: 12, cursor: 'pointer', border: 'none', fontWeight: 600,
              background: newType === t.id ? t.bg : 'rgba(255,255,255,.05)',
              color: newType === t.id ? t.color : '#64748b',
            }}>{t.icon} {t.label}</button>
          ))}
        </div>
        <div style={{ display: 'flex', gap: 8 }}>
          <textarea
            value={newText} onChange={e => setNewText(e.target.value)} rows={2}
            placeholder={placeholders[newType]}
            onKeyDown={e => e.key === 'Enter' && !e.shiftKey && (e.preventDefault(), add())}
            style={{ flex: 1, padding: '9px 12px', borderRadius: 8, background: 'rgba(255,255,255,.06)', border: '1px solid rgba(255,255,255,.12)', color: '#e2e8f0', fontSize: 12, outline: 'none', resize: 'none', fontFamily: 'inherit', lineHeight: 1.6 }}
          />
          <button onClick={add} disabled={!newText.trim()} style={{ padding: '0 20px', borderRadius: 8, fontSize: 12, cursor: 'pointer', border: 'none', background: newText.trim() ? '#6366F1' : 'rgba(99,102,241,.3)', color: '#fff', fontWeight: 600, alignSelf: 'stretch' }}>
            + افزودن
          </button>
        </div>
      </div>

      {/* لیست */}
      {loading ? (
        <div style={{ padding: 32, textAlign: 'center', color: '#64748b', fontSize: 12 }}>در حال بارگذاری...</div>
      ) : rules.length === 0 ? (
        <div style={{ padding: 32, textAlign: 'center', color: '#64748b', fontSize: 12 }}>
          <div style={{ fontSize: 28, marginBottom: 8 }}>⚖️</div>
          هنوز قانونی تعریف نشده
        </div>
      ) : (
        <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
          {TYPES.map(type => {
            const group = rules.filter(r => r.type === type.id);
            if (group.length === 0) return null;
            return (
              <div key={type.id}>
                <div style={{ fontSize: 11, fontWeight: 700, color: type.color, marginBottom: 6, display: 'flex', alignItems: 'center', gap: 6 }}>
                  {type.icon} {type.label}
                  <span style={{ fontSize: 10, color: '#475569', fontWeight: 400 }}>— {type.desc}</span>
                </div>
                <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
                  {group.map(rule => (
                    <div key={rule.id} style={{ display: 'flex', alignItems: 'flex-start', gap: 10, padding: '10px 14px', borderRadius: 10, background: rule.is_active ? type.bg : 'rgba(255,255,255,.02)', border: '1px solid ' + (rule.is_active ? type.color + '30' : 'rgba(255,255,255,.06)'), opacity: rule.is_active ? 1 : 0.5, transition: 'all .2s' }}>
                      <div style={{ flex: 1 }}>
                        {editId === rule.id ? (
                          <div style={{ display: 'flex', gap: 8 }}>
                            <textarea value={editText} onChange={e => setEditText(e.target.value)} rows={2} autoFocus
                              style={{ flex: 1, padding: '6px 10px', borderRadius: 7, background: 'rgba(255,255,255,.08)', border: '1px solid rgba(99,102,241,.4)', color: '#e2e8f0', fontSize: 12, outline: 'none', resize: 'none', fontFamily: 'inherit' }} />
                            <div style={{ display: 'flex', flexDirection: 'column', gap: 4 }}>
                              <button onClick={() => saveEdit(rule.id)} style={{ padding: '5px 12px', borderRadius: 6, fontSize: 11, cursor: 'pointer', border: 'none', background: '#6366F1', color: '#fff', fontWeight: 600 }}>ذخیره</button>
                              <button onClick={() => setEditId(null)} style={{ padding: '5px 12px', borderRadius: 6, fontSize: 11, cursor: 'pointer', border: '1px solid rgba(255,255,255,.1)', background: 'transparent', color: '#64748b' }}>لغو</button>
                            </div>
                          </div>
                        ) : (
                          <div style={{ fontSize: 13, color: '#e2e8f0', lineHeight: 1.7 }}>{rule.text}</div>
                        )}
                      </div>
                      {editId !== rule.id && (
                        <div style={{ display: 'flex', gap: 6, flexShrink: 0 }}>
                          <button onClick={() => toggle(rule)} title={rule.is_active ? 'غیرفعال کن' : 'فعال کن'}
                            style={{ padding: '4px 8px', borderRadius: 6, fontSize: 11, cursor: 'pointer', border: '1px solid rgba(255,255,255,.1)', background: 'transparent', color: rule.is_active ? type.color : '#475569' }}>
                            {rule.is_active ? '● فعال' : '○ غیرفعال'}
                          </button>
                          <button onClick={() => { setEditId(rule.id); setEditText(rule.text); }}
                            style={{ padding: '4px 8px', borderRadius: 6, fontSize: 11, cursor: 'pointer', border: '1px solid rgba(255,255,255,.1)', background: 'transparent', color: '#818CF8' }}>✏️</button>
                          <button onClick={() => remove(rule.id)}
                            style={{ padding: '4px 8px', borderRadius: 6, fontSize: 11, cursor: 'pointer', border: '1px solid rgba(248,113,113,.2)', background: 'transparent', color: '#F87171' }}>🗑</button>
                        </div>
                      )}
                    </div>
                  ))}
                </div>
              </div>
            );
          })}
        </div>
      )}
    </div>
  );
};

// ─── نقشه مراحل اسکریپت ──────────────────────────────────
const FALLBACK_COLORS = ['#6366F1','#10B981','#F59E0B','#EF4444','#06B6D4','#8B5CF6','#F97316'];

/* ─── آواتار مشتری زیر هر استیت ─── */
const StateAvatarCard = ({ color, fillPct, prevData, newData, isActive }) => {
  const R = 26;
  const circ = 2 * Math.PI * R; // ≈ 163.4
  const dash = Math.max(0, Math.min(1, fillPct / 100)) * circ;
  const hasData = prevData.length > 0 || newData.length > 0;

  /* ویژگی‌هایی که از قبل داریم + ویژگی‌های این مرحله */
  const knownFeatures = [
    { key: /نام|اسم/,          icon: '👤', label: 'نام' },
    { key: /سن|سال/,            icon: '🎂', label: 'سن' },
    { key: /شغل|کار|شاغل/,     icon: '💼', label: 'شغل' },
    { key: /تحصیل/,             icon: '🎓', label: 'تحصیلات' },
    { key: /شهر|استان|محل/,    icon: '📍', label: 'شهر' },
    { key: /بودجه|هزینه/,       icon: '💰', label: 'بودجه' },
    { key: /شماره|تلفن|موبایل/, icon: '📱', label: 'شماره' },
    { key: /هدف|نیاز/,          icon: '🎯', label: 'هدف' },
  ];

  /* تطابق چیپ‌ها با آیکون‌ها */
  const chipIcon = (label) => {
    const f = knownFeatures.find(f => f.key.test(label));
    return f ? f.icon : '📌';
  };

  /* رنگ head/body SVG بر اساس درصد */
  const headOpacity = fillPct > 0  ? 1 : 0.2;
  const bodyOpacity = fillPct > 25 ? 1 : 0.2;
  const armOpacity  = fillPct > 55 ? 1 : 0;
  const legOpacity  = fillPct > 75 ? 1 : 0;

  return (
    <div style={{
      width: 190, borderRadius: 12, direction: 'rtl',
      background: isActive ? `${color}0e` : 'rgba(255,255,255,0.02)',
      border: `1px solid ${isActive ? color + '30' : 'rgba(255,255,255,0.07)'}`,
      padding: '12px 10px 10px',
      transition: 'all .25s',
    }}>
      {/* آواتار + رینگ */}
      <div style={{ display:'flex', flexDirection:'column', alignItems:'center', gap:5 }}>
        <div style={{ position:'relative', width:64, height:64 }}>
          {/* حلقه progress */}
          <svg width="64" height="64" viewBox="0 0 64 64"
            style={{ position:'absolute', top:0, left:0, transform:'rotate(-90deg)' }}>
            <circle cx="32" cy="32" r={R} fill="none"
              stroke="rgba(255,255,255,0.07)" strokeWidth="3.5"/>
            <circle cx="32" cy="32" r={R} fill="none"
              stroke={color} strokeWidth="3.5" strokeLinecap="round"
              strokeDasharray={`${dash} ${circ}`}
              style={{ transition:'stroke-dasharray .8s ease' }}/>
          </svg>

          {/* دایره مرکزی + SVG آدم */}
          <div style={{
            position:'absolute', top:'50%', left:'50%',
            transform:'translate(-50%,-50%)',
            width:48, height:48, borderRadius:'50%',
            background: `${color}18`,
            display:'flex', alignItems:'center', justifyContent:'center',
          }}>
            <svg width="28" height="28" viewBox="0 0 28 28" fill="none">
              {/* سر */}
              <circle cx="14" cy="8" r="5"
                fill={color} opacity={headOpacity}
                style={{ transition:'opacity .5s' }}/>
              {/* بدن */}
              <path d="M14 14 L14 21" stroke={color} strokeWidth="2.5"
                strokeLinecap="round" opacity={bodyOpacity}
                style={{ transition:'opacity .5s' }}/>
              {/* بازوها */}
              <path d="M7 17 L14 15 L21 17" stroke={color} strokeWidth="2"
                strokeLinecap="round" opacity={armOpacity}
                style={{ transition:'opacity .5s' }}/>
              {/* پاها */}
              <path d="M14 21 L10 26 M14 21 L18 26" stroke={color} strokeWidth="2"
                strokeLinecap="round" opacity={legOpacity}
                style={{ transition:'opacity .5s' }}/>
              {/* چشم */}
              {fillPct > 0 && (
                <circle cx="14" cy="8" r="1.8"
                  fill="rgba(0,0,0,0.35)" opacity={headOpacity}/>
              )}
            </svg>
          </div>

          {/* badge درصد */}
          <div style={{
            position:'absolute', bottom:0, right:0,
            minWidth:20, height:20, borderRadius:10,
            background: color, padding:'0 4px',
            display:'flex', alignItems:'center', justifyContent:'center',
            fontSize:9, fontWeight:700, color:'#fff',
          }}>
            {fillPct}%
          </div>
        </div>

        <div style={{ fontSize:9, color:'var(--text-3)', textAlign:'center', lineHeight:1.5 }}>
          پروفایل مشتری<br/>
          <span style={{ color, fontWeight:700 }}>{fillPct}%</span> شناخته شده
        </div>
      </div>

      {/* جداکننده */}
      {hasData && (
        <div style={{ height:1, background:'rgba(255,255,255,0.06)', margin:'8px 0 6px' }}/>
      )}

      {/* چیپ‌های داده */}
      {hasData ? (
        <div style={{ display:'flex', flexWrap:'wrap', gap:3 }}>
          {prevData.map((d, idx) => (
            <span key={`p${idx}`} style={{
              fontSize:9, padding:'2px 6px', borderRadius:6, lineHeight:1.5,
              background:'rgba(255,255,255,0.04)', color:'#475569',
              border:'1px solid rgba(255,255,255,0.08)',
            }}>
              {chipIcon(d)} {d}
            </span>
          ))}
          {newData.map((d, idx) => (
            <span key={`n${idx}`} style={{
              fontSize:9, padding:'2px 6px', borderRadius:6, lineHeight:1.5,
              background:`${color}1c`, color,
              border:`1px solid ${color}38`, fontWeight:600,
            }}>
              {chipIcon(d)} {d}
            </span>
          ))}
        </div>
      ) : (
        <div style={{ textAlign:'center', fontSize:9, color:'#334155', marginTop:4 }}>
          داده‌ای جمع نمی‌شه
        </div>
      )}
    </div>
  );
};

const ScriptMapTab = ({ states: initialStates, onBuild, building, highlightStateId = null, scriptId, headers, toast, onStatesUpdated, onPromptUpdated }) => {
  const { fa } = window.SB_DATA;
  const [states,   setStates]   = useState(initialStates);
  const [editMode, setEditMode] = useState(false);
  const [editData, setEditData] = useState({}); // id → {name, description, color, exit_condition}
  const [saving,   setSaving]   = useState(false);
  const [applying, setApplying] = useState(false);

  // sync وقتی states از بیرون عوض شد (بعد از build)
  useEffect(() => {
    setStates(initialStates);
    setEditData({});
    setEditMode(false);
  }, [initialStates]);

  const moveState = (idx, dir) => {
    const next = [...states];
    const swapIdx = idx + dir;
    if (swapIdx < 0 || swapIdx >= next.length) return;
    [next[idx], next[swapIdx]] = [next[swapIdx], next[idx]];
    setStates(next);
  };

  const enterEdit = () => {
    const d = {};
    states.forEach(s => {
      d[s.id] = {
        name: s.name,
        description: s.description,
        color: s.color || '#6366F1',
        exit_condition: s.exit_condition || '',
        data_collect: Array.isArray(s.data_collect) ? s.data_collect.join('، ') : '',
        followup_delay_h: s.followup_delay_h || 0,
      };
    });
    setEditData(d);
    setEditMode(true);
  };

  const saveEdits = async () => {
    setSaving(true);
    try {
      // ساخت لیست نهایی استیت‌ها بر اساس editData
      const finalStates = states.map((s, i) => {
        const d = editData[s.id] || {};
        const dcArr = (d.data_collect || '').split('،').map(x => x.trim()).filter(Boolean);
        return {
          ...s,
          name:           d.name           !== undefined ? d.name           : s.name,
          description:    d.description    !== undefined ? d.description    : s.description,
          color:          d.color          || s.color,
          exit_condition: d.exit_condition !== undefined ? d.exit_condition : s.exit_condition,
          data_collect:   dcArr,
          followup_delay_h: d.followup_delay_h !== undefined ? Number(d.followup_delay_h) || 0 : (s.followup_delay_h || 0),
          order_num:      i + 1,
        };
      });

      // ذخیره همه در دیتابیس
      for (let i = 0; i < finalStates.length; i++) {
        const s = finalStates[i];
        const resp = await fetch(`/api/scripts/states/${s.id}`, {
          method: 'PUT', headers,
          body: JSON.stringify({
            name:           s.name,
            description:    s.description,
            color:          s.color,
            exit_condition: s.exit_condition,
            data_collect:   s.data_collect,
            followup_delay_h: s.followup_delay_h,
            order_num:      s.order_num,
          }),
        });
        if (!resp.ok) throw new Error(`خطا در ذخیره استیت ${s.name}`);
      }

      // آپدیت local state و parent
      setStates(finalStates);
      if (onStatesUpdated) onStatesUpdated(finalStates);
      setEditMode(false);
      setEditData({});
      toast('نقشه ذخیره شد — در حال آپدیت اسکریپت... ⟳', 'info');

      // آپدیت خودکار اسکریپت در پس‌زمینه
      fetch(`/api/scripts/${scriptId}/apply-map`, { method: 'POST', headers })
        .then(r => r.json())
        .then(d => {
          if (d.success) {
            if (onPromptUpdated) onPromptUpdated(d.data.system_prompt);
            toast('نقشه و اسکریپت هر دو آپدیت شدن ✅', 'success');
          }
        })
        .catch(() => {});

    } catch (e) {
      toast('خطا در ذخیره: ' + e.message, 'error');
    } finally { setSaving(false); }
  };

  const applyMapToScript = async () => {
    if (!confirm('نقشه مراحل روی متن اسکریپت اعمال می‌شود. متن فعلی یک نسخه پشتیبان می‌شود. ادامه دهم؟')) return;
    setApplying(true);
    try {
      const r = await fetch(`/api/scripts/${scriptId}/apply-map`, { method: 'POST', headers });
      const d = await r.json();
      if (d.success) {
        toast('متن اسکریپت بر اساس نقشه آپدیت شد ✅', 'success');
        if (onPromptUpdated) onPromptUpdated(d.data.system_prompt);
      } else {
        toast('خطا: ' + d.message, 'error');
      }
    } catch (e) {
      toast('خطا در ارتباط با سرور', 'error');
    } finally {
      setApplying(false);
    }
  };

  const deleteState = async (id) => {
    if (!confirm('این مرحله حذف شود؟')) return;
    await fetch(`/api/scripts/states/${id}`, { method: 'DELETE', headers });
    setStates(prev => prev.filter(s => s.id !== id));
    setEditData(prev => { const d = {...prev}; delete d[id]; return d; });
  };

  const addState = async () => {
    const r = await fetch(`/api/scripts/${scriptId}/states`, {
      method: 'POST', headers,
      body: JSON.stringify({ name: 'مرحله جدید', description: '', color: FALLBACK_COLORS[states.length % FALLBACK_COLORS.length] }),
    });
    const d = await r.json();
    if (d.success) {
      const s = d.data.state || d.data;
      try { s.data_collect = JSON.parse(s.data_collect); } catch { s.data_collect = []; }
      setStates(prev => [...prev, s]);
      setEditData(prev => ({ ...prev, [s.id]: { name: s.name, description: '', color: s.color, exit_condition: '', data_collect: '' } }));
    }
  };

  if (states.length === 0 && !editMode) {
    return (
      <div className="card" style={{ textAlign:'center', padding:60 }}>
        <div style={{ fontSize:48, marginBottom:14 }}>🗺️</div>
        <div style={{ fontSize:15, fontWeight:600, color:'var(--text-1)', marginBottom:8 }}>هنوز نقشه‌ای ساخته نشده</div>
        <div style={{ fontSize:13, color:'var(--text-3)', marginBottom:24, lineHeight:1.8 }}>
          دکمه «ساخت نقشه» رو بزن تا Claude اسکریپت رو بخونه<br/>و مراحل مکالمه رو به صورت گرافیکی نشون بده
        </div>
        <button onClick={onBuild} disabled={building}
          style={{ padding:'10px 28px', borderRadius:10, border:'none', cursor:'pointer',
            background:'rgba(245,158,11,0.15)', color:'#FBBF24', fontSize:14, fontFamily:'inherit' }}>
          {building ? '⟳ در حال ساخت...' : '🗺️ ساخت نقشه مراحل'}
        </button>
      </div>
    );
  }

  return (
    <div>
      {/* نوار ابزار */}
      <div style={{ display:'flex', alignItems:'center', gap:8, marginBottom:20, flexWrap:'wrap' }}>
        <span style={{ fontSize:11, color:'var(--text-3)' }}>🗺️ {fa(states.length)} استیت</span>

        <div style={{ marginRight:'auto', display:'flex', gap:8 }}>
          {editMode ? (
            <>
              <button onClick={addState}
                style={{ padding:'5px 14px', borderRadius:8, border:'1px solid rgba(52,211,153,0.3)',
                  background:'rgba(52,211,153,0.08)', color:'#34D399', fontSize:12, cursor:'pointer', fontFamily:'inherit' }}>
                + استیت جدید
              </button>
              <button onClick={() => { setEditMode(false); setEditData({}); }}
                style={{ padding:'5px 14px', borderRadius:8, border:'1px solid rgba(255,255,255,0.1)',
                  background:'transparent', color:'var(--text-3)', fontSize:12, cursor:'pointer', fontFamily:'inherit' }}>
                انصراف
              </button>
              <button onClick={saveEdits} disabled={saving}
                style={{ padding:'5px 16px', borderRadius:8, border:'none',
                  background:'var(--primary)', color:'#fff', fontSize:12, cursor:'pointer', fontFamily:'inherit', fontWeight:600 }}>
                {saving ? '...' : '💾 ذخیره'}
              </button>
            </>
          ) : (
            <>
              <button onClick={enterEdit}
                style={{ padding:'5px 14px', borderRadius:8, border:'1px solid rgba(99,102,241,0.3)',
                  background:'rgba(99,102,241,0.08)', color:'#818CF8', fontSize:12, cursor:'pointer', fontFamily:'inherit' }}>
                ✏️ ویرایش دستی
              </button>
              <button onClick={onBuild} disabled={building}
                style={{ padding:'5px 14px', borderRadius:8, border:'1px solid rgba(245,158,11,0.3)',
                  background:'rgba(245,158,11,0.08)', color:'#FBBF24', fontSize:12, cursor:'pointer', fontFamily:'inherit' }}>
                {building ? '⟳ در حال ساخت...' : '🤖 ساخت مجدد با AI'}
              </button>
              <button onClick={applyMapToScript} disabled={applying}
                style={{ padding:'5px 14px', borderRadius:8, border:'1px solid rgba(6,182,212,0.3)',
                  background:'rgba(6,182,212,0.08)', color:'#22D3EE', fontSize:12, cursor:'pointer', fontFamily:'inherit' }}>
                {applying ? '⟳ در حال اعمال...' : '🔄 اعمال نقشه روی اسکریپت'}
              </button>
            </>
          )}
        </div>
      </div>

      {/* ─── نمایش نودها (LTR: ۱ از چپ، N از راست) ─── */}
      <div style={{ overflowX:'auto', paddingBottom:16 }}>
        <div style={{ display:'flex', alignItems:'flex-start', gap:0, direction:'ltr', width:'max-content', minWidth:'100%' }}>
          {states.map((state, i) => {
            const ed       = editData[state.id] || {};
            const color    = (editMode ? ed.color : state.color) || FALLBACK_COLORS[i % FALLBACK_COLORS.length];
            const isLast   = i === states.length - 1;
            const isActive = highlightStateId && state.id === highlightStateId;
            const dataItems = Array.isArray(state.data_collect) ? state.data_collect : [];

            /* داده‌های تجمعی برای آواتار */
            const prevData  = states.slice(0, i).flatMap(s => Array.isArray(s.data_collect) ? s.data_collect : []);
            const totalData = states.flatMap(s => Array.isArray(s.data_collect) ? s.data_collect : []);
            const fillPct   = totalData.length > 0
              ? Math.round(((prevData.length + dataItems.length) / totalData.length) * 100)
              : (isLast ? 100 : 0);

            return (
              <React.Fragment key={state.id}>
                {/* ستون: نود + آواتار */}
                <div style={{ display:'flex', flexDirection:'column', alignItems:'center', gap:10 }}>

                  {/* ── کارت نود ── */}
                  <div style={{
                    width: editMode ? 220 : 190, flexShrink:0, borderRadius:14, position:'relative',
                    border:`2px solid ${isActive ? color : color + '50'}`,
                    background: isActive ? `${color}22` : `${color}0d`,
                    boxShadow: isActive ? `0 0 24px ${color}44` : 'none',
                    transform: isActive ? 'translateY(-4px)' : 'none',
                    transition:'all .2s',
                  }}>
                    {/* شماره + کنترل‌ها */}
                    <div style={{ display:'flex', justifyContent:'space-between', alignItems:'center', padding:'10px 12px 0' }}>
                      <div style={{ width:24, height:24, borderRadius:'50%', background:color,
                        display:'flex', alignItems:'center', justifyContent:'center',
                        fontSize:11, fontWeight:700, color:'#fff', flexShrink:0 }}>
                        {i + 1}
                      </div>
                      {editMode && (
                        <div style={{ display:'flex', gap:3, alignItems:'center' }}>
                          <button onClick={() => moveState(i, -1)} disabled={i === 0}
                            style={{ border:'none', background:'none', cursor:'pointer', color: i===0?'#334155':'#94a3b8', fontSize:14, padding:'0 1px', lineHeight:1 }}>←</button>
                          <button onClick={() => moveState(i, 1)} disabled={i === states.length-1}
                            style={{ border:'none', background:'none', cursor:'pointer', color: i===states.length-1?'#334155':'#94a3b8', fontSize:14, padding:'0 1px', lineHeight:1 }}>→</button>
                          <input type="color" value={ed.color || color}
                            onChange={e => setEditData(p => ({ ...p, [state.id]: { ...p[state.id], color: e.target.value } }))}
                            style={{ width:20, height:20, border:'none', borderRadius:4, cursor:'pointer', padding:0, background:'none' }} />
                          <button onClick={() => deleteState(state.id)}
                            style={{ border:'none', background:'none', cursor:'pointer', color:'#F87171', fontSize:14, padding:0, lineHeight:1 }}>✕</button>
                        </div>
                      )}
                      {isActive && !editMode && (
                        <span style={{ fontSize:10, background:color, color:'#fff', padding:'1px 7px', borderRadius:8, fontWeight:700 }}>
                          📍 اینجاست
                        </span>
                      )}
                    </div>

                    <div style={{ padding:'8px 12px 14px', direction:'rtl' }}>
                      {editMode ? (
                        <div style={{ display:'flex', flexDirection:'column', gap:6 }}>
                          <input value={ed.name || ''}
                            onChange={e => setEditData(p => ({ ...p, [state.id]: { ...p[state.id], name: e.target.value } }))}
                            style={{ width:'100%', padding:'5px 8px', borderRadius:7, border:`1px solid ${color}50`,
                              background:'rgba(255,255,255,0.06)', color:'#e2e8f0', fontSize:12, fontFamily:'inherit',
                              textAlign:'right', boxSizing:'border-box' }} />
                          <textarea value={ed.description || ''}
                            onChange={e => setEditData(p => ({ ...p, [state.id]: { ...p[state.id], description: e.target.value } }))}
                            rows={2} placeholder="توضیح..."
                            style={{ width:'100%', padding:'5px 8px', borderRadius:7, border:'1px solid rgba(255,255,255,0.1)',
                              background:'rgba(255,255,255,0.04)', color:'#94a3b8', fontSize:11, fontFamily:'inherit',
                              resize:'none', textAlign:'right', boxSizing:'border-box' }} />
                          <div style={{ fontSize:9, color:'#6EE7B7', marginTop:2, marginBottom:1 }}>📋 اطلاعاتی که ثبت می‌شه (با ، جدا کن)</div>
                          <input value={ed.data_collect || ''}
                            onChange={e => setEditData(p => ({ ...p, [state.id]: { ...p[state.id], data_collect: e.target.value } }))}
                            placeholder="مثال: نظر مشتری، سن، شغل"
                            style={{ width:'100%', padding:'5px 8px', borderRadius:7, border:'1px solid rgba(110,231,183,0.25)',
                              background:'rgba(16,185,129,0.06)', color:'#6EE7B7', fontSize:10, fontFamily:'inherit',
                              textAlign:'right', boxSizing:'border-box' }} />
                          <div style={{ fontSize:9, color:'#FBBF24', marginTop:4, marginBottom:1 }}>⏰ اگر کاربر تا چند ساعت جواب نداد، پیگیری شود (۰ = پیش‌فرض ۳ ساعت)</div>
                          <input type="number" min="0" step="0.5" value={ed.followup_delay_h ?? 0}
                            onChange={e => setEditData(p => ({ ...p, [state.id]: { ...p[state.id], followup_delay_h: e.target.value } }))}
                            placeholder="0"
                            style={{ width:'100%', padding:'5px 8px', borderRadius:7, border:'1px solid rgba(251,191,36,0.25)',
                              background:'rgba(251,191,36,0.06)', color:'#FBBF24', fontSize:10, fontFamily:'inherit',
                              textAlign:'right', boxSizing:'border-box' }} />
                        </div>
                      ) : (
                        <>
                          <div style={{ fontSize:13, fontWeight:700, color, textAlign:'center', marginBottom:6 }}>
                            {state.name}
                          </div>
                          <div style={{ fontSize:11, color:'var(--text-3)', textAlign:'center', lineHeight:1.6, marginBottom:8, minHeight:28 }}>
                            {state.description}
                          </div>
                          {isLast && (
                            <div style={{ textAlign:'center', marginTop:4, fontSize:11, color }}>🎯 هدف نهایی</div>
                          )}
                        </>
                      )}
                    </div>
                  </div>

                  {/* ── آواتار مشتری (فقط view mode) ── */}
                  {!editMode && (
                    <StateAvatarCard
                      color={color}
                      fillPct={fillPct}
                      prevData={prevData}
                      newData={dataItems}
                      isActive={isActive}
                    />
                  )}
                </div>

                {/* فلش → (وسط کارت نود ~ 75px از بالا) */}
                {!isLast && (
                  <div style={{ flexShrink:0, display:'flex', alignItems:'flex-start',
                    paddingTop:62, padding:'62px 3px 0' }}>
                    <div style={{ width:22, height:2, background:'rgba(255,255,255,0.12)' }} />
                    <div style={{ width:0, height:0,
                      borderTop:'5px solid transparent', borderBottom:'5px solid transparent',
                      borderLeft:'7px solid rgba(255,255,255,0.2)' }} />
                  </div>
                )}
              </React.Fragment>
            );
          })}
        </div>
      </div>
    </div>
  );
};

// ─── تب رسانه‌ها ─────────────────────────────────────────────
const MediaFilesTab = ({ mediaFiles, setMediaFiles, libFiles, loadLibFiles, onSave, saving, scriptId, headers, toast }) => {
  const [suggesting,   setSuggesting]   = useState(false);
  const [pickerSlot,   setPickerSlot]   = useState(null);  // slot_key که داریم فایل انتخاب می‌کنیم
  const [uploadSlot,   setUploadSlot]   = useState(null);  // slot_key که داریم آپلود می‌کنیم
  const [uploading,    setUploading]    = useState(false);
  const uploadRef = useRef(null);

  useEffect(() => { if (libFiles.length === 0) loadLibFiles(); }, []);

  const typeIcon = (t) => ({ video:'🎬', audio:'🎧', image:'🖼️', pdf:'📄', text:'📝' }[t] || '📎');
  const typeColor = (t) => ({ video:'#6366F1', audio:'#F59E0B', image:'#10B981', pdf:'#EF4444', audio:'#F59E0B' }[t] || '#64748b');

  // ── پیشنهاد هوشمند ───────────────────────────────────────
  const suggest = async () => {
    setSuggesting(true);
    try {
      const r = await fetch(`/api/scripts/${scriptId}/suggest-media`, { method:'POST', headers });
      const d = await r.json();
      if (d.success) {
        setMediaFiles(d.data.slots || []);
        toast('اسلات‌ها ساخته شدن — فایل‌ها رو آپلود کن ✅', 'success');
      } else toast('خطا: ' + d.message, 'error');
    } catch { toast('خطا در ارتباط با سرور', 'error'); }
    finally { setSuggesting(false); }
  };

  // ── لینک کردن فایل کتابخانه به اسلات ───────────────────
  const linkFile = (slotKey, libFile) => {
    setMediaFiles(prev => {
      const updated = prev.map(s =>
        s.slot_key === slotKey
          ? { ...s, id: libFile.id, file_name: libFile.name || libFile.original_name }
          : s
      );
      // مقدار جدید رو مستقیم پاس میدیم — نه از state که هنوز آپدیت نشده
      setTimeout(() => onSave(updated), 50);
      return updated;
    });
    setPickerSlot(null);
  };

  // ── آپلود مستقیم به کتابخانه + لینک به اسلات ────────────
  const handleUpload = async (slotKey, file) => {
    setUploading(true);
    try {
      const fd = new FormData();
      fd.append('file', file);
      fd.append('name', file.name);
      const r = await fetch('/api/library/upload', {
        method: 'POST',
        headers: { Authorization: headers.Authorization },
        body: fd,
      });
      const d = await r.json();
      if (d.success) {
        const newFile = d.data.file || d.data;
        loadLibFiles(); // رفرش کتابخانه
        linkFile(slotKey, newFile);
        toast('فایل آپلود و لینک شد ✅', 'success');
      } else toast('خطا در آپلود: ' + d.message, 'error');
    } catch { toast('خطا در آپلود', 'error'); }
    finally { setUploading(false); setUploadSlot(null); }
  };

  // ── حذف لینک فایل از اسلات ──────────────────────────────
  const unlinkFile = (slotKey) => {
    setMediaFiles(prev => {
      const updated = prev.map(s =>
        s.slot_key === slotKey ? { ...s, id: null, file_name: null } : s
      );
      setTimeout(() => onSave(updated), 50);
      return updated;
    });
  };

  const filledCount = mediaFiles.filter(s => s.id).length;

  return (
    <div style={{ display:'flex', flexDirection:'column', gap:16 }}>

      {/* هدر */}
      <div style={{ display:'flex', alignItems:'center', justifyContent:'space-between', flexWrap:'wrap', gap:10 }}>
        <div style={{ fontSize:12, color:'var(--text-3)', lineHeight:1.8 }}>
          ربات این فایل‌ها رو در <strong style={{color:'#818CF8'}}>جریان طبیعی مکالمه</strong> می‌فرسته — بدون کلیدواژه.<br/>
          {mediaFiles.length > 0 && <span style={{color: filledCount === mediaFiles.length ? '#34D399' : '#FBBF24'}}>{filledCount}/{mediaFiles.length} اسلات پر شده</span>}
        </div>
        <div style={{ display:'flex', gap:8 }}>
          <button onClick={suggest} disabled={suggesting}
            style={{ padding:'7px 16px', borderRadius:10, border:'none', cursor: suggesting?'wait':'pointer',
              background: suggesting ? 'rgba(99,102,241,0.15)' : 'rgba(99,102,241,0.12)',
              color:'#818CF8', fontSize:12, fontFamily:'inherit', display:'flex', alignItems:'center', gap:6 }}>
            {suggesting
              ? <><span style={{animation:'spin 1s linear infinite',display:'inline-block'}}>⟳</span> در حال تحلیل...</>
              : <>🤖 پیشنهاد هوشمند</>}
          </button>
          {mediaFiles.length > 0 && (
            <button onClick={onSave} disabled={saving}
              style={{ padding:'7px 16px', borderRadius:10, border:'none', background:'var(--primary)', color:'#fff', fontSize:12, cursor:'pointer', fontFamily:'inherit', fontWeight:600 }}>
              {saving ? '...' : '💾 ذخیره'}
            </button>
          )}
        </div>
      </div>

      {/* حالت خالی */}
      {mediaFiles.length === 0 && (
        <div style={{ textAlign:'center', padding:'50px 20px', borderRadius:16, border:'1px dashed rgba(255,255,255,0.1)' }}>
          <div style={{ fontSize:44, marginBottom:12 }}>🤖</div>
          <div style={{ fontSize:14, fontWeight:600, color:'var(--text-1)', marginBottom:8 }}>هنوز اسلاتی ساخته نشده</div>
          <div style={{ fontSize:12, color:'var(--text-3)', marginBottom:20, lineHeight:1.8 }}>
            «پیشنهاد هوشمند» رو بزن تا Claude اسکریپت رو بخونه<br/>و بگه چه فایل‌هایی لازم داره
          </div>
          <button onClick={suggest} disabled={suggesting}
            style={{ padding:'10px 28px', borderRadius:10, border:'none', background:'rgba(99,102,241,0.15)', color:'#818CF8', fontSize:13, cursor:'pointer', fontFamily:'inherit' }}>
            {suggesting ? '⟳ در حال تحلیل...' : '🤖 پیشنهاد هوشمند'}
          </button>
        </div>
      )}

      {/* اسلات‌ها */}
      {mediaFiles.length > 0 && (
        <div style={{ display:'flex', flexDirection:'column', gap:12 }}>
          {mediaFiles.map(slot => {
            const color = typeColor(slot.file_type);
            const isEmpty = !slot.id;
            return (
              <div key={slot.slot_key} style={{
                borderRadius:14, overflow:'hidden',
                border:`1px solid ${isEmpty ? 'rgba(255,255,255,0.08)' : color+'40'}`,
                background: isEmpty ? 'rgba(255,255,255,0.02)' : color+'0a',
                transition:'all .2s',
              }}>
                {/* هدر اسلات */}
                <div style={{ padding:'12px 16px', display:'grid', gridTemplateColumns:'auto 1fr auto', gap:12, alignItems:'center' }}>
                  <div style={{ fontSize:26 }}>{typeIcon(slot.file_type)}</div>
                  <div>
                    <div style={{ fontSize:13, fontWeight:700, color: isEmpty ? 'var(--text-2)' : color }}>{slot.name}</div>
                    <div style={{ fontSize:11, color:'var(--text-3)', marginTop:2, lineHeight:1.5 }}>{slot.description}</div>
                  </div>
                  {/* وضعیت پر/خالی */}
                  <div>
                    {isEmpty
                      ? <span style={{ fontSize:10, padding:'3px 9px', borderRadius:20, background:'rgba(251,191,36,0.1)', color:'#FBBF24', border:'1px solid rgba(251,191,36,0.2)' }}>⚠ خالی</span>
                      : <span style={{ fontSize:10, padding:'3px 9px', borderRadius:20, background:'rgba(52,211,153,0.1)', color:'#34D399', border:'1px solid rgba(52,211,153,0.2)' }}>✓ آماده</span>
                    }
                  </div>
                </div>

                {/* موقعیت ارسال */}
                <div style={{ padding:'0 16px 10px', fontSize:11, color:'#FBBF24', display:'flex', gap:6, alignItems:'flex-start' }}>
                  <span style={{ flexShrink:0 }}>🕐 کِی:</span>
                  <span style={{ lineHeight:1.5 }}>{slot.when_to_send}</span>
                </div>

                {/* فوتر — فایل یا دکمه‌های آپلود */}
                <div style={{ padding:'10px 16px', borderTop:`1px solid ${isEmpty ? 'rgba(255,255,255,0.05)' : color+'20'}`, background:'rgba(0,0,0,0.15)', display:'flex', alignItems:'center', justifyContent:'space-between', gap:10 }}>
                  {isEmpty ? (
                    <div style={{ display:'flex', gap:8 }}>
                      {/* آپلود مستقیم */}
                      <label style={{ padding:'6px 14px', borderRadius:8, border:`1px solid ${color}40`, background:`${color}0f`, color, fontSize:11, cursor:'pointer', fontFamily:'inherit', display:'flex', alignItems:'center', gap:5 }}>
                        ⬆ آپلود فایل
                        <input type="file" style={{ display:'none' }}
                          onChange={e => { if(e.target.files[0]) handleUpload(slot.slot_key, e.target.files[0]); e.target.value=''; }}
                        />
                      </label>
                      {/* انتخاب از کتابخانه */}
                      <button onClick={() => setPickerSlot(pickerSlot===slot.slot_key ? null : slot.slot_key)}
                        style={{ padding:'6px 14px', borderRadius:8, border:'1px solid rgba(255,255,255,0.1)', background:'rgba(255,255,255,0.04)', color:'var(--text-2)', fontSize:11, cursor:'pointer', fontFamily:'inherit' }}>
                        📚 از کتابخانه
                      </button>
                    </div>
                  ) : (
                    <div style={{ display:'flex', alignItems:'center', gap:10, flex:1 }}>
                      <div style={{ fontSize:11, color:'var(--text-2)', overflow:'hidden', textOverflow:'ellipsis', whiteSpace:'nowrap', flex:1 }}>
                        📎 {slot.file_name}
                      </div>
                      <button onClick={() => unlinkFile(slot.slot_key)}
                        style={{ padding:'4px 10px', borderRadius:7, border:'1px solid rgba(248,113,113,0.2)', background:'transparent', color:'#F87171', fontSize:11, cursor:'pointer', fontFamily:'inherit' }}>
                        جایگزین
                      </button>
                    </div>
                  )}
                </div>

                {/* پیکر کتابخانه — باز شده برای این اسلات */}
                {pickerSlot === slot.slot_key && (
                  <div style={{ borderTop:'1px solid rgba(255,255,255,0.06)', background:'rgba(0,0,0,0.2)' }}>
                    {libFiles.length === 0 ? (
                      <div style={{ padding:20, textAlign:'center', color:'var(--text-3)', fontSize:12 }}>کتابخانه خالی است</div>
                    ) : (
                      <div style={{ display:'grid', gridTemplateColumns:'repeat(auto-fill,minmax(160px,1fr))', gap:8, padding:12 }}>
                        {libFiles.map(f => (
                          <div key={f.id} onClick={() => linkFile(slot.slot_key, f)}
                            style={{ padding:'10px 12px', borderRadius:10, cursor:'pointer', border:'1px solid rgba(255,255,255,0.07)', background:'rgba(255,255,255,0.02)',
                              transition:'all .15s' }}
                            onMouseEnter={e => e.currentTarget.style.borderColor=color+'60'}
                            onMouseLeave={e => e.currentTarget.style.borderColor='rgba(255,255,255,0.07)'}>
                            <div style={{ fontSize:20, marginBottom:4 }}>{typeIcon(f.file_type)}</div>
                            <div style={{ fontSize:11, fontWeight:600, color:'var(--text-1)', overflow:'hidden', textOverflow:'ellipsis', whiteSpace:'nowrap' }}>{f.name||f.original_name}</div>
                            <div style={{ fontSize:10, color:'var(--text-3)', marginTop:2 }}>{f.file_type}</div>
                          </div>
                        ))}
                      </div>
                    )}
                  </div>
                )}
              </div>
            );
          })}
        </div>
      )}

      {/* لودینگ آپلود */}
      {uploading && (
        <div style={{ padding:'10px 16px', borderRadius:10, background:'rgba(99,102,241,0.08)', color:'#818CF8', fontSize:12, textAlign:'center' }}>
          ⟳ در حال آپلود...
        </div>
      )}
    </div>
  );
};


// ─── پیگیری ───────────────────────────────────────────────────────────────
// FollowUp — ساده‌شده

// ─── تریگرها با آیکون و رنگ ───────────────────────────────
const FU_TRIGGERS = [
  { id:'script_drop',       icon:'🚪', label:'رها کردن مکالمه',      color:'#F59E0B', desc:'وقتی کاربر وسط مکالمه ناپدید شد' },
  { id:'state_stuck',       icon:'📍', label:'گیر کردن در استیت',    color:'#8B5CF6', desc:'وقتی لید چند ساعت/روز تو یه مرحله گیر کرده' },
  { id:'free_content_sent', icon:'📦', label:'بعد محتوای رایگان',     color:'#10B981', desc:'بعد از ارسال دوره یا فایل رایگان' },
  { id:'consultation_done', icon:'📅', label:'یادآور مشاوره',         color:'#6366F1', desc:'قبل یا بعد از جلسه مشاوره' },
  { id:'payment_expired',   icon:'💳', label:'یادآور پرداخت',         color:'#EF4444', desc:'وقتی مهلت پرداخت نزدیکه' },
  { id:'warm_cold',         icon:'🌡️', label:'لید سرد شد',           color:'#64748B', desc:'وقتی لید چند روزه جواب نمیده' },
  { id:'phone_received',    icon:'📞', label:'شماره دریافت شد',       color:'#10B981', desc:'وقتی لید شماره‌اش رو داد' },
  { id:'new_lead',          icon:'🆕', label:'لید جدید',              color:'#06B6D4', desc:'هر بار که لید جدید وارد بات شد' },
  { id:'post_purchase',     icon:'🛒', label:'بعد از خرید',           color:'#F97316', desc:'پیگیری و upsell بعد از خرید' },
  { id:'manual',            icon:'🖐', label:'دستی',                  color:'#94A3B8', desc:'فقط از پنل لیدها trigger میشه' },
];

const formatDelayH = (h, fa) => {
  if (!h || h === 0) return 'فوری';
  if (h < 24) return `${fa(h)} ساعت`;
  if (h % 24 === 0) return `${fa(h / 24)} روز`;
  return `${fa(h)} ساعت`;
};

// ─── FuModal ───────────────────────────────────────────────
const FuModal = ({ onClose, title, children, maxWidth = 480 }) => (
  <div onClick={e => e.target === e.currentTarget && onClose()}
    style={{ position:'fixed', inset:0, background:'rgba(0,0,0,0.7)', zIndex:1000, display:'flex', alignItems:'center', justifyContent:'center', padding:16 }}>
    <div className="card" style={{ width:'100%', maxWidth, maxHeight:'92vh', overflowY:'auto', padding:24 }}>
      <div style={{ display:'flex', justifyContent:'space-between', alignItems:'center', marginBottom:20 }}>
        <div className="semi" style={{ fontSize:15 }}>{title}</div>
        <button onClick={onClose} style={{ border:'none', background:'none', color:'var(--text-3)', cursor:'pointer', fontSize:20 }}>✕</button>
      </div>
      {children}
    </div>
  </div>
);

// ─── کارت یک فالوآپ ─────────────────────────────────────
const FollowupCard = ({ rule, steps, perf, onToggle, onDelete, onEdit, fa }) => {
  const tr = FU_TRIGGERS.find(t => t.id === rule.trigger_event) || { icon:'⚡', label: rule.trigger_event, color:'#6366F1' };
  const step = steps?.[0];
  const delayLabel = step
    ? formatDelayH(+step.delay_hours, fa)
    : formatDelayH(rule.trigger_delay_h, fa);

  const p = perf || { sent:0, answered:0, rate:0 };
  const rateColor = p.sent === 0 ? '#64748B' : p.rate >= 30 ? '#34D399' : p.rate >= 10 ? '#FBBF24' : '#F87171';
  const rateLabel = p.sent === 0 ? '—' : `${fa(p.rate)}٪`;

  return (
    <div className="card" style={{ padding:'14px 18px', display:'flex', alignItems:'center', gap:14,
      opacity: rule.is_active ? 1 : 0.5, borderRight: `3px solid ${tr.color}` }}>
      <div style={{ fontSize:24, flexShrink:0 }}>{tr.icon}</div>

      <div style={{ flex:1, minWidth:0 }}>
        <div style={{ fontSize:13, fontWeight:600, color:'var(--text-1)', marginBottom:4 }}>{rule.name}</div>
        <div style={{ display:'flex', gap:8, alignItems:'center', flexWrap:'wrap' }}>
          <span style={{ fontSize:11, padding:'2px 8px', borderRadius:20, background:`${tr.color}18`, color:tr.color }}>
            {tr.label}
          </span>
          <span style={{ fontSize:11, color:'var(--text-3)' }}>⏱ {delayLabel}</span>
        </div>
        {(() => {
          let ad = step?.action_data || {};
          if (typeof ad === 'string') { try { ad = JSON.parse(ad); } catch {} }
          const preview =
            step?.template_content ? step.template_content :
            step?.action_type === 'handoff_script' ? `🔀 سپردن به اسکریپت` :
            step?.action_type === 'send_file'       ? `📎 ارسال فایل` :
            step?.action_type === 'send_mixed'      ? `🖼 ${ad.text ? ad.text.slice(0,50) : 'متن + فایل'}` :
            ad.text ? ad.text : null;
          return preview ? (
            <div style={{ fontSize:11, color:'var(--text-3)', marginTop:4, overflow:'hidden', textOverflow:'ellipsis', whiteSpace:'nowrap', maxWidth:360 }}>
              {preview.slice(0,80)}{preview.length > 80 ? '…' : ''}
            </div>
          ) : null;
        })()}
      </div>

      {/* آمار عملکرد */}
      <div style={{ display:'flex', gap:12, flexShrink:0, alignItems:'center' }}>
        <div style={{ textAlign:'center', minWidth:44 }}>
          <div style={{ fontFamily:'JetBrains Mono', fontSize:13, fontWeight:700, color:'var(--text-2)' }}>{fa(p.sent)}</div>
          <div style={{ fontSize:10, color:'var(--text-3)' }}>ارسال</div>
        </div>
        <div style={{ textAlign:'center', minWidth:44 }}>
          <div style={{ fontFamily:'JetBrains Mono', fontSize:13, fontWeight:700, color:rateColor }}>{rateLabel}</div>
          <div style={{ fontSize:10, color:'var(--text-3)' }}>پاسخ</div>
        </div>
      </div>

      <div style={{ display:'flex', alignItems:'center', gap:6, flexShrink:0 }}>
        <button onClick={() => onEdit(rule, step)} title="ویرایش"
          style={{ border:'none', background:'rgba(255,255,255,0.05)', borderRadius:7, width:30, height:30, cursor:'pointer', color:'var(--text-3)', fontSize:13 }}>✏️</button>
        <button onClick={() => onToggle(rule)} title={rule.is_active ? 'غیرفعال کن' : 'فعال کن'}
          style={{ border:'none', borderRadius:7, width:30, height:30, cursor:'pointer', fontSize:13,
            background: rule.is_active ? 'rgba(99,102,241,0.15)' : 'rgba(255,255,255,0.05)',
            color: rule.is_active ? '#6366F1' : '#6B7280' }}>
          {rule.is_active ? '✓' : '○'}
        </button>
        <button onClick={() => onDelete(rule.id)} title="حذف"
          style={{ border:'none', background:'rgba(248,113,113,0.08)', borderRadius:7, width:30, height:30, cursor:'pointer', color:'#F87171', fontSize:13 }}>🗑</button>
      </div>
    </div>
  );
};

// ─── ویزارد ساخت / ویرایش فالوآپ ────────────────────────
const FollowupWizard = ({ onClose, onSave, initial, headers, toast, fa }) => {
  const isEdit = !!initial;
  const [step,    setStep]    = useState(isEdit ? 2 : 1);
  const [trigger, setTrigger] = useState(initial?.trigger || 'script_drop');
  const [name,    setName]    = useState(initial?.name || '');
  const [saving,  setSaving]  = useState(false);

  // delay: عدد + واحد
  const initH = initial?.delay ?? 24;
  const [delayNum,  setDelayNum]  = useState(initH >= 24 && initH % 24 === 0 ? initH / 24 : initH);
  const [delayUnit, setDelayUnit] = useState(initH >= 24 && initH % 24 === 0 ? 'days' : 'hours');
  const delayHours = delayUnit === 'days' ? delayNum * 24 : Number(delayNum);

  // نوع پیام
  const [msgType, setMsgType] = useState(initial?.msgType || 'text');
  const [msg,     setMsg]     = useState(initial?.msg || '');

  // برای state_stuck: انتخاب اسکریپت و استیت
  const [scripts,           setScripts]           = useState([]);
  const [statesList,        setStatesList]         = useState([]);
  const [selectedScriptId,  setSelectedScriptId]   = useState(initial?.trigger_script_id  || '');
  const [selectedStateId,   setSelectedStateId]    = useState(initial?.trigger_state_id   || '');
  const [selectedStateName, setSelectedStateName]  = useState(initial?.trigger_state_name || '');

  // برای فایل / mixed
  const [libFiles,       setLibFiles]       = useState([]);
  const [selectedFileId, setSelectedFileId] = useState(initial?.file_id || '');

  // برای handoff_script
  const [handoffScriptId,  setHandoffScriptId]  = useState(initial?.handoff_script_id || '');
  const [openingMessage,   setOpeningMessage]   = useState(initial?.opening_message   || '');

  const selectedTr = FU_TRIGGERS.find(t => t.id === trigger);

  // بارگذاری اسکریپت‌ها
  useEffect(() => {
    if (trigger === 'state_stuck' || msgType === 'handoff_script') {
      fetch('/api/scripts', { headers }).then(r => r.json()).then(d => {
        if (d.success) setScripts(d.data?.scripts || []);
      });
    }
  }, [trigger, msgType]);

  // بارگذاری استیت‌های اسکریپت انتخابی
  useEffect(() => {
    if (selectedScriptId) {
      fetch(`/api/scripts/${selectedScriptId}/map`, { headers })
        .then(r => r.json()).then(d => {
          if (d.success) setStatesList(d.data?.states || []);
        });
    } else { setStatesList([]); }
  }, [selectedScriptId]);

  // بارگذاری فایل‌های کتابخانه (گروه‌بندی‌شده با نام collection)
  useEffect(() => {
    if (msgType === 'file' || msgType === 'mixed') {
      fetch('/api/library/picker', { headers }).then(r => r.json()).then(d => {
        setLibFiles(d.data?.groups || []);
      }).catch(() => {});
    }
  }, [msgType]);

  const save = async () => {
    setSaving(true);
    try {
      const delayLabel = delayHours === 0 ? 'فوری'
        : delayUnit === 'days' ? `${delayNum} روز` : `${delayNum} ساعت`;
      const autoName = name.trim() || `${selectedTr?.label} — ${delayLabel}`;

      if (isEdit) {
        await window.api(`/followup/rules/${initial.ruleId}`, {
          method: 'PUT', body: {
            name: autoName, trigger_event: trigger,
            trigger_script_id: selectedScriptId,
            trigger_state_id: selectedStateId,
            trigger_state_name: selectedStateName,
          }
        });
        if (initial.templateId && msg.trim()) {
          await window.api(`/followup/templates/${initial.templateId}`, {
            method: 'PUT', body: { name: autoName, content: msg }
          });
        }
        if (initial.stepId) {
          const stepUpdate = { delay_hours: delayHours };
          if (msgType === 'file') {
            stepUpdate.action_data = { file_id: selectedFileId };
          } else if (msgType === 'mixed') {
            stepUpdate.action_data = { text: msg, file_id: selectedFileId };
          } else if (msgType === 'handoff_script') {
            stepUpdate.action_data = { script_id: handoffScriptId, opening_message: openingMessage };
          } else if (msgType === 'text' && !initial.templateId) {
            stepUpdate.action_data = { text: msg };
          }
          await window.api(`/followup/steps/${initial.stepId}`, {
            method: 'PUT', body: stepUpdate
          });
        }
      } else {
        const rule = await window.api('/followup/rules', {
          method: 'POST', body: {
            name: autoName, trigger_event: trigger, trigger_delay_h: 0,
            stop_conditions: ['became_buyer', 'replied'], aftermath: 'nothing',
            trigger_script_id: selectedScriptId,
            trigger_state_id:  selectedStateId,
            trigger_state_name: selectedStateName,
          }
        });
        if (!rule.success) throw new Error(rule.error || 'خطا در ساخت قانون');

        let stepBody = { delay_hours: delayHours };

        if (msgType === 'text') {
          if (!msg.trim()) { toast('متن پیام الزامیه', 'error'); setSaving(false); return; }
          const tmpl = await window.api('/followup/templates', {
            method: 'POST', body: { name: autoName, content: msg, category: 'followup' }
          });
          if (!tmpl.success) throw new Error(tmpl.error);
          stepBody.action_type = 'send_message';
          stepBody.template_id = tmpl.data.id;
        } else if (msgType === 'file') {
          if (!selectedFileId) { toast('یک فایل انتخاب کن', 'error'); setSaving(false); return; }
          stepBody.action_type = 'send_file';
          stepBody.action_data = { file_id: selectedFileId };
        } else if (msgType === 'mixed') {
          stepBody.action_type = 'send_mixed';
          stepBody.action_data = { text: msg, file_id: selectedFileId };
        } else if (msgType === 'handoff_script') {
          if (!handoffScriptId) { toast('یک اسکریپت انتخاب کن', 'error'); setSaving(false); return; }
          stepBody.action_type = 'handoff_script';
          stepBody.action_data = { script_id: handoffScriptId, opening_message: openingMessage };
        }

        await window.api(`/followup/rules/${rule.data.id}/steps`, {
          method: 'POST', body: stepBody
        });
      }
      onSave();
    } catch (e) { toast('خطا: ' + e.message, 'error'); }
    finally { setSaving(false); }
  };

  return (
    <FuModal onClose={onClose} title={isEdit ? 'ویرایش فالوآپ' : 'فالوآپ جدید'} maxWidth={540}>

      {/* Step 1: انتخاب trigger */}
      {step === 1 && (
        <div>
          <div style={{ fontSize:12, color:'var(--text-3)', marginBottom:14 }}>
            این فالوآپ <strong style={{color:'var(--text-1)'}}>کِی</strong> ارسال بشه؟
          </div>
          <div style={{ display:'grid', gridTemplateColumns:'1fr 1fr', gap:8 }}>
            {FU_TRIGGERS.map(tr => (
              <div key={tr.id} onClick={() => setTrigger(tr.id)}
                style={{ padding:'12px 14px', borderRadius:10, cursor:'pointer', transition:'all .15s',
                  border: `2px solid ${trigger === tr.id ? tr.color : 'rgba(255,255,255,0.07)'}`,
                  background: trigger === tr.id ? `${tr.color}12` : 'var(--bg-2)' }}>
                <div style={{ fontSize:20, marginBottom:5 }}>{tr.icon}</div>
                <div style={{ fontSize:12, fontWeight:600, color: trigger === tr.id ? tr.color : 'var(--text-1)', marginBottom:2 }}>{tr.label}</div>
                <div style={{ fontSize:10, color:'var(--text-3)', lineHeight:1.4 }}>{tr.desc}</div>
              </div>
            ))}
          </div>

          <div style={{ marginTop:20, display:'flex', justifyContent:'flex-end' }}>
            <button className="btn btn-primary" onClick={() => setStep(2)}>بعدی ←</button>
          </div>
        </div>
      )}

      {/* Step 2: تأخیر + نوع پیام + محتوا */}
      {step === 2 && (
        <div style={{ display:'flex', flexDirection:'column', gap:16 }}>
          {/* trigger summary */}
          {!isEdit && (
            <div style={{ display:'flex', alignItems:'center', gap:10, padding:'10px 14px', borderRadius:9,
              background:`${selectedTr?.color}12`, border:`1px solid ${selectedTr?.color}30` }}>
              <span style={{ fontSize:20 }}>{selectedTr?.icon}</span>
              <div>
                <div style={{ fontSize:12, fontWeight:600, color: selectedTr?.color }}>{selectedTr?.label}</div>
                <button onClick={() => setStep(1)}
                  style={{ fontSize:10, color:'var(--text-3)', background:'none', border:'none', cursor:'pointer', padding:0 }}>
                  تغییر ←
                </button>
              </div>
            </div>
          )}

          {/* state_stuck: انتخاب اسکریپت + استیت */}
          {trigger === 'state_stuck' && (
            <div style={{ padding:'14px', borderRadius:10,
              background:'rgba(139,92,246,0.06)', border:'1px solid rgba(139,92,246,0.2)' }}>
              <div style={{ fontSize:12, color:'#A78BFA', marginBottom:10 }}>
                📍 لید در کدام مرحله گیر کرده؟
                <span style={{ fontSize:10, color:'var(--text-3)', marginRight:6 }}>(اختیاری — خالی = همه مراحل)</span>
              </div>
              <div style={{ display:'flex', flexDirection:'column', gap:8 }}>
                <select value={selectedScriptId}
                  onChange={e => { setSelectedScriptId(e.target.value); setSelectedStateId(''); setSelectedStateName(''); }}
                  className="input">
                  <option value=''>— همه اسکریپت‌ها —</option>
                  {scripts.map(s => <option key={s.id} value={s.id}>{s.title || s.name}</option>)}
                </select>
                {selectedScriptId && statesList.length === 0 && (
                  <div style={{ fontSize:11, color:'#F59E0B', padding:'8px 12px', borderRadius:8,
                    background:'rgba(245,158,11,0.08)', border:'1px solid rgba(245,158,11,0.2)' }}>
                    ⚠️ این اسکریپت مرحله‌ای ندارد — ابتدا از بخش اسکریپت، نقشه مراحل را بساز
                  </div>
                )}
                {selectedScriptId && statesList.length > 0 && (
                  <select value={selectedStateId}
                    onChange={e => {
                      const st = statesList.find(s => String(s.id) === e.target.value);
                      setSelectedStateId(e.target.value);
                      setSelectedStateName(st?.name || '');
                    }}
                    className="input">
                    <option value=''>— همه مراحل —</option>
                    {statesList.map(s => <option key={s.id} value={s.id}>{s.name}</option>)}
                  </select>
                )}
              </div>
            </div>
          )}

          {/* تأخیر — ورودی دستی */}
          <div>
            <div style={{ fontSize:12, color:'var(--text-3)', marginBottom:8 }}>⏱ چند وقت بعد از trigger ارسال بشه؟</div>
            <div style={{ display:'flex', gap:8, alignItems:'center' }}>
              <input type="number" min="0" max="999" value={delayNum}
                onChange={e => setDelayNum(Math.max(0, Number(e.target.value)))}
                className="input" style={{ width:80, textAlign:'center' }} />
              {[{v:'hours',l:'ساعت'},{v:'days',l:'روز'}].map(u => (
                <button key={u.v} onClick={() => setDelayUnit(u.v)}
                  style={{ padding:'7px 16px', borderRadius:8, border:'none', cursor:'pointer',
                    fontSize:12, fontFamily:'inherit',
                    background: delayUnit === u.v ? '#6366F1' : 'var(--bg-2)',
                    color: delayUnit === u.v ? '#fff' : 'var(--text-2)' }}>
                  {u.l}
                </button>
              ))}
              {delayNum === 0 && <span style={{ fontSize:11, color:'#FBBF24' }}>← فوری</span>}
            </div>
          </div>

          {/* نوع اقدام */}
          <div>
            <div style={{ fontSize:12, color:'var(--text-3)', marginBottom:8 }}>📨 نوع اقدام</div>
            <div style={{ display:'flex', gap:6, flexWrap:'wrap' }}>
              {[
                { id:'text',           icon:'💬', label:'متن' },
                { id:'file',           icon:'📎', label:'فایل' },
                { id:'mixed',          icon:'🖼',  label:'متن + فایل' },
                { id:'handoff_script', icon:'🔀', label:'سپردن به اسکریپت' },
              ].map(t => (
                <button key={t.id} onClick={() => setMsgType(t.id)}
                  style={{ padding:'7px 14px', borderRadius:8, border:'none', cursor:'pointer',
                    fontSize:12, fontFamily:'inherit',
                    background: msgType === t.id ? '#6366F1' : 'var(--bg-2)',
                    color: msgType === t.id ? '#fff' : 'var(--text-2)' }}>
                  {t.icon} {t.label}
                </button>
              ))}
            </div>
          </div>

          {/* متن پیام */}
          {(msgType === 'text' || msgType === 'mixed') && (
            <div>
              <div style={{ display:'flex', justifyContent:'space-between', alignItems:'center', marginBottom:6 }}>
                <div style={{ fontSize:12, color:'var(--text-3)' }}>💬 متن پیام</div>
                <div style={{ display:'flex', gap:6 }}>
                  {['دوستانه','فوری','ملایم'].map((t,i) => {
                    const toneId = ['friendly','urgent','soft'][i];
                    return (
                      <button key={toneId} disabled={saving}
                        onClick={async () => {
                          setSaving(true);
                          try {
                            const r = await window.api('/followup/generate-message', {
                              method:'POST', body:{ trigger_event: trigger, tone: toneId }
                            });
                            if (r.success) setMsg(r.data.message);
                          } finally { setSaving(false); }
                        }}
                        style={{ fontSize:10, padding:'3px 8px', borderRadius:6, border:'1px solid rgba(99,102,241,0.4)',
                          background:'rgba(99,102,241,0.08)', color:'#818CF8', cursor:'pointer', fontFamily:'inherit' }}>
                        ✨ {t}
                      </button>
                    );
                  })}
                </div>
              </div>
              <textarea className="input" rows={4} value={msg} onChange={e => setMsg(e.target.value)}
                placeholder={'سلام {{name}} 👋\nمی‌خواستم بدونم سوالی نداری؟'}
                style={{ resize:'vertical', fontFamily:'inherit', fontSize:13, lineHeight:1.8, width:'100%' }} />
              <div style={{ fontSize:10, color:'#94A3B8', marginTop:4 }}>متغیرها: {'{{name}}'} — نام لید</div>
            </div>
          )}

          {/* فایل از کتابخانه */}
          {(msgType === 'file' || msgType === 'mixed') && (
            <div>
              <div style={{ fontSize:12, color:'var(--text-3)', marginBottom:8 }}>📎 انتخاب فایل از کتابخانه</div>
              {libFiles.length === 0 ? (
                <div style={{ fontSize:12, color:'var(--text-3)', padding:'12px', borderRadius:8, background:'var(--bg-2)' }}>
                  در حال بارگذاری…
                </div>
              ) : (
                <>
                  <select value={selectedFileId} onChange={e => setSelectedFileId(e.target.value)} className="input">
                    <option value=''>— یک فایل انتخاب کنید —</option>
                    {libFiles.map(grp => (
                      <optgroup key={grp.id} label={`📁 ${grp.name}`}>
                        {grp.files.map(f => {
                          const icon = f.file_type === 'video' ? '🎬' : f.file_type === 'image' ? '🖼' : f.file_type === 'audio' ? '🎵' : f.file_type === 'pdf' ? '📄' : '📎';
                          return <option key={f.id} value={f.id}>{icon} {f.display}</option>;
                        })}
                      </optgroup>
                    ))}
                  </select>
                  {selectedFileId && (() => {
                    const found = libFiles.flatMap(g => g.files).find(f => f.id === selectedFileId);
                    return found ? (
                      <div style={{ marginTop:6, fontSize:11, color:'#34D399', padding:'5px 10px',
                        borderRadius:7, background:'rgba(52,211,153,0.08)', border:'1px solid rgba(52,211,153,0.2)' }}>
                        ✓ {found.display}
                      </div>
                    ) : null;
                  })()}
                </>
              )}
            </div>
          )}

          {/* سپردن به اسکریپت */}
          {msgType === 'handoff_script' && (
            <div style={{ display:'flex', flexDirection:'column', gap:12 }}>
              <div>
                <div style={{ fontSize:12, color:'var(--text-3)', marginBottom:8 }}>🔀 اسکریپت مقصد</div>
                <select value={handoffScriptId} onChange={e => setHandoffScriptId(e.target.value)} className="input">
                  <option value=''>— اسکریپت را انتخاب کنید —</option>
                  {scripts.map(s => <option key={s.id} value={s.id}>{s.title || s.name}</option>)}
                </select>
              </div>
              <div>
                <div style={{ fontSize:12, color:'var(--text-3)', marginBottom:6 }}>✉️ پیام شروع (ارسال توسط فالوآپ)</div>
                <textarea className="input" rows={4} value={openingMessage} onChange={e => setOpeningMessage(e.target.value)}
                  placeholder={'سلام {{name}} 👋\nبرگشتید! خوشحالم که دوباره باهاتون صحبت کنم...'}
                  style={{ resize:'vertical', fontFamily:'inherit', fontSize:13, lineHeight:1.8, width:'100%' }} />
                <div style={{ fontSize:10, color:'#94A3B8', marginTop:4 }}>
                  بعد از این پیام، اسکریپت مقصد کنترل مکالمه رو می‌گیره
                </div>
              </div>
            </div>
          )}

          {/* نام */}
          <div>
            <div style={{ fontSize:12, color:'var(--text-3)', marginBottom:6 }}>نام (اختیاری)</div>
            <input className="input" value={name} onChange={e => setName(e.target.value)}
              placeholder={`${selectedTr?.label} — خودکار`} />
          </div>

          <div style={{ display:'flex', gap:8, justifyContent:'flex-end', marginTop:4 }}>
            {!isEdit && <button className="btn btn-ghost" onClick={() => setStep(1)}>← قبلی</button>}
            <button className="btn btn-ghost" onClick={onClose}>انصراف</button>
            <button className="btn btn-primary" onClick={save} disabled={saving}>
              {saving ? '...' : (isEdit ? '💾 ذخیره' : '✅ ساخت فالوآپ')}
            </button>
          </div>
        </div>
      )}
    </FuModal>
  );
};

// ─── FuModal جزئیات یک فالوآپ ──────────────────────────────
const DetailModal = ({ rule, step, perf, headers, fa, onClose }) => {
  const [log,      setLog]      = useState([]);
  const [loading,  setLoading]  = useState(true);
  const [dropData, setDropData] = useState(null);
  const isScriptDrop = rule.trigger_event === 'script_drop';

  const tr = FU_TRIGGERS.find(t => t.id === rule.trigger_event) || { icon:'⚡', label: rule.trigger_event, color:'#6366F1' };
  const p = perf || { sent:0, answered:0, rate:0 };
  const rateColor = p.sent === 0 ? '#64748B' : p.rate >= 30 ? '#34D399' : p.rate >= 10 ? '#FBBF24' : '#F87171';

  const rC = { answered:'#34D399', no_response:'#6B7280', bounced:'#F87171' };
  const rL = { answered:'✅ پاسخ داد', no_response:'— جواب نداد', bounced:'❌ برگشت' };

  useEffect(() => {
    const p1 = fetch(`/api/followup/log?rule_id=${rule.id}&limit=100`, { headers })
      .then(r => r.json()).then(d => { if (d.success) setLog(d.data); });
    const p2 = isScriptDrop
      ? fetch(`/api/followup/drop-analysis/${rule.id}`, { headers })
          .then(r => r.json()).then(d => { if (d.success) setDropData(d.data); })
      : Promise.resolve();
    Promise.all([p1, p2]).finally(() => setLoading(false));
  }, [rule.id]);

  const noResp = log.filter(r => !r.response_type || r.response_type === 'no_response').length;

  return (
    <FuModal onClose={onClose} title="" maxWidth={600}>
      {/* هدر */}
      <div style={{ display:'flex', alignItems:'center', gap:14, marginBottom:20,
        padding:'14px 16px', borderRadius:12, background:`${tr.color}10`, border:`1px solid ${tr.color}25` }}>
        <div style={{ fontSize:32 }}>{tr.icon}</div>
        <div style={{ flex:1 }}>
          <div style={{ fontSize:15, fontWeight:700, color:'var(--text-1)' }}>{rule.name}</div>
          <div style={{ fontSize:12, color:tr.color, marginTop:2 }}>{tr.label}</div>
        </div>
        <div style={{ textAlign:'center' }}>
          <div style={{ fontFamily:'JetBrains Mono', fontSize:28, fontWeight:800, color:rateColor, lineHeight:1 }}>
            {p.sent === 0 ? '—' : `${fa(p.rate)}٪`}
          </div>
          <div style={{ fontSize:10, color:'var(--text-3)', marginTop:2 }}>نرخ پاسخ</div>
        </div>
      </div>

      {/* آمار */}
      <div style={{ display:'grid', gridTemplateColumns:'repeat(3,1fr)', gap:8, marginBottom:20 }}>
        {[
          { label:'ارسال شده', val: fa(p.sent),     color:'var(--text-2)' },
          { label:'پاسخ داد',  val: fa(p.answered), color:'#34D399' },
          { label:'جواب نداد', val: fa(noResp),      color:'#6B7280' },
        ].map(s => (
          <div key={s.label} style={{ padding:'12px', borderRadius:10, background:'var(--bg-2)', textAlign:'center' }}>
            <div style={{ fontFamily:'JetBrains Mono', fontSize:18, fontWeight:700, color:s.color }}>{s.val}</div>
            <div style={{ fontSize:11, color:'var(--text-3)', marginTop:3 }}>{s.label}</div>
          </div>
        ))}
      </div>

      {/* متن پیام */}
      {step?.template_content && (
        <div style={{ marginBottom:20 }}>
          <div style={{ fontSize:11, color:'var(--text-3)', marginBottom:6 }}>📨 متن پیام</div>
          <div style={{ padding:'12px 14px', borderRadius:10, background:'var(--bg-2)',
            fontSize:12, lineHeight:1.8, color:'var(--text-2)', whiteSpace:'pre-wrap',
            borderRight:'3px solid #6366F1' }}>
            {step.template_content}
          </div>
        </div>
      )}

      {/* آنالیز مرحله رها شدن — فقط script_drop */}
      {isScriptDrop && dropData && dropData.total > 0 && (
        <div style={{ marginBottom:20 }}>
          <div style={{ fontSize:11, color:'var(--text-3)', marginBottom:8 }}>
            🚪 در کدام مرحله رها کردند؟
            <span style={{ marginRight:8, color:'#FBBF24' }}>
              (میانگین: مرحله {fa(dropData.avg_step)})
            </span>
          </div>
          <div style={{ display:'flex', flexDirection:'column', gap:6 }}>
            {dropData.chart.map(row => {
              const pct = Math.round(row.count / dropData.total * 100);
              return (
                <div key={row.step} style={{ display:'flex', alignItems:'center', gap:10 }}>
                  <div style={{ fontSize:11, color:'var(--text-2)', width:60, flexShrink:0, textAlign:'right' }}>
                    مرحله {fa(row.step)}
                  </div>
                  <div style={{ flex:1, height:20, borderRadius:5, background:'rgba(255,255,255,0.05)', overflow:'hidden', position:'relative' }}>
                    <div style={{ height:'100%', width:`${pct}%`, borderRadius:5,
                      background: row.step <= 2 ? '#F59E0B' : row.step <= 4 ? '#6366F1' : '#64748B',
                      transition:'width .4s' }} />
                    <div style={{ position:'absolute', inset:0, display:'flex', alignItems:'center', paddingRight:8,
                      fontSize:10, color:'rgba(255,255,255,0.7)', fontFamily:'JetBrains Mono' }}>
                      {fa(row.count)} نفر ({fa(pct)}٪)
                    </div>
                  </div>
                </div>
              );
            })}
          </div>
          {/* آخرین پیام بی‌پاسخ */}
          {dropData.details.length > 0 && dropData.details[0].last_bot_msg && (
            <div style={{ marginTop:10, padding:'10px 12px', borderRadius:8, background:'rgba(245,158,11,0.06)',
              border:'1px solid rgba(245,158,11,0.2)', fontSize:11, color:'var(--text-2)', lineHeight:1.6 }}>
              <div style={{ fontSize:10, color:'#FBBF24', marginBottom:4 }}>آخرین پیام ربات قبل از رها شدن:</div>
              «{dropData.details[0].last_bot_msg}»
            </div>
          )}
        </div>
      )}

      {/* لیست لیدها */}
      <div style={{ fontSize:11, color:'var(--text-3)', marginBottom:8 }}>👥 لیدهایی که این پیام رو گرفتند</div>
      {loading ? (
        <div style={{ textAlign:'center', padding:30, color:'var(--text-3)' }}>در حال بارگذاری...</div>
      ) : log.length === 0 ? (
        <div style={{ textAlign:'center', padding:30, color:'var(--text-3)', fontSize:12 }}>📭 هنوز پیامی ارسال نشده</div>
      ) : (
        <div style={{ borderRadius:10, overflow:'hidden', border:'1px solid rgba(255,255,255,0.06)' }}>
          {log.map((r, i) => (
            <div key={r.id} style={{ display:'flex', alignItems:'center', gap:10, padding:'10px 14px',
              background: i % 2 === 0 ? 'transparent' : 'rgba(255,255,255,0.02)',
              borderBottom: i < log.length-1 ? '1px solid rgba(255,255,255,0.04)' : 'none' }}>
              <div style={{ width:8, height:8, borderRadius:'50%', flexShrink:0,
                background: rC[r.response_type] || '#6B7280' }} />
              <div style={{ flex:1, minWidth:0 }}>
                <div style={{ fontSize:12, fontWeight:600, color:'var(--text-1)' }}>{r.lead_name || '—'}</div>
                {r.lead_phone && <div style={{ fontSize:10, color:'var(--text-3)', fontFamily:'JetBrains Mono' }}>{r.lead_phone}</div>}
              </div>
              <div style={{ fontSize:11, color: rC[r.response_type]||'#6B7280', flexShrink:0 }}>
                {rL[r.response_type] || '—'}
              </div>
              <div style={{ fontSize:10, color:'var(--text-3)', fontFamily:'JetBrains Mono', flexShrink:0 }}>
                {r.sent_at?.slice(5,16) || '—'}
              </div>
            </div>
          ))}
        </div>
      )}
    </FuModal>
  );
};

// ─── تب گزارش ────────────────────────────────────────────
const ReportTab = ({ headers, rules, steps, perf, fa }) => {
  const [selected, setSelected] = useState(null); // rule برای FuModal

  const ranked = [...rules]
    .map(r => ({ ...r, p: perf[r.id] || { sent:0, answered:0, rate:0 } }))
    .sort((a,b) => b.p.rate - a.p.rate);

  const withData    = ranked.filter(r => r.p.sent > 0);
  const withoutData = ranked.filter(r => r.p.sent === 0);

  const RuleRow = ({ r, i }) => {
    const tr = FU_TRIGGERS.find(t => t.id === r.trigger_event) || { icon:'⚡', color:'#6366F1' };
    const rateColor = r.p.rate >= 30 ? '#34D399' : r.p.rate >= 10 ? '#FBBF24' : '#F87171';
    const medal = i === 0 ? '🥇' : i === 1 ? '🥈' : i === 2 ? '🥉' : null;

    return (
      <div onClick={() => setSelected(r)}
        style={{ display:'flex', alignItems:'center', gap:12, padding:'13px 18px', cursor:'pointer',
          borderBottom:'1px solid rgba(255,255,255,0.04)', transition:'background .15s' }}
        onMouseEnter={e => e.currentTarget.style.background='rgba(255,255,255,0.03)'}
        onMouseLeave={e => e.currentTarget.style.background='transparent'}>

        <div style={{ width:22, textAlign:'center', fontSize:14, color:'var(--text-3)', flexShrink:0 }}>
          {medal || <span style={{ fontFamily:'JetBrains Mono', fontSize:11 }}>{fa(i+1)}</span>}
        </div>
        <div style={{ fontSize:20, flexShrink:0 }}>{tr.icon}</div>

        <div style={{ flex:1, minWidth:0 }}>
          <div style={{ fontSize:13, fontWeight:600, color:'var(--text-1)' }}>{r.name}</div>
          <div style={{ display:'flex', alignItems:'center', gap:8, marginTop:5 }}>
            <div style={{ flex:1, height:5, borderRadius:3, background:'rgba(255,255,255,0.07)', overflow:'hidden' }}>
              <div style={{ height:'100%', width:`${Math.min(100, r.p.rate * 2.5)}%`,
                borderRadius:3, background:rateColor, transition:'width .5s' }} />
            </div>
            <span style={{ fontSize:10, color:'var(--text-3)', flexShrink:0 }}>
              {fa(r.p.answered)}/{fa(r.p.sent)} پاسخ
            </span>
          </div>
        </div>

        <div style={{ textAlign:'left', flexShrink:0, minWidth:48 }}>
          <div style={{ fontFamily:'JetBrains Mono', fontSize:16, fontWeight:800, color:rateColor }}>{fa(r.p.rate)}٪</div>
        </div>
        <div style={{ color:'var(--text-3)', fontSize:12 }}>←</div>
      </div>
    );
  };

  return (
    <div>
      {/* راهنما */}
      <div style={{ display:'flex', gap:16, marginBottom:20, fontSize:11, color:'var(--text-3)' }}>
        <span>🟢 ۳۰٪+ عالی</span>
        <span>🟡 ۱۰–۳۰٪ قابل قبول</span>
        <span>🔴 زیر ۱۰٪ نیاز به بازنویسی</span>
        <span style={{ marginRight:'auto' }}>روی هر ردیف کلیک کن جزئیات ببینی</span>
      </div>

      {withData.length === 0 && withoutData.length === 0 ? (
        <div className="card" style={{ textAlign:'center', padding:60, color:'var(--text-3)' }}>
          <div style={{ fontSize:40, marginBottom:10 }}>📊</div>
          هنوز هیچ فالوآپی ارسال نشده
        </div>
      ) : (
        <>
          {withData.length > 0 && (
            <div className="card" style={{ padding:0, overflow:'hidden', marginBottom:16 }}>
              <div style={{ padding:'12px 18px', borderBottom:'1px solid rgba(255,255,255,0.06)',
                fontSize:12, fontWeight:600, color:'var(--text-2)' }}>
                فالوآپ‌هایی که ارسال شدند ({fa(withData.length)})
              </div>
              {withData.map((r, i) => <RuleRow key={r.id} r={r} i={i} />)}
            </div>
          )}

          {withoutData.length > 0 && (
            <div className="card" style={{ padding:0, overflow:'hidden' }}>
              <div style={{ padding:'12px 18px', borderBottom:'1px solid rgba(255,255,255,0.06)',
                fontSize:12, fontWeight:600, color:'var(--text-3)' }}>
                فالوآپ‌هایی که هنوز trigger نشدند ({fa(withoutData.length)})
              </div>
              {withoutData.map((r, i) => {
                const tr = FU_TRIGGERS.find(t => t.id === r.trigger_event) || { icon:'⚡', color:'#6366F1' };
                return (
                  <div key={r.id} style={{ display:'flex', alignItems:'center', gap:12, padding:'12px 18px',
                    borderBottom:'1px solid rgba(255,255,255,0.04)', opacity:0.6 }}>
                    <div style={{ fontSize:18 }}>{tr.icon}</div>
                    <div style={{ flex:1 }}>
                      <div style={{ fontSize:12, color:'var(--text-2)' }}>{r.name}</div>
                    </div>
                    <div style={{ fontSize:10, color:'var(--text-3)' }}>هنوز ارسال نشده</div>
                  </div>
                );
              })}
            </div>
          )}
        </>
      )}

      {selected && (
        <DetailModal
          rule={selected} step={steps[selected.id]?.[0]}
          perf={perf[selected.id]} headers={headers} fa={fa}
          onClose={() => setSelected(null)} />
      )}
    </div>
  );
};

// ═══════════════════════════════════════════════════════
// ─── TasksTab (تسک‌های واحد فالوآپ) ─────────────────────
// ═══════════════════════════════════════════════════════
const KIND_META = {
  rule_step:             { label:'گام قانون',    icon:'⚙️', color:'#818CF8' },
  hook_message:          { label:'پیام زمان‌بند', icon:'⏱️', color:'#34D399' },
  reminder_call:         { label:'یادآور تماس',   icon:'📞', color:'#F472B6' },
  reminder_payment:      { label:'یادآور پرداخت', icon:'💳', color:'#FBBF24' },
  reminder_consultation: { label:'یادآور مشاوره', icon:'🗓️', color:'#60A5FA' },
  state_stuck:           { label:'گیر در مرحله',  icon:'📍', color:'#FB923C' },
  conversation_wait:     { label:'انتظار پاسخ',   icon:'💬', color:'#A78BFA' },
  campaign_step:         { label:'گام کمپین',     icon:'📣', color:'#22D3EE' },
  manual:                { label:'دستی',          icon:'✋', color:'#94A3B8' },
};

const TasksTab = ({ headers, fa }) => {
  const [items,   setItems]   = useState([]);
  const [stats,   setStats]   = useState(null);
  const [bucket,  setBucket]  = useState('');      // '' | overdue | today | upcoming
  const [status,  setStatus]  = useState('pending');
  const [loading, setLoading] = useState(true);

  const load = () => {
    setLoading(true);
    const qs = new URLSearchParams({ status, ...(bucket ? { bucket } : {}) }).toString();
    Promise.all([
      fetch(`/api/followup/tasks?${qs}`,   { headers }).then(r=>r.json()),
      fetch('/api/followup/tasks/stats',   { headers }).then(r=>r.json()),
    ]).then(([td, sd]) => {
      if (td.success) setItems(td.data.items || []);
      if (sd.success) setStats(sd.data);
    }).finally(() => setLoading(false));
  };
  useEffect(() => { load(); }, [bucket, status]);

  const setTaskStatus = (id, newStatus) => {
    fetch(`/api/followup/tasks/${id}`, { method:'PATCH', headers, body:JSON.stringify({ status:newStatus }) })
      .then(r=>r.json()).then(d => { if (d.success) load(); });
  };

  const fmtDue = (iso) => {
    if (!iso) return '—';
    const d = new Date(iso), now = new Date();
    const diffH = (d - now) / 3600000;
    const date = d.toLocaleDateString('fa-IR') + ' ' + d.toLocaleTimeString('fa-IR', { hour:'2-digit', minute:'2-digit' });
    if (diffH < 0)   return { txt:date, tag:'عقب‌افتاده', color:'#F87171' };
    if (diffH < 24)  return { txt:date, tag:'امروز',      color:'#FBBF24' };
    return { txt:date, tag:'آینده', color:'#60A5FA' };
  };

  return (
    <div>
      {/* آمار تسک */}
      {stats && (
        <div style={{ display:'flex', gap:10, marginBottom:16, flexWrap:'wrap' }}>
          {[
            { key:'',        label:'همه در صف', val:stats.pending, color:'#6366F1' },
            { key:'overdue', label:'عقب‌افتاده', val:stats.overdue, color:'#F87171' },
            { key:'today',   label:'امروز',      val:stats.today,   color:'#FBBF24' },
            { key:'upcoming',label:'آینده',      val:Math.max(0,(stats.pending||0)-(stats.overdue||0)-(stats.today||0)), color:'#60A5FA' },
          ].map(s => (
            <div key={s.label} onClick={() => setBucket(s.key)}
              className="card" style={{ padding:'12px 18px', flex:1, minWidth:110, cursor:'pointer',
                border: bucket===s.key ? `1px solid ${s.color}` : '1px solid transparent' }}>
              <div style={{ fontFamily:'JetBrains Mono', fontSize:20, fontWeight:700, color:s.color }}>{fa(s.val)}</div>
              <div style={{ fontSize:11, color:'var(--text-3)', marginTop:2 }}>{s.label}</div>
            </div>
          ))}
        </div>
      )}

      {/* فیلتر وضعیت */}
      <div style={{ display:'flex', gap:6, marginBottom:14 }}>
        {[
          { id:'pending', label:'در انتظار' },
          { id:'sent',    label:'ارسال‌شده' },
          { id:'done',    label:'انجام‌شده' },
          { id:'failed',  label:'ناموفق' },
          { id:'all',     label:'همه' },
        ].map(t => (
          <button key={t.id} onClick={() => setStatus(t.id)}
            style={{ padding:'5px 12px', borderRadius:7, border:'none', cursor:'pointer', fontFamily:'inherit', fontSize:11,
              background: status===t.id ? 'var(--surface)' : 'var(--bg-2)',
              color: status===t.id ? 'var(--text-1)' : 'var(--text-3)' }}>
            {t.label}
          </button>
        ))}
      </div>

      {loading ? (
        <div style={{ textAlign:'center', padding:60, color:'var(--text-3)' }}>در حال بارگذاری...</div>
      ) : items.length === 0 ? (
        <div className="card" style={{ textAlign:'center', padding:50 }}>
          <div style={{ fontSize:40, marginBottom:10 }}>🗂️</div>
          <div style={{ fontSize:13, color:'var(--text-3)' }}>تسکی در این فیلتر نیست</div>
        </div>
      ) : (
        <div style={{ display:'flex', flexDirection:'column', gap:6 }}>
          {items.map(t => {
            const meta = KIND_META[t.kind] || { label:t.kind, icon:'•', color:'#94A3B8' };
            const due = fmtDue(t.due_at);
            return (
              <div key={t.id} className="card" style={{ padding:'10px 14px', display:'flex', alignItems:'center', gap:12 }}>
                <div style={{ fontSize:20 }}>{meta.icon}</div>
                <div style={{ flex:1, minWidth:0 }}>
                  <div style={{ fontSize:13, fontWeight:600, color:'var(--text-1)' }}>
                    {t.title || meta.label}
                    <span style={{ fontSize:10, color:meta.color, marginRight:8, padding:'1px 7px',
                      borderRadius:5, background:'var(--bg-2)' }}>{meta.label}</span>
                  </div>
                  <div style={{ fontSize:11, color:'var(--text-3)', marginTop:3 }}>
                    {t.lead_name || t.lead_phone || t.lead_id}
                    {t.lead_status ? ` · ${t.lead_status}` : ''}
                  </div>
                </div>
                <div style={{ textAlign:'left', fontSize:11 }}>
                  {due.tag && <span style={{ color:due.color, fontWeight:600 }}>{due.tag}</span>}
                  <div style={{ color:'var(--text-3)', fontFamily:'JetBrains Mono', fontSize:10 }}>{due.txt}</div>
                </div>
                {t.status === 'pending' && (
                  <div style={{ display:'flex', gap:4 }}>
                    <button title="انجام شد" onClick={() => setTaskStatus(t.id,'done')}
                      style={{ border:'none', cursor:'pointer', borderRadius:6, padding:'4px 8px', background:'var(--bg-2)', color:'#34D399' }}>✓</button>
                    <button title="لغو" onClick={() => setTaskStatus(t.id,'cancelled')}
                      style={{ border:'none', cursor:'pointer', borderRadius:6, padding:'4px 8px', background:'var(--bg-2)', color:'#F87171' }}>✕</button>
                  </div>
                )}
                {t.status !== 'pending' && (
                  <span style={{ fontSize:10, color:'var(--text-3)', padding:'2px 8px', borderRadius:5, background:'var(--bg-2)' }}>{t.status}</span>
                )}
              </div>
            );
          })}
        </div>
      )}
    </div>
  );
};

// ═══════════════════════════════════════════════════════
// ─── FollowUp (root) ─────────────────────────────────────
// ═══════════════════════════════════════════════════════
const FollowUp = () => {
  const { useToast } = window.SB_UI;
  const { fa } = window.SB_DATA;
  const toast  = useToast();
  const token  = localStorage.getItem(window.TOKEN_KEY);
  const headers = { 'Content-Type':'application/json', Authorization:`Bearer ${token}` };

  const [mainTab, setMainTab] = window.useStickyState('tab_followup', 'list'); // list | report
  const [rules,   setRules]   = useState([]);
  const [steps,   setSteps]   = useState({});
  const [perf,    setPerf]    = useState({});
  const [stats,   setStats]   = useState(null);
  const [loading, setLoading] = useState(true);
  const [wizard,  setWizard]  = useState(null);

  const load = () => {
    setLoading(true);
    Promise.all([
      fetch('/api/followup/rules',        { headers }).then(r=>r.json()),
      fetch('/api/followup/stats',        { headers }).then(r=>r.json()),
      fetch('/api/followup/stats/per-rule',{ headers }).then(r=>r.json()),
    ]).then(([rd, sd, pd]) => {
      if (rd.success) {
        const ruleList = rd.data;
        setRules(ruleList);
        Promise.all(ruleList.map(r =>
          fetch(`/api/followup/rules/${r.id}`, { headers }).then(x=>x.json())
        )).then(details => {
          const map = {};
          details.forEach((d, i) => {
            if (d.success) map[ruleList[i].id] = d.data.steps || [];
          });
          setSteps(map);
        });
      }
      if (sd.success) setStats(sd.data);
      if (pd.success) setPerf(pd.data);
    }).finally(() => setLoading(false));
  };

  useEffect(() => { load(); }, []);

  const toggleActive = (rule) => {
    fetch(`/api/followup/rules/${rule.id}`, { method:'PUT', headers, body:JSON.stringify({ is_active: rule.is_active ? 0:1 }) })
      .then(r=>r.json()).then(d => {
        if (d.success) setRules(p => p.map(x => x.id===rule.id ? {...x, is_active: x.is_active?0:1} : x));
      });
  };

  const deleteRule = (id) => {
    if (!confirm('این فالوآپ حذف شود؟')) return;
    fetch(`/api/followup/rules/${id}`, { method:'DELETE', headers })
      .then(r=>r.json()).then(d => {
        if (d.success) { setRules(p => p.filter(x=>x.id!==id)); toast('حذف شد', 'success'); }
      });
  };

  const openEdit = (rule, step) => {
    let ad = step?.action_data || {};
    if (typeof ad === 'string') { try { ad = JSON.parse(ad); } catch {} }
    const at = step?.action_type || 'send_message';
    const msgType =
      at === 'send_file'        ? 'file' :
      at === 'send_mixed'       ? 'mixed' :
      at === 'handoff_script'   ? 'handoff_script' : 'text';

    setWizard({
      isEdit: true, ruleId: rule.id,
      trigger: rule.trigger_event, name: rule.name,
      delay: step?.delay_hours ?? 0,
      // متن
      msg: step?.template_content || ad.text || '',
      templateId: step?.template_id,
      stepId: step?.id,
      // نوع اقدام
      msgType,
      file_id:          ad.file_id        || '',
      handoff_script_id: ad.script_id     || '',
      opening_message:  ad.opening_message || '',
      // state_stuck
      trigger_script_id:  rule.trigger_script_id  || '',
      trigger_state_id:   rule.trigger_state_id   || '',
      trigger_state_name: rule.trigger_state_name || '',
    });
  };

  // آمار
  const active  = rules.filter(r => r.is_active).length;
  const total   = rules.length;

  return (
    <div>
      {/* ─── Header ──────────────────────────────────── */}
      <div style={{ display:'flex', justifyContent:'space-between', alignItems:'center', marginBottom:20 }}>
        {/* تب‌های اصلی */}
        <div style={{ display:'flex', gap:2, background:'var(--bg-2)', padding:3, borderRadius:10 }}>
          {[
            { id:'list',   label:'📋 فالوآپ‌ها' },
            { id:'tasks',  label:'🗂️ تسک‌ها' },
            { id:'report', label:'📊 گزارش عملکرد' },
          ].map(t => (
            <button key={t.id} onClick={() => setMainTab(t.id)}
              style={{ padding:'7px 16px', borderRadius:8, border:'none', cursor:'pointer',
                fontFamily:'inherit', fontSize:12,
                background: mainTab===t.id ? 'var(--surface)' : 'transparent',
                color: mainTab===t.id ? 'var(--text-1)' : 'var(--text-3)',
                boxShadow: mainTab===t.id ? '0 1px 4px rgba(0,0,0,0.2)' : 'none' }}>
              {t.label}
            </button>
          ))}
        </div>
        {mainTab === 'list' && (
          <button className="btn btn-primary" onClick={() => setWizard('new')}>+ فالوآپ جدید</button>
        )}
      </div>

      {/* ─── آمار (مشترک) ────────────────────────────── */}
      {stats && mainTab !== 'tasks' && (
        <div style={{ display:'flex', gap:10, marginBottom:20, flexWrap:'wrap' }}>
          {[
            { label:'فالوآپ فعال',  val: fa(rules.filter(r=>r.is_active).length), color:'#6366F1' },
            { label:'کل ارسال‌شده', val: fa(stats.sent_count),                    color:'#34D399' },
            { label:'در صف',        val: fa(stats.pending_count),                  color:'#FBBF24' },
            { label:'پاسخ دادند',   val: fa(stats.response_count || 0),            color:'#60A5FA' },
          ].map(s => (
            <div key={s.label} className="card" style={{ padding:'12px 18px', flex:1, minWidth:110 }}>
              <div style={{ fontFamily:'JetBrains Mono', fontSize:20, fontWeight:700, color:s.color }}>{s.val}</div>
              <div style={{ fontSize:11, color:'var(--text-3)', marginTop:2 }}>{s.label}</div>
            </div>
          ))}
        </div>
      )}

      {/* ─── تب لیست ─────────────────────────────────── */}
      {mainTab === 'list' && (
        loading ? (
          <div style={{ textAlign:'center', padding:60, color:'var(--text-3)' }}>در حال بارگذاری...</div>
        ) : rules.length === 0 ? (
          <div className="card" style={{ textAlign:'center', padding:60 }}>
            <div style={{ fontSize:48, marginBottom:12 }}>🤖</div>
            <div style={{ fontSize:15, fontWeight:600, marginBottom:8 }}>هنوز فالوآپی ندارید</div>
            <div style={{ fontSize:12, color:'var(--text-3)', marginBottom:20 }}>
              فالوآپ بسازید تا وقتی کاربر رها کرد یا محتوا گرفت، خودکار پیام بره
            </div>
            <button className="btn btn-primary" onClick={() => setWizard('new')}>+ اولین فالوآپ را بساز</button>
          </div>
        ) : (
          <div style={{ display:'flex', flexDirection:'column', gap:8 }}>
            {rules.map(rule => (
              <FollowupCard key={rule.id} rule={rule} steps={steps[rule.id]} perf={perf[rule.id]}
                onToggle={toggleActive} onDelete={deleteRule} onEdit={openEdit} fa={fa} />
            ))}
          </div>
        )
      )}

      {/* ─── تب تسک‌ها ───────────────────────────────── */}
      {mainTab === 'tasks' && (
        <TasksTab headers={headers} fa={fa} />
      )}

      {/* تب «وضعیت مکالمات» به ماژول مارکت منتقل شد (Market → 📱 وضعیت مکالمات) */}

      {/* ─── تب گزارش ────────────────────────────────── */}
      {mainTab === 'report' && (
        <ReportTab headers={headers} rules={rules} steps={steps} perf={perf} fa={fa} />
      )}

      {/* ─── Wizard ────────────────────────────────────── */}
      {wizard && (
        <FollowupWizard
          headers={headers} toast={toast} fa={fa}
          initial={wizard === 'new' ? null : wizard}
          onClose={() => setWizard(null)}
          onSave={() => { setWizard(null); toast('✅ ذخیره شد', 'success'); load(); }}
        />
      )}
    </div>
  );
};

window.Campaigns = Campaigns;