// ماژول نقشه سناریوها + تست سلامت سیستم SmartBot

// ─── داده‌های سناریوها ───────────────────────────────────────────────────────
const SM_SCENARIOS = [
  { num:'۱',  cat:'buy',  name:'خرید مستقیم (ایده‌آل)',
    phases:[{cls:'p-new',label:'ورود بله'},{cls:'p-talk',label:'مکالمه AI'},{cls:'p-assign',label:'انتساب'},{cls:'p-call',label:'answered'},{cls:'p-call',label:'scheduled'},{cls:'p-buy',label:'sold ✅'}],
    finalStatus:{cls:'ss-buyer',label:'buyer'}, triggers:['consultation_done','status_change'], tables:['leads','lead_events','pool_conversions','sales_feed'], note:null },
  { num:'۲',  cat:'buy',  name:'خرید با تخفیف',
    phases:[{cls:'p-new',label:'ورود'},{cls:'p-talk',label:'مکالمه'},{cls:'p-assign',label:'انتساب'},{cls:'p-buy',label:'sold + discount'}],
    finalStatus:{cls:'ss-buyer',label:'buyer'}, triggers:['status_change'], tables:['leads.discount_amount','pool_conversions','sales_feed'], note:null },
  { num:'۳',  cat:'buy',  name:'خرید اقساطی',
    phases:[{cls:'p-new',label:'ورود'},{cls:'p-talk',label:'مکالمه'},{cls:'p-assign',label:'انتساب'},{cls:'p-buy',label:'sold + installments'}],
    finalStatus:{cls:'ss-buyer',label:'buyer'}, triggers:['payment_expired','status_change'], tables:['lead_installments','pool_conversions','sales_feed'], note:null },
  { num:'۴',  cat:'buy',  name:'خرید بعد چند پیگیری',
    phases:[{cls:'p-new',label:'ورود'},{cls:'p-talk',label:'مکالمه'},{cls:'p-assign',label:'انتساب'},{cls:'p-call',label:'no_answer ×۳'},{cls:'p-camp',label:'کمپین'},{cls:'p-call',label:'answered'},{cls:'p-buy',label:'sold ✅'}],
    finalStatus:{cls:'ss-buyer',label:'buyer'}, triggers:['script_drop','consultation_done'], tables:['pool_lead_tags(❄️سرد)','campaign_leads','pool_conversions'], note:null },
  { num:'۵',  cat:'buy',  name:'خرید بعد محتوای رایگان',
    phases:[{cls:'p-new',label:'ورود'},{cls:'p-talk',label:'مکالمه + دوره رایگان'},{cls:'p-camp',label:'کمپین free_content'},{cls:'p-assign',label:'انتساب'},{cls:'p-buy',label:'sold ✅'}],
    finalStatus:{cls:'ss-buyer',label:'buyer'}, triggers:['free_content_sent','status_change'], tables:['leads.free_courses_count','campaign_leads','pool_conversions'], note:null },
  { num:'۶',  cat:'buy',  name:'خرید دوم (تکرار خرید)',
    phases:[{cls:'p-back',label:'قبلاً buyer'},{cls:'p-camp',label:'winback / دستی'},{cls:'p-call',label:'تماس مجدد'},{cls:'p-buy',label:'sold دوم ✅'}],
    finalStatus:{cls:'ss-buyer',label:'buyer'}, triggers:['manual'], tables:['lead_events(sold×۲)','pool_conversions','sales_feed'], note:'⚠️ sale_amount فقط آخری نگه می‌داره' },
  { num:'۷',  cat:'lost', name:'بی‌علاقه (not_interested)',
    phases:[{cls:'p-new',label:'ورود'},{cls:'p-talk',label:'مکالمه'},{cls:'p-assign',label:'انتساب'},{cls:'p-call',label:'answered'},{cls:'p-lost',label:'not_interested'}],
    finalStatus:{cls:'ss-lost',label:'lost'}, triggers:['status_change'], tables:['leads.lost_reason','lead_events'], note:null },
  { num:'۸',  cat:'lost', name:'کنسل شده',
    phases:[{cls:'p-new',label:'ورود'},{cls:'p-assign',label:'انتساب'},{cls:'p-call',label:'علاقه اولیه'},{cls:'p-lost',label:'cancelled'}],
    finalStatus:{cls:'ss-cancelled',label:'cancelled'}, triggers:['status_change'], tables:['leads.lost_reason','lead_events'], note:null },
  { num:'۹',  cat:'lost', name:'شماره اشتباه',
    phases:[{cls:'p-new',label:'ورود'},{cls:'p-assign',label:'انتساب'},{cls:'p-call',label:'bad_number'}],
    finalStatus:{cls:'ss-lost',label:'bad_number'}, triggers:['—'], tables:['lead_events'], note:null },
  { num:'۱۰', cat:'lost', name:'سکوت — جواب ربات نداد',
    phases:[{cls:'p-new',label:'ورود'},{cls:'p-talk',label:'پیام اول'},{cls:'p-camp',label:'script_drop → کمپین'},{cls:'p-grav',label:'بدون پاسخ → قبرستان'}],
    finalStatus:{cls:'ss-grav',label:'graveyard'}, triggers:['script_drop','state_stuck'], tables:['lead_script_state.stuck_since','pool_segment_members'], note:null },
  { num:'۱۱', cat:'lost', name:'سرد — ۳ بار بی‌پاسخ',
    phases:[{cls:'p-call',label:'no_answer ×۳'},{cls:'p-camp',label:'کمپین بازفعال'},{cls:'p-grav',label:'بدون نتیجه → قبرستان'}],
    finalStatus:{cls:'ss-grav',label:'graveyard'}, triggers:['script_drop'], tables:['pool_lead_tags(❄️سرد-واقعی)','pool_segment_members'], note:null },
  { num:'۱۲', cat:'lost', name:'پرداخت نکرد (payment_expired)',
    phases:[{cls:'p-call',label:'scheduled / consultation'},{cls:'p-inst',label:'payment_due_at ست'},{cls:'p-camp',label:'payment_expired → کمپین'},{cls:'p-lost',label:'بدون خرید → lost'}],
    finalStatus:{cls:'ss-lost',label:'lost'}, triggers:['payment_expired'], tables:['leads.payment_due_at','campaign_leads'], note:null },
  { num:'۱۳', cat:'lost', name:'عودت (Refund)',
    phases:[{cls:'p-buy',label:'buyer ✅'},{cls:'p-lost',label:'درخواست عودت'},{cls:'p-lost',label:'ادمین ثبت refund'}],
    finalStatus:{cls:'ss-cancelled',label:'cancelled'}, triggers:['—'], tables:['leads.refund_amount','leads.refund_at','leads.refund_reason'], note:null },
  { num:'۱۴', cat:'back', name:'رستاخیز — پیام جدید از قبرستان',
    phases:[{cls:'p-grav',label:'lost / cancelled'},{cls:'p-new',label:'پیام جدید در بله'},{cls:'p-back',label:'hook → follow_up + تگ 🪦'},{cls:'p-assign',label:'انتساب مجدد'}],
    finalStatus:{cls:'ss-followup',label:'follow_up'}, triggers:['status_change'], tables:['pool_lead_tags(🪦برگشته)','lead_events'], note:null },
  { num:'۱۵', cat:'back', name:'بازیابی دستی از قبرستان',
    phases:[{cls:'p-grav',label:'در قبرستان'},{cls:'p-back',label:'ادمین: winback'},{cls:'p-camp',label:'سکانس winback'},{cls:'p-call',label:'تماس مجدد'}],
    finalStatus:{cls:'ss-back',label:'buyer یا lost'}, triggers:['manual'], tables:['campaign_leads(winback)'], note:null },
  { num:'۱۶', cat:'back', name:'re_request — خودش خواست تماس',
    phases:[{cls:'p-lost',label:'لید lost'},{cls:'p-back',label:'outcome = re_request'},{cls:'p-new',label:'status → new'},{cls:'p-assign',label:'انتساب مجدد'}],
    finalStatus:{cls:'ss-new',label:'new'}, triggers:['status_change'], tables:['lead_events(re_request)','pool_lead_tags(🔄برگشتی)'], note:null },
  { num:'۱۷', cat:'back', name:'بازگشت به استخر (SLA تموم شد)',
    phases:[{cls:'p-assign',label:'SLA تموم شد'},{cls:'p-back',label:'unit → market'},{cls:'p-assign',label:'انتساب مجدد'}],
    finalStatus:{cls:'ss-followup',label:'follow_up'}, triggers:['—'], tables:['leads.unit=market','lead_history(returned)'], note:null },
  { num:'۱۸', cat:'camp', name:'سکانس فالوآپ — بی‌نتیجه',
    phases:[{cls:'p-camp',label:'trigger → سکانس شروع'},{cls:'p-camp',label:'گام‌ها اجرا'},{cls:'p-camp',label:'سکانس تموم'},{cls:'p-grav',label:'aftermath → tag_cold'}],
    finalStatus:{cls:'ss-grav',label:'سرد / قبرستان'}, triggers:['script_drop','state_stuck'], tables:['campaign_leads','followup_rule_log','pool_lead_tags(سرد)'], note:null },
  { num:'۱۹', cat:'camp', name:'سکانس فالوآپ — جواب داد',
    phases:[{cls:'p-camp',label:'سکانس در حال اجرا'},{cls:'p-back',label:'لید پاسخ داد → replied'},{cls:'p-call',label:'سکانس متوقف → تماس'}],
    finalStatus:{cls:'ss-followup',label:'follow_up'}, triggers:['status_change'], tables:['followup_rule_log(answered)','campaign_leads(warm)'], note:null },
  { num:'۲۰', cat:'camp', name:'سگمنت — ورود خودکار',
    phases:[{cls:'p-camp',label:'cron هر ۶۰ دقیقه'},{cls:'p-back',label:'شرط برقرار'},{cls:'p-camp',label:'اکشن: join_campaign / add_tag'}],
    finalStatus:{cls:'ss-followup',label:'بسته به اکشن'}, triggers:['—'], tables:['pool_segment_members','pool_lead_tags','campaign_leads'], note:null },
  { num:'۲۱', cat:'camp', name:'فریز — تماس بعداً',
    phases:[{cls:'p-call',label:'لید گفت بعداً'},{cls:'p-inst',label:'freeze_until ست'},{cls:'p-camp',label:'در صف تا سررسید'},{cls:'p-back',label:'آنفریز → انتساب'}],
    finalStatus:{cls:'ss-followup',label:'follow_up'}, triggers:['—'], tables:['leads.freeze_until','leads.freeze_note','lead_history(frozen)'], note:null },
];

