// ═══════════════════════════════════════════════════════
// Conversion Simulator — JS Engine
// ═══════════════════════════════════════════════════════

// ── STATE ─────────────────────────────────────────────
const TARGETS = {
  prod: "http://172.16.2.207:5000/api/agent/chat",
  dev:  "http://172.16.2.207:5000/api/agent/chat-dev",
  local:"http://localhost:5000/api/agent/chat-dev",
}
const PERSONAS_DEFAULT = [
  { id:1, name:"Chị Lan", age:35, archetype:"Mẹ bỉm sữa",
    trait:"Mua đồ cho con trai 5 tuổi, budget 300k-600k, cẩn thận so sánh giá",
    system:"Bạn đóng vai Chị Lan, 35 tuổi, nội trợ. Mua cho con trai 5 tuổi, budget 300k-600k. Hay hỏi 'có sale không?', so sánh giá. MUA khi combo dưới 500k+free ship. BỎ khi gợi SP trên 1tr.",
    budget:"300k-600k", shopping_for:"Con trai 5 tuổi", conversion_trigger:"Combo dưới 500k + free ship", drop_trigger:"SP trên 1tr"},
  { id:2, name:"Vy GenZ", age:20, archetype:"GenZ TikToker",
    trait:"Thích trend, chat nhanh, dùng slang/emoji, budget thấp",
    system:"Bạn đóng vai Vy, 20 tuổi, sinh viên. Chat nhanh, dùng emoji 💀🔥. Budget 200k-400k. MUA khi có SP trendy giá rẻ. BỎ khi bot formal quá hoặc chậm.",
    budget:"200k-400k", shopping_for:"Bản thân", conversion_trigger:"SP trendy giá rẻ dưới 300k", drop_trigger:"Bot quá formal"},
  { id:3, name:"Anh Tuấn", age:42, archetype:"Ông chú IT",
    trait:"Mua quà cho vợ, không rành thời trang, cần tư vấn rõ ràng",
    system:"Bạn đóng vai Anh Tuấn, 42 tuổi, IT manager. Mua quà sinh nhật cho vợ, budget 500k-1tr. Không biết size/style. MUA khi bot gợi ý cụ thể + quà tặng kèm. BỎ khi bot hỏi quá nhiều.",
    budget:"500k-1tr", shopping_for:"Vợ", conversion_trigger:"Bot gợi ý cụ thể + quà tặng kèm", drop_trigger:"Bot hỏi quá nhiều"},
  { id:4, name:"Bà Hoa", age:63, archetype:"Bà ngoại",
    trait:"Mua cho cháu, chat đơn giản, không biết thuật ngữ",
    system:"Bạn đóng vai Bà Hoa, 63 tuổi. Mua quần áo cho cháu gái 8 tuổi. Chat đơn giản. MUA khi bot giải thích dễ hiểu + gợi SP trẻ em phù hợp. BỎ khi bot dùng từ khó hiểu.",
    budget:"200k-500k", shopping_for:"Cháu gái 8 tuổi", conversion_trigger:"Bot giải thích dễ hiểu + SP trẻ em", drop_trigger:"Bot dùng từ khó hiểu"},
  { id:5, name:"Minh Anh", age:28, archetype:"Fashionista",
    trait:"Biết nhiều brand, kén chọn, so sánh Canifa vs Uniqlo",
    system:"Bạn đóng vai Minh Anh, 28 tuổi, designer. Biết rõ thời trang, hay so sánh Canifa với Uniqlo/H&M. Budget 700k-1.5tr. MUA khi bot show unique value Canifa. BỎ khi bot né so sánh.",
    budget:"700k-1.5tr", shopping_for:"Bản thân", conversion_trigger:"Bot show unique value Canifa", drop_trigger:"Bot né so sánh"},
]

let personas = [...PERSONAS_DEFAULT]
let chatbotUrl = TARGETS.prod
let conversations = {}
let results = {}
let synthesis = null
let running = false, runningId = null, selectedId = null
let editingPersonaId = null
let currentTab = "command"
let simStartTime = null

const TABS = [["command","🎛 Command"],["live","🔬 Live Sim"],["report","📊 Report"],["insights","💡 Insights"]]
const CONV_ICONS = {converted:'✅',interested:'🤔',dropped:'❌',error:'⚠️'}
const scoreColor = v => v >= 4 ? "var(--green)" : v >= 3 ? "var(--amber)" : "var(--red)"
const scoreBg = v => v >= 4 ? "rgba(16,185,129,.15)" : v >= 3 ? "rgba(245,158,11,.12)" : "rgba(239,68,68,.12)"
const avg = a => a.length ? a.reduce((s,v)=>s+v,0)/a.length : 0
const sleep = ms => new Promise(r => setTimeout(r, ms))
const MAX_TURNS_DEFAULT = 5

// ── TARGET SELECTION ──────────────────────────────────
function setTarget(el, key) {
  document.querySelectorAll('.target-chip').forEach(c => c.classList.remove('active'))
  el.classList.add('active')
  chatbotUrl = TARGETS[key] || el.dataset.url
  document.getElementById('customUrl').value = ''
}
function onCustomUrl(inp) {
  if (inp.value.trim()) {
    chatbotUrl = inp.value.trim()
    document.querySelectorAll('.target-chip').forEach(c => c.classList.remove('active'))
  }
}

// ── TABS ──────────────────────────────────────────────
function switchTab(id) {
  currentTab = id
  renderTabs()
  document.querySelectorAll('.tab-panel').forEach(p => p.classList.remove('active'))
  document.getElementById('panel-'+id).classList.add('active')
  if (id === 'live') renderSimSidebar()
  if (id === 'report') renderReport()
}
function renderTabs() {
  const doneCount = personas.filter(p => results[p.id]).length
  document.getElementById('tabGroup').innerHTML = TABS.map(([id,lbl]) =>
    `<button class="tab-btn ${currentTab===id?'active':''}" onclick="switchTab('${id}')">
      ${lbl}${id==='report'&&doneCount>0?`<span class="tab-badge">${doneCount}</span>`:''}
    </button>`
  ).join('')
}

// ── TOP ACTIONS ───────────────────────────────────────
function renderActions() {
  const el = document.getElementById('topActions')
  const doneCount = personas.filter(p => results[p.id]).length
  const overallEl = document.getElementById('overallStat')
  if (doneCount > 0) {
    const convCount = personas.filter(p => results[p.id]?.conversion_status === 'converted').length
    overallEl.style.display = ''
    document.getElementById('overallScore').textContent = Math.round(convCount/doneCount*100) + '%'
    document.getElementById('overallScore').style.color = convCount/doneCount >= .5 ? 'var(--green)' : 'var(--amber)'
  } else { overallEl.style.display = 'none' }
  if (running) {
    el.innerHTML = `<button class="btn-danger" onclick="stopAll()">⏹ Stop</button>`
  } else {
    el.innerHTML = `${doneCount > 0 ? `<button class="btn-success" onclick="runSynthesis()">💡 Synthesize</button>` : ''}`
  }
}