// ─── داده‌های تست سلامت ──────────────────────────────────────────────────────
const SM_HEALTH_TABS = [
  { id:'prereq', label:'پیش‌نیاز' },
  { id:'t1',     label:'۱ — ورود لید' },
  { id:'t2',     label:'۲ — مکالمه ربات' },
  { id:'t3',     label:'۳ — فروشنده' },
  { id:'t4',     label:'۴ — خرید' },
  { id:'t5',     label:'۵ — باخت' },
  { id:'t6',     label:'۶ — کمپین' },
  { id:'t7',     label:'۷ — قبرستان' },
  { id:'t8',     label:'۸ — گزارش' },
];

const SM_HEALTH_DATA = {
  prereq: {
    intro: 'قبل از شروع تست، این موارد باید وجود داشته باشن. بدون این‌ها تست‌های بعدی ممکنه fail بشن.',
    cases: [
      { num:'A', title:'داده‌های پایه سیستم', desc:'بررسی کن قبل از هر تستی این‌ها وجود داشته باشن',
        input:['حداقل ۱ فروشنده فعال','حداقل ۱ اسکریپت فعال','حداقل ۱ محصول با list_price','حداقل ۱ کمپین با سکانس','قوانین توزیع در Rules'],
        output:['تب فروشندگان → حداقل ۱ ردیف','تب کتابخانه → اسکریپت فعال','تب محصولات → قیمت مصوب پر','تب اتوماسیون → سکانس با گام','Rules → قوانین ورودی ست'],
        note:null },
      { num:'B', title:'اکانت‌های لازم', desc:'چه اکانت‌هایی نیاز داری',
        input:['ادمین: admin / admin123','یک اکانت فروشنده فعال','اکانت بله/تلگرام برای شبیه‌سازی لید'],
        output:['یا: استفاده از endpoint مستقیم API','POST /api/leads → ساخت لید مستقیم','تب مانیتور API در پنل','صفحه Simulation برای شبیه‌سازی'],
        note:null },
    ],
  },
  t1: {
    intro: 'بررسی می‌کنیم لید جدید از کانال بله وارد می‌شه و همه فیلدهای اولیه درست ست می‌شن.',
    cases: [
      { num:'۱-۱', title:'ورود لید از بله', desc:'شبیه‌سازی پیام اول',
        input:['platform: bale','platform_id: 100001','username: ali_test','full_name: علی رضایی','پیام: «سلام»'],
        output:['leads: یک ردیف جدید','status = new','lead_type = bot','unit = market','score = 0','conversations: ساخته شد','messages: پیام ذخیره شد'],
        note:'تأیید: استخر لید → فیلتر «جدید» → اسم علی ظاهر بشه' },
      { num:'۱-۲', title:'لید تکراری', desc:'همان platform_id دوباره پیام بفرسته',
        input:['platform_id: 100001 (همان قبلی)','پیام: «می‌خوام بیشتر بدونم»'],
        output:['لید جدید ساخته نشه','پیام به همان لید اضافه شه','تعداد leads ثابت بمونه'],
        note:'تأیید: تعداد کل لیدها یکی نشه — فقط messages اضافه بشه' },
    ],
  },
  t2: {
    intro: 'بررسی می‌کنیم AI داده‌ها رو درست استخراج می‌کنه، score بالا می‌ره و تگ‌های خودکار اضافه می‌شن.',
    cases: [
      { num:'۲-۱', title:'استخراج داده توسط AI', desc:'چند پیام با اطلاعات واضح',
        input:['«اسمم علیه، شاغلم»','«می‌خوام برنامه‌نویسی یاد بگیرم»','«بودجه‌ام حدود ۳۵ میلیونه»','«لپ‌تاپ دارم، صبح‌ها وقت دارم»'],
        output:['lead_collected_data: نام، هدف، بودجه پر','score ≥ ۵','تگ «شاغل» اضافه','تگ «سیستم_دارد» اضافه','تگ «بودجه_۳۰_۵۰» اضافه','تگ «تماس_صبح» اضافه'],
        note:'تأیید: جزئیات لید → تب «داده جمع‌آوری‌شده» — فیلدها پر باشن' },
      { num:'۲-۲', title:'گیر کردن در استیت (state_stuck)', desc:'ربات سوال پرسیده ولی لید جواب نداده',
        input:['لید وارد اسکریپت شده','X ساعت بدون پاسخ (طبق تنظیم)','cron هر ۳۰ دقیقه چک می‌کنه'],
        output:['lead_script_state.stuck_since پر','trigger: state_stuck فعال','اگه کمپین state_stuck داره → campaign_leads'],
        note:null },
    ],
  },
  t3: {
    intro: 'انتساب لید به فروشنده، تماس گرفتن، و ثبت نتایج مختلف.',
    cases: [
      { num:'۳-۱', title:'انتساب خودکار به فروشنده', desc:'قوانین توزیع لید رو می‌فرسته',
        input:['لید با score کافی در استخر','قوانین توزیع فعال','فروشنده ظرفیت داره'],
        output:['leads.seller_id پر','leads.unit = sales','leads.assigned_at ست','leads.expires_at = +48h','lead_history: action=assigned'],
        note:null },
      { num:'۳-۲', title:'تماس — answered', desc:'فروشنده LogModal رو پر می‌کنه',
        input:['outcome: answered','note: «علاقمند به دوره پایتون»','duration: 5 دقیقه'],
        output:['leads.status = interested','leads.first_contact_at ست','lead_events: outcome=answered','trigger: status_change'],
        note:null },
      { num:'۳-۳', title:'تماس — no_answer', desc:'سه بار بی‌پاسخ',
        input:['outcome: no_answer','follow_up_at: +2 روز','۳ بار تکرار کن'],
        output:['leads.status = follow_up','lead_events: follow_up_at ست','followup_tasks: reminder_call','بعد ۳ بار → تگ ❄️سرد-واقعی'],
        note:'تأیید: no_answer_count در جزئیات لید = ۳' },
    ],
  },
  t4: {
    intro: 'مسیر کامل فروش — مهم‌ترین تست سیستم.',
    cases: [
      { num:'۴-۱', title:'فروش نقدی ساده', desc:'مسیر ایده‌آل ✅',
        input:['outcome: sold','sale_amount: 35,000,000','product_id: دوره پایتون','pay_method: cash'],
        output:['leads.status = buyer','leads.sale_amount = 35M','lead_events: outcome=sold','pool_conversions: ردیف جدید','sales_feed: ردیف جدید'],
        note:'تأیید داشبورد: «فروش ۳۰روز» این فروش رو بشمره. فروشندگان توست 🎉 بگیرن.' },
      { num:'۴-۲', title:'فروش اقساطی', desc:'pay_method=installment',
        input:['outcome: sold','sale_amount: 30,000,000','pay_method: installment','قسط ۱: ۱۰M — ۱ ماه دیگه','قسط ۲: ۱۰M — ۲ ماه دیگه','قسط ۳: ۱۰M — ۳ ماه دیگه'],
        output:['lead_installments: ۳ ردیف','paid_at = NULL (نپرداخته)','unpaid_installments_count = 3','trigger payment_expired موقع سررسید'],
        note:null },
      { num:'۴-۳', title:'فروش با تخفیف', desc:'discount_amount پر بشه',
        input:['sale_amount: 30,000,000','discount_amount: 3,000,000','list_price محصول: 35,000,000'],
        output:['leads.discount_amount = 3M','کارنامه فروشنده: پرچم «قیمت‌شکن» اگه زیاد','میانگین تخفیف فروشنده آپدیت'],
        note:null },
    ],
  },
  t5: {
    intro: 'مسیرهای مختلف از دست دادن لید.',
    cases: [
      { num:'۵-۱', title:'not_interested', desc:'لید علاقه‌ای نداره',
        input:['outcome: not_interested','lost_reason: «قیمت برام زیاده»'],
        output:['leads.status = lost','leads.lost_reason پر','lead_events: outcome=not_interested'],
        note:null },
      { num:'۵-۲', title:'bad_number', desc:'شماره اشتباه',
        input:['outcome: bad_number'],
        output:['leads.status = bad_number','lead_events: ردیف','فروشنده می‌تونه ویرایش شماره کنه'],
        note:null },
      { num:'۵-۳', title:'عودت وجه (Refund)', desc:'لید باید buyer باشه',
        input:['refund_amount: 35,000,000','refund_reason: «محصول مطابق انتظار نبود»','ادمین از CRM → دکمه «عودت»'],
        output:['leads.refund_amount ست','leads.refund_at ست','leads.refund_reason ست','گزارش فروشنده: عودت لحاظ شده'],
        note:null },
    ],
  },
  t6: {
    intro: 'کمپین فالوآپ، سکانس‌ها، و سگمنت‌ها.',
    cases: [
      { num:'۶-۱', title:'trigger: script_drop', desc:'لید جواب ربات رو نداده',
        input:['لید وارد اسکریپت شده','X ساعت بدون پاسخ','کمپین با trigger=script_drop موجود'],
        output:['campaign_leads: ردیف جدید','entry_event = bot','سکانس شروع می‌شه','پیام‌های فالوآپ ارسال'],
        note:null },
      { num:'۶-۲', title:'stop_condition: became_buyer', desc:'فروش داخل سکانس اتفاق افتاد',
        input:['لید در سکانس فالوآپ','فروشنده outcome=sold ثبت کنه'],
        output:['سکانس متوقف می‌شه','campaign_leads.status = buyer','پیام‌های بعدی ارسال نمی‌شن'],
        note:'تأیید: تب لیدهای کمپین → وضعیت buyer، صف فالوآپ خالی' },
      { num:'۶-۳', title:'سگمنت — ورود خودکار', desc:'cron هر ۶۰ دقیقه بررسی می‌کنه',
        input:['شرط: score ≥ 7 AND status = interested','اکشن: join_campaign «داغ‌ها»'],
        output:['pool_segment_members: ردیف','campaign_leads: entry_event=bot','سکانس مربوطه فعال'],
        note:'تأیید: بعد از ۶۰ دقیقه یا اجرای دستی cron' },
    ],
  },
  t7: {
    intro: 'قبرستان، رستاخیز، و winback.',
    cases: [
      { num:'۷-۱', title:'ورود به قبرستان', desc:'سگمنت seg_auto_graveyard',
        input:['no_answer_count ≥ 3','AND last_call_days ≥ 30','سگمنت seg_auto_graveyard فعال'],
        output:['pool_segment_members: ردیف جدید','اکشن to_graveyard اجرا','لید در تب قبرستان ظاهر'],
        note:null },
      { num:'۷-۲', title:'رستاخیز — پیام جدید', desc:'لید lost/cancelled پیام می‌فرسته',
        input:['لید با status=lost','از بله پیام جدید می‌فرسته','پیام: «هنوز می‌تونم ثبت‌نام کنم؟»'],
        output:['leads.status = follow_up','تگ «🪦برگشته از قبرستان» اضافه','lead_events: ردیف','فروشنده نوتیف می‌گیره'],
        note:'تأیید: استخر لید → جستجوی نام → follow_up + تگ قبرستان' },
      { num:'۷-۳', title:'winback دستی', desc:'ادمین از UI قبرستان',
        input:['تب قبرستان → انتخاب لید','دکمه «ارسال به کمپین»','کمپین: winback'],
        output:['campaign_leads: entry_event=winback','سکانس winback شروع','لید از قبرستان خارج'],
        note:null },
    ],
  },
  t8: {
    intro: 'بررسی صحت داشبورد و گزارش‌ها بعد از اجرای تست‌های قبلی.',
    cases: [
      { num:'۸-۱', title:'داشبورد اصلی', desc:'بعد از انجام تست‌های ۴،۵،۶',
        input:['حداقل ۱ فروش ثبت شده','حداقل ۱ لید باخته','حداقل ۱ لید در کمپین'],
        output:['«فروش ۳۰روز» ≥ ۱ نشون بده','«لید جدید امروز» تعداد درست','نمودار روند آپدیت شده','speed-to-lead محاسبه درست'],
        note:null },
      { num:'۸-۲', title:'کارنامه فروشنده', desc:'CRM ادمین → فروشنده مربوطه',
        input:['CRM ادمین → فروشنده → تب Performance'],
        output:['تعداد فروش درست','مجموع فروش = sale_amount ها','تخفیف داده‌شده ثبت','نرخ تبدیل محاسبه'],
        note:null },
      { num:'۸-۳', title:'صف اقساط', desc:'شرط: تست ۴-۲ انجام شده',
        input:['CRM ادمین → تب «وصول اقساط»','فیلتر: unpaid'],
        output:['۳ قسط لیست بشن','paid_at = null (نپرداخته)','دکمه toggle پرداخت کار کنه'],
        note:'تأیید: بعد از کلیک toggle، paid_at پر بشه و از لیست unpaid خارج' },
    ],
  },
};