// ── PERSONA GRID ──────────────────────────────────────
function renderPersonaGrid() {
  document.getElementById('personaCount').textContent = personas.length
  const grid = document.getElementById('personaGrid')
  grid.innerHTML = personas.map(p => {
    const r = results[p.id], isRun = runningId===p.id, isDone = !!r
    const ov = r ? avg(Object.values(r.scores||{})) : null
    const cs = r?.conversion_status
    const cc = cs==='converted'?'conv-converted':cs==='interested'?'conv-interested':cs==='dropped'?'conv-dropped':''
    return `<div class="persona-card ${isDone?'done':''} ${isRun?'running':''}">
      ${isRun?'<div class="pulse-dot" style="position:absolute;top:10px;right:10px"></div>':''}
      ${isDone&&cs?`<span class="conv-badge ${cc}" style="position:absolute;top:10px;right:10px">${CONV_ICONS[cs]||''} ${cs}</span>`:''}
      <div style="display:flex;align-items:center;gap:10px;margin-bottom:8px">
        <div class="persona-avatar">${p.name.charAt(0)}</div>
        <div>
          <p class="persona-name">${p.name}</p>
          <p class="persona-meta">${p.age} tuổi · ${p.archetype}</p>
          ${p.budget?`<p style="font-size:10px;color:var(--t3)">💰 ${p.budget} · 🎯 ${p.shopping_for||''}</p>`:''}
        </div>
      </div>
      <p style="font-size:11.5px;color:var(--t2);line-height:1.5;margin-bottom:8px">${p.trait}</p>
      ${r?`<div style="border-top:1px solid var(--card-border);padding-top:8px;margin-top:4px">
        ${r.conversion_reason?`<p style="font-size:10.5px;color:var(--t3);font-style:italic;margin-bottom:6px">"${r.conversion_reason}"</p>`:''}
        ${isDone&&ov!==null?`<div style="display:flex;align-items:center;gap:6px"><span style="font-size:20px;font-weight:800;color:${scoreColor(ov)}">${ov.toFixed(1)}</span><span style="font-size:10px;color:var(--t3)">/ 5</span></div>`:''}
      </div>`:''}
      <div style="display:flex;gap:6px;margin-top:8px">
        <button class="btn-secondary" style="flex:1;padding:5px;font-size:11px" onclick="openPersonaModal(${p.id})">Edit</button>
        <button style="background:rgba(239,68,68,.1);border:1px solid rgba(239,68,68,.2);border-radius:7px;padding:5px 8px;font-size:11px;color:var(--red)" onclick="deletePersona(${p.id})">×</button>
        <button style="width:28px;height:28px;border-radius:50%;background:${running?'var(--bg3)':'var(--purple)'};border:none;color:#fff;font-size:11px;display:flex;align-items:center;justify-content:center" onclick="runSingle(${p.id})" ${running?'disabled':''}>▶</button>
      </div>
    </div>`
  }).join('')
}

// ── AI PERSONA GENERATION ─────────────────────────────
async function generatePersonasAI() {
  const btn = document.getElementById('genPersonaBtn')
  const og = btn.innerHTML
  btn.disabled = true; btn.innerHTML = '<span class="spinner"></span> Đang tạo...'
  try {
    const count = parseInt(document.getElementById('cfgCount').value) || 5
    const resp = await fetch('/api/user-simulator/generate-personas', {
      method:'POST', headers:{'Content-Type':'application/json'}, body: JSON.stringify({count})
    })
    const d = await resp.json()
    if (d.status !== 'success') throw new Error(d.message || 'Fail')
    personas = d.personas.map((p,i) => ({
      id: Date.now()+i, name:p.name, age:p.age, archetype:p.archetype,
      trait: `${p.chat_style}. Budget: ${p.budget}, mua cho: ${p.shopping_for}`,
      system: p.system_prompt, budget:p.budget, shopping_for:p.shopping_for,
      conversion_trigger:p.conversion_trigger, drop_trigger:p.drop_trigger,
    }))
    results = {}; conversations = {}; synthesis = null
    renderAll()
  } catch(e) { alert('Lỗi: '+e.message) }
  finally { btn.disabled=false; btn.innerHTML=og }
}

// ── PERSONA MODAL ─────────────────────────────────────
function openPersonaModal(id) {
  editingPersonaId = id || null
  const m = document.getElementById('personaModal')
  document.getElementById('modalTitle').textContent = id ? 'Edit Persona' : 'New Persona'
  if (id) {
    const p = personas.find(x=>x.id===id); if(!p) return
    document.getElementById('mName').value = p.name
    document.getElementById('mAge').value = p.age
    document.getElementById('mArchetype').value = p.archetype
    document.getElementById('mBudget').value = p.budget || ''
    document.getElementById('mTrait').value = p.trait
    document.getElementById('mSystem').value = p.system
  } else { ['mName','mArchetype','mBudget','mTrait','mSystem'].forEach(k=>document.getElementById(k).value=''); document.getElementById('mAge').value='30' }
  m.style.display = 'flex'
}
function closePersonaModal() { document.getElementById('personaModal').style.display = 'none' }
function savePersona() {
  const n = document.getElementById('mName').value.trim()
  if (!n) return alert('Tên không được trống')
  const data = {
    name:n, age:parseInt(document.getElementById('mAge').value)||30,
    archetype:document.getElementById('mArchetype').value.trim(),
    trait:document.getElementById('mTrait').value.trim(),
    system:document.getElementById('mSystem').value.trim(),
    budget:document.getElementById('mBudget').value.trim(),
  }
  if (editingPersonaId) { const p = personas.find(x=>x.id===editingPersonaId); if(p) Object.assign(p, data) }
  else { data.id = Date.now(); personas.push(data) }
  closePersonaModal(); renderAll()
}
function deletePersona(id) { personas = personas.filter(p=>p.id!==id); delete results[id]; delete conversations[id]; renderAll() }

// ── SIMULATION ENGINE ─────────────────────────────────
async function launchSimulation() {
  if (running) return
  running = true; simStartTime = Date.now()
  const maxTurns = parseInt(document.getElementById('cfgTurns').value) || MAX_TURNS_DEFAULT
  showProgress(0, personas.length)
  switchTab('live')
  renderAll()
  for (let i = 0; i < personas.length; i++) {
    if (!running) break
    await runSinglePersona(personas[i], maxTurns)
    showProgress(i+1, personas.length)
  }
  running = false; runningId = null
  hideProgress()
  renderAll()
  if (personas.filter(p => results[p.id]).length > 0) await runSynthesis()
}

async function runSingle(id) {
  if (running) return
  const p = personas.find(x=>x.id===id); if(!p) return
  running = true; simStartTime = Date.now()
  const maxTurns = parseInt(document.getElementById('cfgTurns').value) || MAX_TURNS_DEFAULT
  showProgress(0, 1)
  switchTab('live')
  renderAll()
  await runSinglePersona(p, maxTurns)
  running = false; runningId = null
  showProgress(1, 1)
  setTimeout(hideProgress, 1000)
  renderAll()
}

async function runSinglePersona(p, maxTurns) {
  runningId = p.id; selectedId = p.id
  conversations[p.id] = []
  renderSimSidebar(); renderChatView(); renderMetricsPanel()
  renderPersonaGrid(); renderActions()

  for (let turn = 0; turn < maxTurns; turn++) {
    if (!running) break
    // 1. Generate user message
    try {
      const umResp = await fetch('/api/user-simulator/generate-message', {
        method:'POST', headers:{'Content-Type':'application/json'},
        body: JSON.stringify({ persona_system_prompt: p.system, conversation: conversations[p.id].filter(m=>!m.thinking).map(m=>({role:m.role,content:m.content})) })
      })
      const umData = await umResp.json()
      if (umData.status !== 'success') { addMsg(p.id,'system','[Lỗi tạo tin nhắn]'); break }
      if (umData.thinking) addMsg(p.id,'thinking',umData.thinking)
      addMsg(p.id,'user', umData.message)
    } catch(e) { addMsg(p.id,'system','[Lỗi: '+e.message+']'); break }
    renderChatView(); await sleep(300)

    // 2. Chat with bot
    try {
      const botResp = await fetch('/api/user-simulator/chat-with-bot', {
        method:'POST', headers:{'Content-Type':'application/json'},
        body: JSON.stringify({
          message: conversations[p.id].filter(m=>m.role==='user').pop()?.content || '',
          chatbot_url: chatbotUrl,
          device_id: 'sim-'+p.id
        })
      })
      const botData = await botResp.json()
      if (botData.status === 'success') { addMsg(p.id,'assistant',botData.response) }
      else { addMsg(p.id,'assistant','[Chatbot không phản hồi]') }
    } catch(e) { addMsg(p.id,'assistant','[Lỗi kết nối chatbot]') }
    renderChatView(); await sleep(300)
  }

  // 3. Evaluate
  try {
    const evalResp = await fetch('/api/user-simulator/evaluate', {
      method:'POST', headers:{'Content-Type':'application/json'},
      body: JSON.stringify({
        persona_name:p.name, persona_age:p.age, persona_archetype:p.archetype, persona_trait:p.trait,
        conversation: conversations[p.id].filter(m=>!m.thinking).map(m=>({role:m.role,content:m.content})),
        conversion_trigger:p.conversion_trigger||'', drop_trigger:p.drop_trigger||'',
        budget:p.budget||'', shopping_for:p.shopping_for||'',
      })
    })
    const evalData = await evalResp.json()
    if (evalData.status === 'success') results[p.id] = evalData
  } catch(e) { console.error('Eval error:', e) }
  renderSimSidebar(); renderChatView(); renderMetricsPanel()
  renderPersonaGrid(); renderActions()
}

function addMsg(pid, role, content) {
  if (!conversations[pid]) conversations[pid] = []
  conversations[pid].push({role, content, thinking: role==='thinking'})
}
function stopAll() { running = false }