// ─── CSS مشترک ───────────────────────────────────────────────────────────────
const SM_CSS = `
  .sm-phase { display:inline-block; padding:2px 8px; border-radius:10px; font-size:10.5px; font-weight:600; margin:1px; white-space:nowrap; }
  .sm-phase.p-new    { background:#1e3a5f; color:#60a5fa; }
  .sm-phase.p-talk   { background:#1a2e1a; color:#4ade80; }
  .sm-phase.p-assign { background:#2d2014; color:#fb923c; }
  .sm-phase.p-call   { background:#2a1f3d; color:#a78bfa; }
  .sm-phase.p-buy    { background:#14291f; color:#34d399; }
  .sm-phase.p-lost   { background:#2d1515; color:#f87171; }
  .sm-phase.p-camp   { background:#1f1a2e; color:#c4b5fd; }
  .sm-phase.p-grav   { background:#1a1a1a; color:#94a3b8; }
  .sm-phase.p-back   { background:#1e2a1a; color:#86efac; }
  .sm-phase.p-inst   { background:#1a2333; color:#7dd3fc; }

  .sm-cat { display:inline-block; padding:2px 8px; border-radius:4px; font-size:10.5px; font-weight:600; }
  .sm-cat-buy  { background:#14291f; color:#4ade80; }
  .sm-cat-lost { background:#2d1515; color:#f87171; }
  .sm-cat-back { background:#1e2a1a; color:#86efac; }
  .sm-cat-camp { background:#1f1a2e; color:#a78bfa; }

  .sm-status { display:inline-block; padding:2px 10px; border-radius:10px; font-size:11px; font-weight:700; white-space:nowrap; }
  .sm-status.ss-buyer    { background:#14291f; color:#4ade80; border:1px solid #166534; }
  .sm-status.ss-lost     { background:#2d1515; color:#f87171; border:1px solid #7f1d1d; }
  .sm-status.ss-cancelled{ background:#2d1a10; color:#fb923c; border:1px solid #7c2d12; }
  .sm-status.ss-followup { background:#1e2433; color:#94a3b8; border:1px solid #334155; }
  .sm-status.ss-new      { background:#1e3a5f; color:#60a5fa; border:1px solid #1e40af; }
  .sm-status.ss-grav     { background:#111;    color:#6b7280; border:1px solid #374151; }
  .sm-status.ss-back     { background:#14291f; color:#34d399; border:1px solid #065f46; }

  .sm-trig  { display:inline-block; background:#1f1a2e; color:#c4b5fd; padding:1px 7px; border-radius:4px; font-size:10.5px; margin:1px; }
  .sm-table { display:inline-block; background:#1e2433; color:#7dd3fc; padding:1px 6px; border-radius:4px; font-size:10px; margin:1px; }

  .sm-main-tab { padding:8px 20px; border-radius:8px; border:1.5px solid transparent; cursor:pointer; font-size:13px; font-family:inherit; font-weight:600; transition:all 0.15s; }
  .sm-main-tab.active { background:transparent; }

  .sm-htab { padding:5px 13px; border-radius:16px; border:1.5px solid transparent; cursor:pointer; font-size:11.5px; font-family:inherit; transition:all 0.15s; }

  .sm-hcard { background:#111827; border:1px solid #1e2433; border-radius:12px; padding:16px; margin-bottom:12px; }
  .sm-hcard-head { display:flex; align-items:flex-start; gap:12px; margin-bottom:12px; }
  .sm-hnum { min-width:30px; height:30px; border-radius:50%; background:#1e2433; display:flex; align-items:center; justify-content:center; font-size:11px; font-weight:600; color:#94a3b8; flex-shrink:0; }
  .sm-htitle { font-size:13.5px; font-weight:600; color:#e2e8f0; margin-bottom:3px; }
  .sm-hdesc  { font-size:11.5px; color:#64748b; }
  .sm-hcols  { display:grid; grid-template-columns:1fr 1fr; gap:10px; }
  .sm-hbox   { background:#0f1623; border-radius:8px; padding:10px 12px; }
  .sm-hbox-label { font-size:10px; font-weight:600; color:#475569; margin-bottom:6px; letter-spacing:0.5px; text-transform:uppercase; }
  .sm-hbox ul { list-style:none; padding:0; margin:0; }
  .sm-hbox li { font-size:11.5px; color:#cbd5e1; padding:2px 0; line-height:1.5; }
  .sm-hbox.in li::before  { content:"→ "; color:#475569; }
  .sm-hbox.out li::before { content:"✓ "; color:#334155; }
  .sm-hnote { font-size:11px; color:#94a3b8; border-right:2px solid #2d3748; padding-right:8px; margin-top:10px; }
`;

// ─── زیرکامپوننت: نقشه سناریوها ─────────────────────────────────────────────
const SM_ScenarioTab = () => {
  const [smCat, setSmCat] = React.useState('all');
  const [smSearch, setSmSearch] = React.useState('');

  const cats = [
    { id:'all',  label:'همه', color:'#64748b' },
    { id:'buy',  label:'✅ خرید', color:'#4ade80' },
    { id:'lost', label:'❌ باخت', color:'#f87171' },
    { id:'back', label:'🔄 بازگشت', color:'#86efac' },
    { id:'camp', label:'📣 کمپین', color:'#a78bfa' },
  ];
  const counts = { all:SM_SCENARIOS.length, buy:0, lost:0, back:0, camp:0 };
  SM_SCENARIOS.forEach(s => counts[s.cat]++);

  const visible = SM_SCENARIOS.filter(s => {
    if (smCat !== 'all' && s.cat !== smCat) return false;
    if (smSearch.trim()) {
      const q = smSearch.trim().toLowerCase();
      return s.name.toLowerCase().includes(q)
        || s.tables.some(t => t.toLowerCase().includes(q))
        || s.triggers.some(t => t.toLowerCase().includes(q));
    }
    return true;
  });

  const legend = [
    {cls:'p-new',label:'ورود'},{cls:'p-talk',label:'مکالمه'},{cls:'p-assign',label:'انتساب'},
    {cls:'p-call',label:'تماس'},{cls:'p-buy',label:'خرید'},{cls:'p-lost',label:'باخت'},
    {cls:'p-camp',label:'کمپین'},{cls:'p-grav',label:'قبرستان'},
  ];

  return (
    <div>
      {/* آمار */}
      <div style={{ display:'flex', gap:10, flexWrap:'wrap', marginBottom:18 }}>
        {[{label:'مسیر خرید',count:counts.buy,color:'#4ade80'},{label:'مسیر باخت',count:counts.lost,color:'#f87171'},{label:'بازگشت',count:counts.back,color:'#86efac'},{label:'کمپین',count:counts.camp,color:'#a78bfa'}].map(st => (
          <div key={st.label} style={{ background:'#1e2433', borderRadius:10, padding:'8px 14px', display:'flex', alignItems:'center', gap:8 }}>
            <div style={{ fontSize:18, fontWeight:800, color:st.color, fontFamily:'JetBrains Mono' }}>{window.SB_DATA.fa(st.count)}</div>
            <div style={{ fontSize:11, color:'#94a3b8' }}>{st.label}</div>
          </div>
        ))}
      </div>

      {/* فیلترها */}
      <div style={{ display:'flex', gap:8, alignItems:'center', flexWrap:'wrap', marginBottom:14 }}>
        {cats.map(c => (
          <button key={c.id} onClick={() => setSmCat(c.id)} style={{
            padding:'4px 12px', borderRadius:16, border:'1.5px solid',
            cursor:'pointer', fontSize:11.5, fontFamily:'inherit',
            background: smCat===c.id ? 'transparent' : '#1e2433',
            color: smCat===c.id ? c.color : '#94a3b8',
            borderColor: smCat===c.id ? c.color : 'transparent',
            transition:'all 0.15s',
          }}>
            {c.label} <span style={{ opacity:0.6, fontSize:10 }}>({window.SB_DATA.fa(counts[c.id])})</span>
          </button>
        ))}
        <input value={smSearch} onChange={e => setSmSearch(e.target.value)}
          placeholder="جستجو سناریو، جدول، تریگر..."
          style={{ background:'#1e2433', border:'1px solid #2d3748', borderRadius:8, padding:'5px 11px', color:'#e2e8f0', fontSize:12, fontFamily:'inherit', outline:'none', width:200 }} />
      </div>

      {/* legend */}
      <div style={{ display:'flex', gap:8, flexWrap:'wrap', marginBottom:14 }}>
        {legend.map(l => <span key={l.cls} className={`sm-phase ${l.cls}`} style={{ fontSize:10 }}>{l.label}</span>)}
      </div>

      {/* جدول */}
      <div style={{ overflowX:'auto' }}>
        <table style={{ width:'100%', borderCollapse:'collapse', minWidth:860 }}>
          <thead>
            <tr>
              {['#','سناریو','دسته','مراحل','وضعیت نهایی','تریگرها','جداول'].map((h,i) => (
                <th key={i} style={{ background:'#1e2433', padding:'9px 11px', textAlign:'right', fontSize:11, fontWeight:600, color:'#94a3b8', borderBottom:'2px solid #2d3748', whiteSpace:'nowrap', minWidth: i===3?280:i===6?190:'auto' }}>{h}</th>
              ))}
            </tr>
          </thead>
          <tbody>
            {visible.map(s => (
              <tr key={s.num} style={{ borderBottom:'1px solid #1e2433' }}
                onMouseEnter={e => e.currentTarget.style.background='#1a2030'}
                onMouseLeave={e => e.currentTarget.style.background='transparent'}>
                <td style={{ padding:'8px 11px', color:'#475569', fontSize:11, whiteSpace:'nowrap' }}>{s.num}</td>
                <td style={{ padding:'8px 11px', fontWeight:600, fontSize:12.5, whiteSpace:'nowrap', color:'#e2e8f0' }}>{s.name}</td>
                <td style={{ padding:'8px 11px' }}>
                  <span className={`sm-cat sm-cat-${s.cat}`}>{s.cat==='buy'?'✅ خرید':s.cat==='lost'?'❌ باخت':s.cat==='back'?'🔄 بازگشت':'📣 کمپین'}</span>
                </td>
                <td style={{ padding:'8px 11px' }}>{s.phases.map((p,i) => <span key={i} className={`sm-phase ${p.cls}`}>{p.label}</span>)}</td>
                <td style={{ padding:'8px 11px' }}><span className={`sm-status ${s.finalStatus.cls}`}>{s.finalStatus.label}</span></td>
                <td style={{ padding:'8px 11px', verticalAlign:'top' }}>{s.triggers.map((t,i) => <span key={i} className="sm-trig">{t}</span>)}</td>
                <td style={{ padding:'8px 11px', verticalAlign:'top', fontSize:11 }}>
                  {s.tables.map((t,i) => <span key={i} className="sm-table">{t}</span>)}
                  {s.note && <div style={{ marginTop:4, fontSize:10, color:'#f87171' }}>{s.note}</div>}
                </td>
              </tr>
            ))}
            {visible.length===0 && (
              <tr><td colSpan={7} style={{ padding:'28px', textAlign:'center', color:'#475569', fontSize:13 }}>هیچ سناریویی پیدا نشد</td></tr>
            )}
          </tbody>
        </table>
      </div>
    </div>
  );
};