// ── LIVE TAB RENDERS ──────────────────────────────────
function renderSimSidebar() {
  const sb = document.getElementById('simSidebar')
  sb.innerHTML = personas.map(p => {
    const r = results[p.id], isRun = runningId===p.id
    const cs = r?.conversion_status
    const icon = isRun ? '<div class="pulse-dot"></div>' : cs ? (CONV_ICONS[cs]||'') : '○'
    const msgCount = (conversations[p.id]||[]).filter(m=>!m.thinking).length
    return `<div class="sim-sidebar-item ${selectedId===p.id?'active':''}" onclick="selectPersona(${p.id})">
      <div style="display:flex;align-items:center;gap:8px">
        <span style="font-size:12px;width:18px;text-align:center">${icon}</span>
        <div>
          <p style="font-size:12px;font-weight:600;color:var(--t1)">${p.name}</p>
          <p style="font-size:10px;color:var(--t3)">${msgCount} msgs${r?' · '+avg(Object.values(r.scores||{})).toFixed(1):''}</p>
        </div>
      </div>
    </div>`
  }).join('')
}
function selectPersona(id) { selectedId = id; renderSimSidebar(); renderChatView(); renderMetricsPanel() }

function renderChatView() {
  const p = personas.find(x => x.id === selectedId)
  if (!p) return
  const header = document.getElementById('chatHeader')
  const isRun = runningId === p.id
  header.innerHTML = `<div class="persona-avatar" style="width:32px;height:32px;font-size:12px">${p.name.charAt(0)}</div>
    <div><p style="font-size:13px;font-weight:700">${p.name} ${isRun?'đang test':'- '+p.archetype}</p>
    <p style="font-size:10.5px;color:var(--t3)">${p.age} tuổi · ${p.budget||''}</p></div>
    ${isRun?'<div class="pulse-dot" style="margin-left:auto"></div>':''}`
  const area = document.getElementById('chatArea')
  const msgs = conversations[p.id] || []
  area.innerHTML = msgs.map(m => {
    if (m.thinking) return `<div class="msg-thinking"><span class="msg-label">THINKING</span>${m.content}</div>`
    if (m.role==='system') return `<div style="text-align:center;font-size:11px;color:var(--t3)">${m.content}</div>`
    return `<div><span class="msg-label" style="text-align:${m.role==='user'?'right':'left'};display:block">${m.role==='user'?p.name:'CHATBOT'}</span>
      <div class="msg-bubble ${m.role==='user'?'msg-user':'msg-bot'}">${m.content}</div></div>`
  }).join('')
  area.scrollTop = area.scrollHeight
}

function renderMetricsPanel() {
  const mc = document.getElementById('metricsContent')
  const p = personas.find(x=>x.id===selectedId)
  const r = p ? results[p.id] : null
  if (!r) { mc.innerHTML = '<p style="color:var(--t3);font-size:12px;text-align:center;padding:20px 0">Chưa có dữ liệu</p>'; return }
  const cs = r.conversion_status, cc = cs==='converted'?'conv-converted':cs==='interested'?'conv-interested':'conv-dropped'
  const ov = avg(Object.values(r.scores||{}))
  mc.innerHTML = `
    <div style="text-align:center;margin-bottom:16px">
      <span class="conv-badge ${cc}" style="font-size:13px;padding:6px 16px">${CONV_ICONS[cs]||''} ${(cs||'').toUpperCase()}</span>
    </div>
    <div style="text-align:center;margin-bottom:14px">
      <span style="font-size:36px;font-weight:800;color:${scoreColor(ov)}">${ov.toFixed(1)}</span>
      <span style="font-size:14px;color:var(--t3)">/ 5</span>
    </div>
    ${Object.entries(r.scores||{}).map(([k,v]) => `
      <div style="margin-bottom:10px">
        <div style="display:flex;justify-content:space-between;margin-bottom:3px">
          <span style="font-size:11px;color:var(--t2)">${k}</span>
          <span style="font-size:11px;font-weight:700;color:${scoreColor(v)}">${v.toFixed(1)}</span>
        </div>
        <div class="minibar-track"><div class="minibar-fill" style="width:${(v/5)*100}%;background:${scoreColor(v)}"></div></div>
      </div>
    `).join('')}
    ${r.conversion_reason?`<div class="card" style="margin-top:12px;padding:10px 12px"><p style="font-size:10px;font-weight:600;color:var(--t3);margin-bottom:4px">📝 Lý do</p><p style="font-size:11.5px;color:var(--t2);line-height:1.5">${r.conversion_reason}</p></div>`:''}
    ${r.key_wins?.length?`<div style="margin-top:12px"><p style="font-size:10px;font-weight:600;color:var(--green);margin-bottom:6px">✅ WINS</p>${r.key_wins.map(w=>`<p style="font-size:11px;color:var(--t2);margin-bottom:4px">• ${w}</p>`).join('')}</div>`:''}
    ${r.key_fails?.length?`<div style="margin-top:10px"><p style="font-size:10px;font-weight:600;color:var(--red);margin-bottom:6px">❌ FAILS</p>${r.key_fails.map(f=>`<p style="font-size:11px;color:var(--t2);margin-bottom:4px">• ${f}</p>`).join('')}</div>`:''}`
}