// ─── زیرکامپوننت: تست سلامت ──────────────────────────────────────────────────
const SM_HealthTab = () => {
  const [activeHTab, setActiveHTab] = React.useState('prereq');
  const section = SM_HEALTH_DATA[activeHTab];

  const tabColors = { prereq:'#94a3b8', t1:'#60a5fa', t2:'#a78bfa', t3:'#fb923c', t4:'#4ade80', t5:'#f87171', t6:'#c4b5fd', t7:'#86efac', t8:'#7dd3fc' };

  return (
    <div>
      {/* تب‌های فرعی */}
      <div style={{ display:'flex', gap:6, flexWrap:'wrap', marginBottom:18, paddingBottom:14, borderBottom:'1px solid #1e2433' }}>
        {SM_HEALTH_TABS.map(t => {
          const col = tabColors[t.id] || '#94a3b8';
          const isActive = activeHTab === t.id;
          return (
            <button key={t.id} onClick={() => setActiveHTab(t.id)} className="sm-htab" style={{
              background: isActive ? 'transparent' : '#1e2433',
              color: isActive ? col : '#94a3b8',
              borderColor: isActive ? col : 'transparent',
            }}>
              {t.label}
            </button>
          );
        })}
      </div>

      {/* توضیح بخش */}
      <div style={{ fontSize:12.5, color:'#64748b', marginBottom:16, lineHeight:1.6, borderRight:'2px solid #2d3748', paddingRight:10 }}>
        {section.intro}
      </div>

      {/* کارت‌های تست */}
      {section.cases.map(c => (
        <div key={c.num} className="sm-hcard">
          <div className="sm-hcard-head">
            <div className="sm-hnum">{c.num}</div>
            <div>
              <div className="sm-htitle">{c.title}</div>
              {c.desc && <div className="sm-hdesc">{c.desc}</div>}
            </div>
          </div>
          <div className="sm-hcols">
            <div className="sm-hbox in">
              <div className="sm-hbox-label">داده ورودی / شرط</div>
              <ul>{c.input.map((item,i) => <li key={i}>{item}</li>)}</ul>
            </div>
            <div className="sm-hbox out">
              <div className="sm-hbox-label">خروجی انتظاری</div>
              <ul>{c.output.map((item,i) => <li key={i}>{item}</li>)}</ul>
            </div>
          </div>
          {c.note && <div className="sm-hnote">{c.note}</div>}
        </div>
      ))}

      {/* شمارش */}
      <div style={{ marginTop:8, fontSize:11, color:'#475569', textAlign:'left' }}>
        {window.SB_DATA.fa(section.cases.length)} تست در این بخش
      </div>
    </div>
  );
};