// ── REPORT TAB ────────────────────────────────────────
function renderReport() {
  const done = personas.filter(p => results[p.id])
  if (!done.length) { document.getElementById('kpiRow').innerHTML = '<p style="grid-column:1/-1;text-align:center;color:var(--t3);font-size:13px;padding:40px">Chưa có kết quả. Chạy simulation trước.</p>'; return }
  const convCount = done.filter(p => results[p.id].conversion_status === 'converted').length
  const intCount = done.filter(p => results[p.id].conversion_status === 'interested').length
  const dropCount = done.filter(p => results[p.id].conversion_status === 'dropped').length
  const avgScore = avg(done.map(p => avg(Object.values(results[p.id].scores||{}))))
  // KPIs
  document.getElementById('kpiRow').innerHTML = `
    <div class="kpi-card"><p class="kpi-label">Conversion Rate</p><p class="kpi-value" style="color:var(--green)">${Math.round(convCount/done.length*100)}%</p><p style="font-size:11px;color:var(--t3)">${convCount}/${done.length}</p></div>
    <div class="kpi-card"><p class="kpi-label">Interest Rate</p><p class="kpi-value" style="color:var(--amber)">${Math.round((convCount+intCount)/done.length*100)}%</p><p style="font-size:11px;color:var(--t3)">${convCount+intCount}/${done.length}</p></div>
    <div class="kpi-card"><p class="kpi-label">Avg Score</p><p class="kpi-value" style="color:${scoreColor(avgScore)}">${avgScore.toFixed(1)}</p><p style="font-size:11px;color:var(--t3)">/ 5.0</p></div>
    <div class="kpi-card"><p class="kpi-label">Drop Rate</p><p class="kpi-value" style="color:var(--red)">${Math.round(dropCount/done.length*100)}%</p><p style="font-size:11px;color:var(--t3)">${dropCount}/${done.length}</p></div>`
  // Funnel
  const total = done.length
  document.getElementById('funnelView').innerHTML = [
    ['Started', total, 'var(--purple)'],
    ['Engaged', total, 'var(--blue)'],
    ['Interested', convCount+intCount, 'var(--amber)'],
    ['Converted', convCount, 'var(--green)'],
  ].map(([label,count,color]) => {
    const pct = Math.max((count/total)*100, 8)
    return `<div class="funnel-stage"><span style="width:80px;font-size:11px;color:var(--t3);font-weight:600">${label}</span>
      <div class="funnel-bar" style="width:${pct}%;background:${color}">${count}</div></div>`
  }).join('')
  // Matrix
  const scoreKeys = [...new Set(done.flatMap(p => Object.keys(results[p.id].scores||{})))]
  document.getElementById('matrixTable').innerHTML = `<table class="score-table">
    <thead><tr><th>Persona</th><th>Status</th>${scoreKeys.map(k=>`<th>${k}</th>`).join('')}<th>Overall</th></tr></thead>
    <tbody>${done.map(p => {
      const r = results[p.id], cs = r.conversion_status
      const cc = cs==='converted'?'conv-converted':cs==='interested'?'conv-interested':'conv-dropped'
      const ov = avg(Object.values(r.scores||{}))
      return `<tr style="cursor:pointer" onclick="selectedId=${p.id};switchTab('live')">
        <td style="display:flex;align-items:center;gap:8px"><div class="persona-avatar" style="width:26px;height:26px;font-size:10px">${p.name.charAt(0)}</div>${p.name}</td>
        <td><span class="conv-badge ${cc}">${CONV_ICONS[cs]||''} ${cs}</span></td>
        ${scoreKeys.map(k=>`<td style="color:${scoreColor(r.scores[k]||0)};font-weight:700">${(r.scores[k]||0).toFixed(1)}</td>`).join('')}
        <td style="color:${scoreColor(ov)};font-weight:800">${ov.toFixed(1)}</td></tr>`
    }).join('')}</tbody></table>`
}