// ─── کامپوننت اصلی ───────────────────────────────────────────────────────────
const ScenarioMap = () => {
  const [smMainTab, setSmMainTab] = React.useState('scenarios');

  return (
    <div style={{ padding:'0 0 40px' }}>
      <style>{SM_CSS}</style>

      {/* تب‌های اصلی بالا */}
      <div style={{ display:'flex', gap:8, marginBottom:24, borderBottom:'1px solid #1e2433', paddingBottom:0 }}>
        {[
          { id:'scenarios', label:'🗺️ نقشه سناریوها', color:'#60a5fa', sub:`${window.SB_DATA.fa(SM_SCENARIOS.length)} سناریو` },
          { id:'health',    label:'🩺 تست سلامت سیستم', color:'#4ade80', sub:'۲۴ تست کیس' },
        ].map(t => (
          <button key={t.id} onClick={() => setSmMainTab(t.id)} style={{
            padding:'10px 20px 12px',
            background:'transparent',
            border:'none',
            borderBottom: smMainTab===t.id ? `2px solid ${t.color}` : '2px solid transparent',
            cursor:'pointer',
            fontFamily:'inherit',
            display:'flex', flexDirection:'column', alignItems:'flex-start', gap:2,
            transition:'all 0.15s',
            marginBottom:'-1px',
          }}>
            <span style={{ fontSize:13, fontWeight:600, color: smMainTab===t.id ? t.color : '#64748b' }}>{t.label}</span>
            <span style={{ fontSize:10, color: smMainTab===t.id ? t.color+'99' : '#475569' }}>{t.sub}</span>
          </button>
        ))}
      </div>

      {/* محتوا */}
      {smMainTab === 'scenarios' ? <SM_ScenarioTab /> : <SM_HealthTab />}
    </div>
  );
};

window.ScenarioMap = ScenarioMap;