// ── SYNTHESIS ─────────────────────────────────────────
async function runSynthesis() {
  const done = personas.filter(p => results[p.id])
  if (!done.length) return
  switchTab('insights')
  document.getElementById('insightsContent').innerHTML = '<div style="text-align:center;padding:40px 0"><div class="spinner" style="width:24px;height:24px;border-width:3px;margin-bottom:8px"></div><p style="color:var(--t2);font-size:13px">AI đang phân tích...</p></div>'
  try {
    const resp = await fetch('/api/user-simulator/synthesize', {
      method:'POST', headers:{'Content-Type':'application/json'},
      body: JSON.stringify({
        chatbot_prompt: '', system_prompt: '',
        results: done.map(p => ({
          persona_name:p.name, archetype:p.archetype, scores:results[p.id].scores,
          conversion_status:results[p.id].conversion_status||'', conversion_reason:results[p.id].conversion_reason||'',
          key_wins:results[p.id].key_wins||[], key_fails:results[p.id].key_fails||[],
        }))
      })
    })
    const d = await resp.json()
    if (d.status === 'success') { synthesis = d; renderInsights(d) }
    else throw new Error(d.message||'Fail')
  } catch(e) { document.getElementById('insightsContent').innerHTML = `<div style="padding:20px;color:var(--red)">Lỗi: ${e.message}</div>` }
}
function renderInsights(d) {
  const ic = document.getElementById('insightsContent')
  ic.innerHTML = `
    <div class="card" style="margin-bottom:14px;background:rgba(139,92,246,.08);border-color:rgba(139,92,246,.2)">
      <p class="insight-label" style="color:var(--purple)">📋 Executive Summary</p>
      <p style="font-size:13px;color:var(--t1);line-height:1.6">${d.summary||'N/A'}</p>
    </div>
    ${d.systemic_issues?.length?`<div class="card" style="margin-bottom:14px">
      <p class="insight-label" style="color:var(--red)">⚠️ Systemic Issues</p>
      ${d.systemic_issues.map((s,i)=>`<p style="font-size:12.5px;color:var(--t2);margin-bottom:6px;line-height:1.5">${i+1}. ${s}</p>`).join('')}
    </div>`:''}
    ${d.prompt_fixes?.length?`<div class="card" style="margin-bottom:14px">
      <p class="insight-label" style="color:var(--green)">🔧 Prompt Fixes</p>
      ${d.prompt_fixes.map(f=>`<div style="background:rgba(16,185,129,.06);border-radius:8px;padding:10px 12px;margin-bottom:8px;border:1px solid rgba(16,185,129,.15)"><p style="font-size:12px;color:var(--t1);line-height:1.5">${f}</p></div>`).join('')}
    </div>`:''}`
}

// ── PROGRESS BAR ──────────────────────────────────────
function showProgress(cur, total) {
  const bar = document.getElementById('progressBar'); bar.style.display = 'flex'
  document.getElementById('progressLabel').textContent = cur+'/'+total+' personas'
  document.getElementById('progressFill').style.width = (total?cur/total*100:0)+'%'
  if (simStartTime) {
    const s = Math.floor((Date.now()-simStartTime)/1000)
    document.getElementById('progressTime').textContent = Math.floor(s/60)+':'+String(s%60).padStart(2,'0')
  }
}
function hideProgress() { document.getElementById('progressBar').style.display = 'none' }

// ── RENDER ALL ────────────────────────────────────────
function renderAll() { renderTabs(); renderActions(); renderPersonaGrid() }
renderAll()
