import{isLoggedIn,getToken,setAuth,getUser,GET,POST,PUT,ago,fmtDate}from'./auth.js';
import{layout,loading,kpi}from'./ui.js';

const $=id=>document.getElementById(id);
const app=()=>document.getElementById('app');
const main=()=>document.querySelector('main');

/* ═══════════════════════════════════════
   ROUTER + ROUTE PROTECTION
   ═══════════════════════════════════════ */
function route(){
  const h=location.hash.slice(1)||(getToken()?'dashboard':'login');
  if(h!=='login'&&!getToken()){location.hash='#login';return}
  if(h==='login'&&getToken()){location.hash='#dashboard';return}
  const[pg,...p]=h.split('/');
  const param=p.join('/');
  const u=getUser();

  // Route protection by role
  if(u){
    const adminOnly=['users','settings'];
    const agentUp=['assets'];
    if(adminOnly.includes(pg)&&u.role!=='admin'){location.hash='#dashboard';return}
    if(agentUp.includes(pg)&&!['admin','agent'].includes(u.role)){location.hash='#dashboard';return}
  }

  const routes={login:pgLogin,dashboard:pgDash,tickets:pgTickets,'new-ticket':pgNewTicket,assets:pgAssets,knowledge:pgKB,users:pgUsers,settings:pgSettings};
  (routes[pg]||pg404)(param);
}
window.addEventListener('hashchange',route);
document.addEventListener('DOMContentLoaded',route);

/* ═══════════════════════════════════════
   LOGIN
   ═══════════════════════════════════════ */
function pgLogin(){
  app().innerHTML=`<div class="min-h-screen flex items-center justify-center bg-gradient-to-br from-gray-50 to-gray-100 dark:from-gray-900 dark:to-gray-800 p-4">
  <div class="w-full max-w-md bg-white dark:bg-gray-800 rounded-2xl shadow-xl p-8 border border-gray-200 dark:border-gray-700">
    <div class="text-center mb-8"><div class="w-16 h-16 bg-[#007A33] rounded-2xl flex items-center justify-center mx-auto mb-4"><i class="fas fa-headset text-2xl text-white"></i></div><h1 class="text-2xl font-bold text-gray-800 dark:text-white">HelpDesk ITSM</h1><p class="text-sm text-gray-500 mt-1">Sistema de Gestión de Servicios de TI</p></div>
    <form id="lf" class="space-y-5">
      <div><label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Email</label><input id="le" type="email" required class="input-field" placeholder="correo@empresa.com"></div>
      <div><label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Contraseña</label><input id="lp" type="password" required class="input-field" placeholder="••••••••"></div>
      <button type="submit" class="btn-primary w-full justify-center"><i class="fas fa-sign-in-alt mr-2"></i>Ingresar</button>
      <div id="lerr" class="hidden p-3 rounded-lg bg-red-50 dark:bg-red-900/30 text-red-600 dark:text-red-400 text-sm text-center"></div>
    </form>
  </div></div>`;
  $('lf').onsubmit=async e=>{e.preventDefault();$('lerr').classList.add('hidden');try{
    const r=await fetch('/api/auth/login',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({email:$('le').value,password:$('lp').value})});
    const d=await r.json();if(!r.ok)throw new Error(d.error);setAuth(d.token,d.user);location.hash='#dashboard';
  }catch(err){$('lerr').textContent=err.message;$('lerr').classList.remove('hidden')}};
}

/* ═══════════════════════════════════════
   DASHBOARD — Role-based routing
   ═══════════════════════════════════════ */
async function pgDash(){
  const u=getUser();
  if(u.role==='client') return pgDashClient();
  if(u.role==='agent') return pgDashAgent();
  return pgDashAdmin();
}

/* ─── ADMIN DASHBOARD ─── */
async function pgDashAdmin(){
  app().innerHTML=layout('Dashboard',loading,'dashboard');
  try{
    const d=await GET('/api/dashboard');const u=getUser();
    const satAvg=d.satisfaction?.avg?Number(d.satisfaction.avg).toFixed(1):'—';
    const satTotal=d.satisfaction?.total||0;
    main().innerHTML=`<div class="space-y-6">
      <div class="flex flex-wrap justify-between items-center gap-4">
        <p class="text-gray-500 dark:text-gray-400">Bienvenido, <strong class="text-gray-800 dark:text-white">${u.name}</strong> <span class="text-xs bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400 px-2 py-0.5 rounded-full ml-1">Administrador</span></p>
        <a href="#new-ticket" class="btn-primary"><i class="fas fa-plus mr-2"></i>Nuevo Ticket</a>
      </div>
      <div class="grid grid-cols-2 lg:grid-cols-4 gap-4">
        ${kpi('Abiertos',d.openTickets,'fa-ticket','blue')}
        ${kpi('Resueltos Hoy',d.resolvedToday,'fa-check-circle','green')}
        ${kpi('SLA Vencidos',d.slaBreached,'fa-exclamation-triangle','red')}
        ${kpi('Satisfacción',satAvg!=='—'?satAvg+' ★':'—','fa-smile','purple')}
      </div>
      <div class="grid lg:grid-cols-2 gap-6">
        <div class="card p-5"><h3 class="font-semibold dark:text-white mb-4">Por Estado</h3><div class="space-y-3">${d.byStatus.map(s=>`<div class="flex justify-between items-center"><div class="flex items-center gap-2"><div class="w-3 h-3 rounded-full" style="background:${s.color}"></div><span class="text-sm text-gray-600 dark:text-gray-300">${s.name}</span></div><div class="flex items-center gap-3"><div class="w-20 bg-gray-200 dark:bg-gray-700 rounded-full h-1.5"><div class="h-1.5 rounded-full" style="background:${s.color};width:${d.openTickets?Math.round(s.count/(d.openTickets+d.resolvedToday+(d.slaBreached||0))*100):0}%"></div></div><span class="font-bold dark:text-white text-sm w-6 text-right">${s.count}</span></div></div>`).join('')}</div></div>
        <div class="card p-5"><h3 class="font-semibold dark:text-white mb-4">Por Prioridad</h3><div class="space-y-3">${d.byPriority.map(p=>{const colors={critical:'#EF4444',high:'#F97316',medium:'#EAB308',low:'#22C55E'};return`<div class="flex justify-between items-center"><div class="flex items-center gap-2"><div class="w-3 h-3 rounded-full" style="background:${colors[p.priority]||'#6B7280'}"></div><span class="text-sm capitalize text-gray-600 dark:text-gray-300">${p.priority==='critical'?'Crítico':p.priority==='high'?'Alto':p.priority==='medium'?'Medio':'Bajo'}</span></div><span class="font-bold dark:text-white">${p.count}</span></div>`}).join('')}</div></div>
      </div>
      ${d.agentStats?.length?`<div class="card p-5"><h3 class="font-semibold dark:text-white mb-4"><i class="fas fa-users mr-2 text-gray-400"></i>Rendimiento de Agentes</h3><div class="overflow-x-auto"><table class="w-full text-sm"><thead><tr><th class="text-left py-2 text-xs text-gray-500 uppercase">Agente</th><th class="text-left py-2 text-xs text-gray-500 uppercase">Asignados</th><th class="text-left py-2 text-xs text-gray-500 uppercase">Resueltos</th><th class="text-left py-2 text-xs text-gray-500 uppercase">Prom. Horas</th><th class="text-left py-2 text-xs text-gray-500 uppercase">Eficiencia</th></tr></thead><tbody>${d.agentStats.map(a=>{const eff=a.total_tickets>0?Math.round(a.resolved/a.total_tickets*100):0;return`<tr class="border-t border-gray-100 dark:border-gray-700"><td class="py-3 dark:text-white font-medium">${a.name}</td><td class="py-3 text-gray-500">${a.total_tickets}</td><td class="py-3 text-gray-500">${a.resolved}</td><td class="py-3 text-gray-500">${a.avg_hours?Math.round(a.avg_hours)+'h':'—'}</td><td class="py-3"><div class="flex items-center gap-2"><div class="w-20 bg-gray-200 dark:bg-gray-700 rounded-full h-2"><div class="bg-[#007A33] h-2 rounded-full transition-all" style="width:${eff}%"></div></div><span class="text-xs font-medium ${eff>=70?'text-green-600':eff>=40?'text-yellow-600':'text-red-600'}">${eff}%</span></div></td></tr>`}).join('')}</tbody></table></div></div>`:''}
      <div class="grid lg:grid-cols-3 gap-6">
        <div class="lg:col-span-2 card"><div class="p-5 border-b border-gray-200 dark:border-gray-700 flex justify-between items-center"><h3 class="font-semibold dark:text-white">Tickets Recientes</h3><a href="#tickets" class="text-sm text-[#007A33] hover:underline">Ver todos →</a></div>
        <div class="overflow-x-auto"><table class="w-full text-sm"><thead class="bg-gray-50 dark:bg-gray-700/50"><tr><th class="text-left px-5 py-3 text-xs text-gray-500 uppercase">ID</th><th class="text-left px-5 py-3 text-xs text-gray-500 uppercase">Asunto</th><th class="text-left px-5 py-3 text-xs text-gray-500 uppercase">Estado</th><th class="text-left px-5 py-3 text-xs text-gray-500 uppercase">Prioridad</th><th class="text-left px-5 py-3 text-xs text-gray-500 uppercase">Creado</th></tr></thead>
        <tbody class="divide-y divide-gray-100 dark:divide-gray-700">${d.recent.length?d.recent.map(t=>`<tr class="hover:bg-gray-50 dark:hover:bg-gray-700/30 cursor-pointer" onclick="location.hash='#tickets/${t.id}'"><td class="px-5 py-3 font-medium text-[#007A33]">#${t.id}</td><td class="px-5 py-3 dark:text-gray-200 max-w-[200px] truncate">${t.subject}</td><td class="px-5 py-3"><span class="badge text-white" style="background:${t.status_color}">${t.status_name}</span></td><td class="px-5 py-3"><span class="text-xs font-medium px-2 py-0.5 rounded-full ${t.priority==='critical'?'bg-red-100 text-red-700':t.priority==='high'?'bg-orange-100 text-orange-700':t.priority==='medium'?'bg-yellow-100 text-yellow-700':'bg-green-100 text-green-700'} capitalize">${t.priority}</span></td><td class="px-5 py-3 text-gray-500 text-xs">${ago(t.created_at)}</td></tr>`).join(''):'<tr><td colspan="5" class="px-5 py-10 text-center text-gray-400">No hay tickets</td></tr>'}</tbody></table></div></div>
        <div class="space-y-6">
          <div class="card p-5"><h3 class="font-semibold dark:text-white mb-3"><i class="fas fa-chart-line mr-2 text-gray-400"></i>Métricas</h3>
            <div class="space-y-4">
              <div><p class="text-xs text-gray-500 mb-1">Resp. Promedio</p><p class="text-xl font-bold dark:text-white">${d.avgResponseMinutes}m</p></div>
              <div><p class="text-xs text-gray-500 mb-1">Resolución Promedio</p><p class="text-xl font-bold dark:text-white">${d.avgResolutionHours||0}h</p></div>
              <div><p class="text-xs text-gray-500 mb-1">Satisfacción</p><p class="text-xl font-bold dark:text-white">${satAvg!=='—'?satAvg+' ★ <span class="text-xs text-gray-400 font-normal">('+satTotal+' votos)</span>':'Sin datos'}</p></div>
            </div>
          </div>
          ${d.unreadNotifications>0?`<div class="card p-5 bg-blue-50 dark:bg-blue-900/20 border-blue-200 dark:border-blue-800"><p class="text-sm text-blue-700 dark:text-blue-300"><i class="fas fa-bell mr-2"></i>Tienes <strong>${d.unreadNotifications}</strong> notificaciones sin leer</p></div>`:''}
        </div>
      </div>
    </div>`;
  }catch(e){main().innerHTML=`<p class="text-red-500 p-8">Error: ${e.message}</p>`}
}

/* ─── AGENT DASHBOARD ─── */
async function pgDashAgent(){
  app().innerHTML=layout('Dashboard',loading,'dashboard');
  try{
    const d=await GET('/api/dashboard');const u=getUser();
    main().innerHTML=`<div class="space-y-6">
      <div class="flex flex-wrap justify-between items-center gap-4">
        <p class="text-gray-500 dark:text-gray-400">Bienvenido, <strong class="text-gray-800 dark:text-white">${u.name}</strong> <span class="text-xs bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-400 px-2 py-0.5 rounded-full ml-1">Agente de Soporte</span></p>
        <a href="#new-ticket" class="btn-primary"><i class="fas fa-plus mr-2"></i>Nuevo Ticket</a>
      </div>
      <div class="grid grid-cols-2 lg:grid-cols-4 gap-4">
        ${kpi('Tickets Abiertos',d.openTickets,'fa-ticket','blue')}
        ${kpi('Resueltos Hoy',d.resolvedToday,'fa-check-circle','green')}
        ${kpi('SLA Vencidos',d.slaBreached,'fa-exclamation-triangle','red')}
        ${kpi('Resp. Promedio',d.avgResponseMinutes+'m','fa-clock','purple')}
      </div>
      <div class="grid lg:grid-cols-2 gap-6">
        <div class="card p-5"><h3 class="font-semibold dark:text-white mb-4">Por Estado</h3><div class="space-y-3">${d.byStatus.map(s=>`<div class="flex justify-between items-center"><div class="flex items-center gap-2"><div class="w-3 h-3 rounded-full" style="background:${s.color}"></div><span class="text-sm text-gray-600 dark:text-gray-300">${s.name}</span></div><span class="font-bold dark:text-white">${s.count}</span></div>`).join('')}</div></div>
        <div class="card p-5"><h3 class="font-semibold dark:text-white mb-4">Por Prioridad</h3><div class="space-y-3">${d.byPriority.map(p=>`<div class="flex justify-between"><span class="text-sm capitalize text-gray-600 dark:text-gray-300">${p.priority==='critical'?'Crítico':p.priority==='high'?'Alto':p.priority==='medium'?'Medio':'Bajo'}</span><span class="font-bold dark:text-white">${p.count}</span></div>`).join('')}</div></div>
      </div>
      <div class="card"><div class="p-5 border-b border-gray-200 dark:border-gray-700 flex justify-between items-center"><h3 class="font-semibold dark:text-white">Tickets Recientes</h3><a href="#tickets" class="text-sm text-[#007A33] hover:underline">Ver todos →</a></div>
      <div class="overflow-x-auto"><table class="w-full text-sm"><thead class="bg-gray-50 dark:bg-gray-700/50"><tr><th class="text-left px-5 py-3 text-xs text-gray-500 uppercase">ID</th><th class="text-left px-5 py-3 text-xs text-gray-500 uppercase">Asunto</th><th class="text-left px-5 py-3 text-xs text-gray-500 uppercase">Estado</th><th class="text-left px-5 py-3 text-xs text-gray-500 uppercase">Prioridad</th><th class="text-left px-5 py-3 text-xs text-gray-500 uppercase">Creado</th></tr></thead>
      <tbody class="divide-y divide-gray-100 dark:divide-gray-700">${d.recent.length?d.recent.map(t=>`<tr class="hover:bg-gray-50 dark:hover:bg-gray-700/30 cursor-pointer" onclick="location.hash='#tickets/${t.id}'"><td class="px-5 py-3 font-medium text-[#007A33]">#${t.id}</td><td class="px-5 py-3 dark:text-gray-200">${t.subject}</td><td class="px-5 py-3"><span class="badge text-white" style="background:${t.status_color}">${t.status_name}</span></td><td class="px-5 py-3"><span class="text-xs font-medium px-2 py-0.5 rounded-full ${t.priority==='critical'?'bg-red-100 text-red-700':t.priority==='high'?'bg-orange-100 text-orange-700':t.priority==='medium'?'bg-yellow-100 text-yellow-700':'bg-green-100 text-green-700'} capitalize">${t.priority}</span></td><td class="px-5 py-3 text-gray-500 text-xs">${ago(t.created_at)}</td></tr>`).join(''):'<tr><td colspan="5" class="px-5 py-10 text-center text-gray-400">Sin tickets</td></tr>'}</tbody></table></div></div>
    </div>`;
  }catch(e){main().innerHTML=`<p class="text-red-500 p-8">Error: ${e.message}</p>`}
}

/* ─── CLIENT DASHBOARD ─── */
async function pgDashClient(){
  app().innerHTML=layout('Mi Portal de Soporte',loading,'dashboard');
  try{
    const d=await GET('/api/dashboard');const u=getUser();
    const openCount=d.byStatus.filter(s=>!['Resuelto (cierre)','Cerrado (cierre)'].includes(s.name)).reduce((a,b)=>a+b.count,0);
    const closedCount=d.byStatus.filter(s=>['Resuelto (cierre)','Cerrado (cierre)'].includes(s.name)).reduce((a,b)=>a+b.count,0);
    main().innerHTML=`<div class="space-y-6">
      <div class="flex flex-wrap justify-between items-center gap-4">
        <div><p class="text-gray-500 dark:text-gray-400">Bienvenido, <strong class="text-gray-800 dark:text-white">${u.name}</strong></p><p class="text-xs text-gray-400 mt-1">Desde aquí puedes gestionar tus solicitudes de soporte</p></div>
        <a href="#new-ticket" class="btn-primary"><i class="fas fa-plus mr-2"></i>Nueva Solicitud</a>
      </div>
      <div class="grid grid-cols-3 gap-4">
        ${kpi('Abiertas',openCount,'fa-folder-open','blue')}
        ${kpi('Resueltas',closedCount,'fa-check-circle','green')}
        ${kpi('Total',d.recent.length,'fa-ticket','purple')}
      </div>
      <div class="card p-5 bg-gradient-to-r from-green-50 to-emerald-50 dark:from-green-900/20 dark:to-emerald-900/20 border-green-200 dark:border-green-800">
        <div class="flex items-start gap-4">
          <div class="w-10 h-10 bg-green-100 dark:bg-green-900/40 rounded-xl flex items-center justify-center flex-shrink-0"><i class="fas fa-lightbulb text-green-600"></i></div>
          <div><h3 class="font-semibold text-green-800 dark:text-green-300">¿Necesitas ayuda rápida?</h3>
          <p class="text-sm text-green-700 dark:text-green-400 mt-1">Revisa nuestra Base de Conocimiento. Puede que ya tengamos la solución a tu problema.</p>
          <a href="#knowledge" class="inline-flex items-center gap-2 text-sm font-medium text-green-700 dark:text-green-300 hover:underline mt-2"><i class="fas fa-book"></i>Ir a la Base de Conocimiento →</a></div>
        </div>
      </div>
      <div class="card"><div class="p-5 border-b border-gray-200 dark:border-gray-700"><h3 class="font-semibold dark:text-white">Mis Solicitudes</h3></div>
      <div class="overflow-x-auto"><table class="w-full text-sm"><thead class="bg-gray-50 dark:bg-gray-700/50"><tr><th class="text-left px-5 py-3 text-xs text-gray-500 uppercase">N°</th><th class="text-left px-5 py-3 text-xs text-gray-500 uppercase">Asunto</th><th class="text-left px-5 py-3 text-xs text-gray-500 uppercase">Estado</th><th class="text-left px-5 py-3 text-xs text-gray-500 uppercase">Prioridad</th><th class="text-left px-5 py-3 text-xs text-gray-500 uppercase">Fecha</th></tr></thead>
      <tbody class="divide-y divide-gray-100 dark:divide-gray-700">${d.recent.length?d.recent.map(t=>`<tr class="hover:bg-gray-50 dark:hover:bg-gray-700/30 cursor-pointer" onclick="location.hash='#tickets/${t.id}'"><td class="px-5 py-3 font-medium text-[#007A33]">#${t.id}</td><td class="px-5 py-3 dark:text-gray-200">${t.subject}</td><td class="px-5 py-3"><span class="badge text-white" style="background:${t.status_color}">${t.status_name}</span></td><td class="px-5 py-3"><span class="text-xs font-medium px-2 py-0.5 rounded-full ${t.priority==='critical'?'bg-red-100 text-red-700':t.priority==='high'?'bg-orange-100 text-orange-700':t.priority==='medium'?'bg-yellow-100 text-yellow-700':'bg-green-100 text-green-700'} capitalize">${t.priority}</span></td><td class="px-5 py-3 text-gray-500 text-xs">${ago(t.created_at)}</td></tr>`).join(''):'<tr><td colspan="5" class="px-5 py-10 text-center text-gray-400"><div class="py-4"><i class="fas fa-inbox text-4xl text-gray-300 mb-3 block"></i><p>No tienes solicitudes aún</p><a href="#new-ticket" class="text-[#007A33] hover:underline text-sm mt-2 inline-block">Crear tu primera solicitud →</a></div></td></tr>'}</tbody></table></div></div>
    </div>`;
  }catch(e){main().innerHTML=`<p class="text-red-500 p-8">Error: ${e.message}</p>`}
}

/* ═══════════════════════════════════════
   TICKETS LIST + FILTERS + SEARCH
   ═══════════════════════════════════════ */
let ticketFilters={status:'',priority:'',category:'',assigned:'',search:''};

async function pgTickets(param){
  if(param==='new')return pgNewTicket();
  if(param&&!isNaN(param))return pgTicketDetail(param);
  app().innerHTML=layout('Tickets',loading,'tickets');
  try{
    const u=getUser(),isAg=['admin','agent'].includes(u.role),isClient=u.role==='client';
    // Load filter data
    let statuses=[],categories=[],agents=[];
    if(isAg){
      [statuses,categories,agents]=await Promise.all([GET('/api/admin/statuses'),GET('/api/admin/categories'),GET('/api/admin/agents')]);
      categories=categories.filter(c=>!c.parent_id);
    }

    const qs=Object.entries(ticketFilters).filter(([_,v])=>v).map(([k,v])=>`${k}=${encodeURIComponent(v)}`).join('&');
    const d=await GET('/api/tickets?limit=50'+(qs?'&'+qs:''));

    main().innerHTML=`<div class="space-y-4">
      <div class="flex justify-between items-center flex-wrap gap-3">
        <h2 class="text-xl font-bold dark:text-white">${d.total} ${isClient?'solicitudes':'tickets'}</h2>
        <div class="flex items-center gap-3">
          ${isAg?`<div class="relative"><input id="tsearch" type="text" placeholder="Buscar tickets..." value="${ticketFilters.search}" class="input-field pl-9 pr-4 py-2 text-sm w-56"><i class="fas fa-search absolute left-3 top-1/2 -translate-y-1/2 text-gray-400 text-xs"></i></div>`:''}
          <a href="#new-ticket" class="btn-primary"><i class="fas fa-plus mr-2"></i>${isClient?'Nueva Solicitud':'Nuevo'}</a>
        </div>
      </div>
      ${isAg?`<div class="card p-3"><div class="flex flex-wrap gap-3 items-center">
        <span class="text-xs text-gray-500 font-medium"><i class="fas fa-filter mr-1"></i>Filtros:</span>
        <select id="fStatus" class="input-field py-1.5 text-sm w-auto"><option value="">Estado</option>${statuses.map(s=>`<option value="${s.name}"${ticketFilters.status===s.name?' selected':''}>${s.name}</option>`).join('')}</select>
        <select id="fPriority" class="input-field py-1.5 text-sm w-auto"><option value="">Prioridad</option>${['critical','high','medium','low'].map(p=>`<option value="${p}"${ticketFilters.priority===p?' selected':''}>${p==='critical'?'Crítico':p==='high'?'Alto':p==='medium'?'Medio':'Bajo'}</option>`).join('')}</select>
        <select id="fCategory" class="input-field py-1.5 text-sm w-auto"><option value="">Categoría</option>${categories.map(c=>`<option value="${c.id}"${ticketFilters.category==c.id?' selected':''}>${c.name}</option>`).join('')}</select>
        <select id="fAgent" class="input-field py-1.5 text-sm w-auto"><option value="">Agente</option>${agents.map(a=>`<option value="${a.id}"${ticketFilters.assigned==a.id?' selected':''}>${a.name}</option>`).join('')}</select>
        ${Object.values(ticketFilters).some(v=>v)?`<button id="clearFilters" class="text-xs text-red-500 hover:text-red-700 font-medium"><i class="fas fa-times mr-1"></i>Limpiar</button>`:''}
      </div></div>`:''}
      <div class="card overflow-x-auto"><table class="w-full text-sm"><thead class="bg-gray-50 dark:bg-gray-700/50"><tr><th class="text-left px-5 py-3 text-xs text-gray-500 uppercase">ID</th><th class="text-left px-5 py-3 text-xs text-gray-500 uppercase">Asunto</th>${!isClient?'<th class="text-left px-5 py-3 text-xs text-gray-500 uppercase">Categoría</th>':''}<th class="text-left px-5 py-3 text-xs text-gray-500 uppercase">Estado</th><th class="text-left px-5 py-3 text-xs text-gray-500 uppercase">Prioridad</th>${!isClient?'<th class="text-left px-5 py-3 text-xs text-gray-500 uppercase">Agente</th>':''}<th class="text-left px-5 py-3 text-xs text-gray-500 uppercase">SLA</th><th class="text-left px-5 py-3 text-xs text-gray-500 uppercase">Fecha</th></tr></thead>
      <tbody class="divide-y divide-gray-100 dark:divide-gray-700">${d.data.length?d.data.map(t=>{
        const slaOk=!t.sla_resolution_due||t.is_closed||new Date(t.sla_resolution_due)>new Date();
        const slaHtml=t.sla_resolution_due?(slaOk?'<span class="text-xs text-green-600"><i class="fas fa-check-circle"></i></span>':'<span class="text-xs text-red-600 font-bold"><i class="fas fa-exclamation-circle"></i> Vencido</span>'):'<span class="text-xs text-gray-400">—</span>';
        return`<tr class="hover:bg-gray-50 dark:hover:bg-gray-700/30 cursor-pointer" onclick="location.hash='#tickets/${t.id}'"><td class="px-5 py-3 font-medium text-[#007A33]">#${t.id}</td><td class="px-5 py-3 dark:text-gray-200 max-w-xs truncate">${t.subject}${t.comment_count?` <span class="text-xs text-gray-400"><i class="fas fa-comment"></i>${t.comment_count}</span>`:''}</td>${!isClient?`<td class="px-5 py-3 text-gray-500 text-xs">${t.category_name||'—'}</td>`:''}<td class="px-5 py-3"><span class="badge text-white" style="background:${t.status_color}">${t.status_name}</span></td><td class="px-5 py-3"><span class="text-xs font-medium px-2 py-0.5 rounded-full ${t.priority==='critical'?'bg-red-100 text-red-700':t.priority==='high'?'bg-orange-100 text-orange-700':t.priority==='medium'?'bg-yellow-100 text-yellow-700':'bg-green-100 text-green-700'} capitalize">${t.priority}</span></td>${!isClient?`<td class="px-5 py-3 text-gray-500 text-xs">${t.agent_name||'<span class="text-orange-500">Sin asignar</span>'}</td>`:''}<td class="px-5 py-3">${slaHtml}</td><td class="px-5 py-3 text-gray-500 text-xs">${ago(t.created_at)}</td></tr>`}).join(''):'<tr><td colspan="8" class="px-5 py-10 text-center text-gray-400">No hay tickets con estos filtros</td></tr>'}</tbody></table></div>
    </div>`;

    // Bind filter events
    const applyFilter=()=>{
      ticketFilters.status=$('fStatus')?.value||'';
      ticketFilters.priority=$('fPriority')?.value||'';
      ticketFilters.category=$('fCategory')?.value||'';
      ticketFilters.assigned=$('fAgent')?.value||'';
      pgTickets();
    };
    $('fStatus')?.addEventListener('change',applyFilter);
    $('fPriority')?.addEventListener('change',applyFilter);
    $('fCategory')?.addEventListener('change',applyFilter);
    $('fAgent')?.addEventListener('change',applyFilter);
    $('clearFilters')?.addEventListener('click',()=>{ticketFilters={status:'',priority:'',category:'',assigned:'',search:''};pgTickets()});
    let searchTimer;
    $('tsearch')?.addEventListener('input',e=>{clearTimeout(searchTimer);searchTimer=setTimeout(()=>{ticketFilters.search=e.target.value;pgTickets()},400)});
  }catch(e){main().innerHTML=`<p class="text-red-500 p-8">Error: ${e.message}</p>`}
}

/* ═══════════════════════════════════════
   TICKET DETAIL
   ═══════════════════════════════════════ */
async function pgTicketDetail(id){
  app().innerHTML=layout('Ticket #'+id,loading,'tickets');
  try{
    const u=getUser(),isAg=['admin','agent'].includes(u.role);
    const promises=[GET(`/api/tickets/${id}`)];
    if(isAg){promises.push(GET('/api/admin/statuses'));promises.push(GET('/api/admin/agents'))}
    const results=await Promise.all(promises);
    const t=results[0],sts=results[1]||[],ags=results[2]||[];

    let aiInfo='';
    try{const ai=t.ai_summary?JSON.parse(t.ai_summary):null;if(ai?.summary)aiInfo=`<div class="mt-4 p-4 bg-purple-50 dark:bg-purple-900/20 rounded-lg border border-purple-200 dark:border-purple-800"><div class="flex items-center gap-2 mb-2"><i class="fas fa-robot text-purple-600"></i><span class="text-xs font-semibold text-purple-600">Análisis IA — Confianza: ${Math.round((ai.confidence||0)*100)}%</span></div><p class="text-sm text-purple-800 dark:text-purple-300">${ai.summary}</p>${ai.suggested_response?`<p class="text-xs text-purple-600 mt-2"><strong>Sugerencia:</strong> ${ai.suggested_response}</p>`:''}${ai.kb_article?`<p class="text-xs text-purple-500 mt-1"><i class="fas fa-book mr-1"></i>Artículo relacionado: ${ai.kb_article}</p>`:''}</div>`}catch{}

    // SLA indicator
    let slaHtml='';
    if(t.sla_resolution_due && !t.is_closed){
      const due=new Date(t.sla_resolution_due),now=new Date();
      const totalMs=due.getTime()-new Date(t.created_at).getTime();
      const elapsedMs=now.getTime()-new Date(t.created_at).getTime();
      const pct=Math.min(100,Math.max(0,Math.round(elapsedMs/totalMs*100)));
      const remaining=due.getTime()-now.getTime();
      const overdue=remaining<0;
      const remText=overdue?'VENCIDO':remaining<3600000?Math.round(remaining/60000)+'m restantes':Math.round(remaining/3600000)+'h restantes';
      slaHtml=`<div class="card p-4 ${overdue?'bg-red-50 dark:bg-red-900/20 border-red-200 dark:border-red-800':''}"><div class="flex justify-between items-center mb-2"><span class="text-xs font-medium ${overdue?'text-red-600':'text-gray-500'}"><i class="fas fa-clock mr-1"></i>SLA Resolución</span><span class="text-xs font-bold ${overdue?'text-red-600':pct>75?'text-orange-600':'text-green-600'}">${remText}</span></div><div class="w-full bg-gray-200 dark:bg-gray-700 rounded-full h-2"><div class="h-2 rounded-full transition-all ${overdue?'bg-red-500':pct>75?'bg-orange-500':pct>50?'bg-yellow-500':'bg-green-500'}" style="width:${Math.min(pct,100)}%"></div></div><p class="text-xs text-gray-400 mt-1">Vence: ${fmtDate(t.sla_resolution_due)}</p></div>`;
    }

    // Rating for client on closed tickets
    let ratingHtml='';
    if(u.role==='client' && t.is_closed && !t.satisfaction_rating){
      ratingHtml=`<div class="card p-5 bg-yellow-50 dark:bg-yellow-900/10 border-yellow-200 dark:border-yellow-800"><h3 class="font-semibold text-yellow-800 dark:text-yellow-300 mb-3"><i class="fas fa-star mr-2"></i>¿Cómo fue tu experiencia?</h3><div class="flex gap-1" id="ratingStars">${[1,2,3,4,5].map(n=>`<button data-r="${n}" class="text-3xl text-gray-300 hover:text-yellow-400 transition-colors rating-star"><i class="fas fa-star"></i></button>`).join('')}</div><p class="text-xs text-gray-400 mt-2">Tu opinión nos ayuda a mejorar</p></div>`;
    } else if(t.satisfaction_rating){
      ratingHtml=`<div class="card p-4"><div class="flex items-center gap-2"><span class="text-sm text-gray-500">Calificación:</span><span class="text-yellow-500">${'★'.repeat(t.satisfaction_rating)}${'☆'.repeat(5-t.satisfaction_rating)}</span></div></div>`;
    }

    main().innerHTML=`<div class="space-y-6">
      <div class="flex items-center gap-3 flex-wrap"><a href="#tickets" class="text-gray-400 hover:text-gray-600 transition"><i class="fas fa-arrow-left"></i></a><h2 class="text-xl font-bold dark:text-white">${t.subject}</h2><span class="badge text-white" style="background:${t.status_color}">${t.status_name}</span><span class="text-xs font-medium px-2 py-0.5 rounded-full ${t.priority==='critical'?'bg-red-100 text-red-700':t.priority==='high'?'bg-orange-100 text-orange-700':t.priority==='medium'?'bg-yellow-100 text-yellow-700':'bg-green-100 text-green-700'} capitalize">${t.priority}</span></div>
      <div class="grid lg:grid-cols-3 gap-6">
        <div class="lg:col-span-2 space-y-4">
          <div class="card p-5"><div class="text-gray-700 dark:text-gray-300 whitespace-pre-wrap">${t.description}</div>${aiInfo}${t.attachments?.length?`<div class="mt-4 flex flex-wrap gap-2">${t.attachments.map(a=>`<a href="/uploads/${a.filename}" target="_blank" class="inline-flex items-center gap-1 px-3 py-1.5 bg-gray-100 dark:bg-gray-700 rounded-lg text-xs hover:bg-gray-200 transition"><i class="fas fa-paperclip"></i>${a.original_name}</a>`).join('')}</div>`:''}</div>
          <div class="card"><div class="p-5 border-b border-gray-200 dark:border-gray-700"><h3 class="font-semibold dark:text-white"><i class="fas fa-comments mr-2 text-gray-400"></i>Conversación (${t.comments?.length||0})</h3></div>
          <div class="divide-y divide-gray-100 dark:divide-gray-700 max-h-96 overflow-y-auto">${t.comments?.length?t.comments.map(c=>`<div class="p-5 ${c.is_internal?'bg-yellow-50 dark:bg-yellow-900/10 border-l-4 border-yellow-400':''}"><div class="flex justify-between mb-2"><span class="font-medium text-sm dark:text-white">${c.user_name} <span class="text-xs px-1.5 py-0.5 rounded ${c.user_role==='admin'?'bg-green-100 text-green-700':c.user_role==='agent'?'bg-blue-100 text-blue-700':'bg-gray-100 text-gray-600'}">${c.user_role}</span>${c.is_internal?' <span class="text-xs text-yellow-600 bg-yellow-100 px-1.5 py-0.5 rounded">🔒 Interno</span>':''}</span><span class="text-xs text-gray-400">${fmtDate(c.created_at)}</span></div><p class="text-sm text-gray-700 dark:text-gray-300 whitespace-pre-wrap">${c.comment}</p></div>`).join(''):'<p class="p-5 text-gray-400 text-sm text-center"><i class="fas fa-comment-slash mr-2"></i>Sin comentarios aún</p>'}</div>
          ${!t.is_closed?`<div class="p-5 border-t border-gray-200 dark:border-gray-700"><form id="cf"><textarea id="ct" rows="3" required class="input-field" placeholder="${u.role==='client'?'Escribe tu mensaje...':'Escribe un comentario...'}"></textarea><div class="flex justify-between items-center mt-3">${isAg?'<label class="flex items-center gap-2 text-sm text-gray-500 cursor-pointer"><input type="checkbox" id="ci" class="rounded"><span>Nota interna</span></label>':'<div></div>'}<button type="submit" class="btn-primary"><i class="fas fa-paper-plane mr-1"></i>Enviar</button></div></form></div>`:''}</div>
          ${isAg?`<div class="flex gap-3 flex-wrap"><button id="aiBtn" class="flex-1 py-2.5 px-4 rounded-xl text-white text-sm font-medium transition-all hover:shadow-lg" style="background:linear-gradient(135deg,#7c3aed,#9333ea)"><i class="fas fa-robot mr-2"></i>Sugerir Respuesta IA</button><button id="aiAnalyze" class="py-2.5 px-4 rounded-xl bg-purple-100 text-purple-700 text-sm font-medium hover:bg-purple-200 transition"><i class="fas fa-brain mr-1"></i>Analizar</button></div>`:''}
          ${ratingHtml}
        </div>
        <div class="space-y-4">
          ${isAg?`<div class="card p-5 space-y-4"><h3 class="font-semibold dark:text-white"><i class="fas fa-cog mr-2 text-gray-400"></i>Gestionar</h3><form id="uf" class="space-y-3">
            <div><label class="text-xs text-gray-500">Estado</label><select id="us" class="input-field">${sts.map(s=>`<option value="${s.id}"${s.id===t.status_id?' selected':''}>${s.name}</option>`).join('')}</select></div>
            <div><label class="text-xs text-gray-500">Prioridad</label><select id="up" class="input-field">${['low','medium','high','critical'].map(p=>`<option value="${p}"${p===t.priority?' selected':''}>${p==='critical'?'Crítico':p==='high'?'Alto':p==='medium'?'Medio':'Bajo'}</option>`).join('')}</select></div>
            <div><label class="text-xs text-gray-500">Asignado a</label><select id="ua" class="input-field"><option value="">Sin asignar</option>${ags.map(a=>`<option value="${a.id}"${a.id===t.assigned_to?' selected':''}>${a.name}</option>`).join('')}</select></div>
            <button type="submit" class="btn-primary w-full justify-center">Actualizar</button></form></div>`:``}
          ${slaHtml}
          <div class="card p-5 space-y-3 text-sm"><h3 class="font-semibold dark:text-white"><i class="fas fa-info-circle mr-2 text-gray-400"></i>Detalles</h3>
            ${isAg?`<div class="flex justify-between"><span class="text-gray-500">Creado por</span><span class="dark:text-white font-medium">${t.creator_name}</span></div>`:''}
            <div class="flex justify-between"><span class="text-gray-500">Categoría</span><span class="dark:text-white">${t.category_name||'—'}</span></div>
            ${t.subcategory_name?`<div class="flex justify-between"><span class="text-gray-500">Subcategoría</span><span class="dark:text-white">${t.subcategory_name}</span></div>`:''}
            ${isAg&&t.asset_name?`<div class="flex justify-between"><span class="text-gray-500">Activo</span><span class="dark:text-white">[${t.asset_tag}] ${t.asset_name}</span></div>`:''}
            <div class="flex justify-between"><span class="text-gray-500">Creado</span><span class="dark:text-white">${fmtDate(t.created_at)}</span></div>
            ${t.first_response_at?`<div class="flex justify-between"><span class="text-gray-500">Primera respuesta</span><span class="dark:text-white">${fmtDate(t.first_response_at)}</span></div>`:''}
            ${t.resolved_at?`<div class="flex justify-between"><span class="text-gray-500">Resuelto</span><span class="dark:text-white">${fmtDate(t.resolved_at)}</span></div>`:''}
          </div>
        </div>
      </div></div>`;

    // Event bindings
    $('cf')?.addEventListener('submit',async e=>{e.preventDefault();const btn=e.target.querySelector('button[type=submit]');btn.innerHTML='<i class="fas fa-spinner fa-spin mr-1"></i>Enviando...';btn.disabled=true;await POST(`/api/tickets/${id}/comments`,{comment:$('ct').value,is_internal:$('ci')?.checked||false});pgTicketDetail(id)});
    $('uf')?.addEventListener('submit',async e=>{e.preventDefault();await PUT(`/api/tickets/${id}`,{status_id:+$('us').value,priority:$('up').value,assigned_to:$('ua').value?+$('ua').value:null});pgTicketDetail(id)});
    $('aiBtn')?.addEventListener('click',async()=>{const b=$('aiBtn');b.innerHTML='<i class="fas fa-spinner fa-spin mr-2"></i>Generando respuesta...';b.disabled=true;const r=await GET(`/api/tickets/${id}/ai-suggest`);if($('ct')&&r.suggestion)$('ct').value=r.suggestion;b.innerHTML='<i class="fas fa-robot mr-2"></i>Sugerir Respuesta IA';b.disabled=false});
    $('aiAnalyze')?.addEventListener('click',async()=>{const b=$('aiAnalyze');b.innerHTML='<i class="fas fa-spinner fa-spin mr-1"></i>Analizando...';b.disabled=true;const r=await GET(`/api/tickets/${id}/ai-analyze`);if(r&&!r.error){await PUT(`/api/tickets/${id}`,{});pgTicketDetail(id)}else{b.innerHTML='<i class="fas fa-brain mr-1"></i>Analizar';b.disabled=false;alert(r?.error||'IA no disponible')}});
    document.querySelectorAll('.rating-star').forEach(btn=>{
      btn.onmouseenter=()=>{const r=+btn.dataset.r;document.querySelectorAll('.rating-star').forEach(s=>{s.querySelector('i').className=+s.dataset.r<=r?'fas fa-star text-yellow-400':'fas fa-star'})};
      btn.onclick=async()=>{await POST(`/api/tickets/${id}/rate`,{rating:+btn.dataset.r});pgTicketDetail(id)};
    });
  }catch(e){main().innerHTML=`<p class="text-red-500 p-8">Error: ${e.message}</p>`}
}

/* ═══════════════════════════════════════
   NEW TICKET
   ═══════════════════════════════════════ */
async function pgNewTicket(){
  app().innerHTML=layout('Nuevo Ticket',loading,'tickets');
  const u=getUser(),isAg=['admin','agent'].includes(u.role);
  const[cats,ags]=await Promise.all([GET('/api/admin/categories'),GET('/api/admin/agents')]);
  let assets=[];if(isAg)try{const a=await GET('/api/assets');assets=Array.isArray(a)?a:[]}catch{}
  const pCats=cats.filter(c=>!c.parent_id),sCats=cats.filter(c=>c.parent_id);
  main().innerHTML=`<div class="max-w-2xl mx-auto"><div class="card p-6"><h2 class="text-xl font-bold dark:text-white mb-6"><i class="fas fa-plus-circle mr-2 text-[#007A33]"></i>${u.role==='client'?'Nueva Solicitud de Soporte':'Crear Ticket'}</h2>
    <form id="tf" class="space-y-5">
      <div><label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Asunto *</label><input id="ns" required class="input-field" placeholder="Describe brevemente el problema"></div>
      <div><label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Descripción detallada *</label><textarea id="nd" rows="5" required class="input-field" placeholder="Incluye todos los detalles: qué pasó, cuándo, qué equipo, mensajes de error..."></textarea></div>
      <div class="grid grid-cols-2 gap-4">
        <div><label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Prioridad</label><select id="np" class="input-field"><option value="low">🟢 Baja</option><option value="medium" selected>🟡 Media</option><option value="high">🟠 Alta</option><option value="critical">🔴 Crítica</option></select></div>
        <div><label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Categoría</label><select id="nc" class="input-field"><option value="">Seleccionar</option>${pCats.map(c=>`<option value="${c.id}">${c.name}</option>`).join('')}</select></div>
      </div>
      <div class="grid grid-cols-2 gap-4">
        <div><label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Subcategoría</label><select id="nsc" class="input-field"><option value="">Seleccionar categoría primero</option></select></div>
        ${isAg?`<div><label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Asignar a</label><select id="na" class="input-field"><option value="">Auto-asignar</option>${ags.map(a=>`<option value="${a.id}">${a.name}</option>`).join('')}</select></div>`:`<div></div>`}
      </div>
      ${isAg&&assets.length?`<div><label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Activo relacionado</label><select id="nast" class="input-field"><option value="">Ninguno</option>${assets.map(a=>`<option value="${a.id}">[${a.asset_tag}] ${a.name}</option>`).join('')}</select></div>`:''}
      <button type="submit" class="btn-primary w-full justify-center text-base py-3"><i class="fas fa-paper-plane mr-2"></i>${u.role==='client'?'Enviar Solicitud':'Crear Ticket'}</button>
    </form></div></div>`;
  $('nc').addEventListener('change',()=>{const pid=+$('nc').value;$('nsc').innerHTML='<option value="">Seleccionar</option>'+sCats.filter(c=>c.parent_id===pid).map(c=>`<option value="${c.id}">${c.name}</option>`).join('')});
  $('tf').addEventListener('submit',async e=>{e.preventDefault();const btn=e.target.querySelector('button[type=submit]');btn.innerHTML='<i class="fas fa-spinner fa-spin mr-2"></i>Creando...';btn.disabled=true;const r=await POST('/api/tickets',{subject:$('ns').value,description:$('nd').value,priority:$('np').value,category_id:$('nc').value||null,subcategory_id:$('nsc').value||null,assigned_to:$('na')?.value||null,asset_id:$('nast')?.value||null});if(r.id)location.hash=`#tickets/${r.id}`});
}

/* ═══════════════════════════════════════
   ASSETS (CMDB)
   ═══════════════════════════════════════ */
async function pgAssets(param){
  if(param&&!isNaN(param))return pgAssetDetail(param);
  app().innerHTML=layout('Inventario CMDB',loading,'assets');
  try{
    const d=await GET('/api/assets');
    const byStatus={};d.forEach(a=>{byStatus[a.status]=(byStatus[a.status]||0)+1});
    main().innerHTML=`<div class="space-y-4">
      <div class="flex justify-between items-center"><h2 class="text-xl font-bold dark:text-white">${d.length} activos</h2><button id="newAssetBtn" class="btn-primary"><i class="fas fa-plus mr-2"></i>Nuevo Activo</button></div>
      <div class="flex gap-3 flex-wrap">${Object.entries(byStatus).map(([s,c])=>`<span class="text-xs px-3 py-1.5 rounded-full ${s==='active'?'bg-green-100 text-green-700':s==='maintenance'?'bg-yellow-100 text-yellow-700':'bg-gray-100 text-gray-600'} capitalize font-medium">${s}: ${c}</span>`).join('')}</div>
      <div class="card overflow-x-auto"><table class="w-full text-sm"><thead class="bg-gray-50 dark:bg-gray-700/50"><tr><th class="text-left px-5 py-3 text-xs text-gray-500 uppercase">Tag</th><th class="text-left px-5 py-3 text-xs text-gray-500 uppercase">Nombre</th><th class="text-left px-5 py-3 text-xs text-gray-500 uppercase">Tipo</th><th class="text-left px-5 py-3 text-xs text-gray-500 uppercase">Estado</th><th class="text-left px-5 py-3 text-xs text-gray-500 uppercase">Ubicación</th><th class="text-left px-5 py-3 text-xs text-gray-500 uppercase">Asignado</th></tr></thead>
      <tbody class="divide-y divide-gray-100 dark:divide-gray-700">${d.length?d.map(a=>`<tr class="hover:bg-gray-50 dark:hover:bg-gray-700/30 cursor-pointer" onclick="location.hash='#assets/${a.id}'"><td class="px-5 py-3 font-mono text-xs text-[#007A33] font-bold">${a.asset_tag}</td><td class="px-5 py-3 dark:text-gray-200">${a.name}</td><td class="px-5 py-3 capitalize text-gray-500 text-xs">${a.type}</td><td class="px-5 py-3"><span class="text-xs px-2 py-0.5 rounded-full capitalize ${a.status==='active'?'bg-green-100 text-green-700':a.status==='maintenance'?'bg-yellow-100 text-yellow-700':'bg-gray-100 text-gray-600'}">${a.status}</span></td><td class="px-5 py-3 text-gray-500 text-xs">${a.location||'—'}</td><td class="px-5 py-3 text-gray-500 text-xs">${a.assigned_user||'—'}</td></tr>`).join(''):'<tr><td colspan="6" class="px-5 py-10 text-center text-gray-400">No hay activos registrados</td></tr>'}</tbody></table></div>
    </div>`;
    $('newAssetBtn').onclick=()=>location.hash='#assets/new';
  }catch(e){main().innerHTML=`<p class="text-red-500 p-8">Error: ${e.message}</p>`}
}

async function pgAssetDetail(id){
  if(id==='new'){
    app().innerHTML=layout('Nuevo Activo','','assets');
    const ags=await GET('/api/admin/agents');
    main().innerHTML=`<div class="max-w-2xl mx-auto"><div class="card p-6"><h2 class="text-xl font-bold dark:text-white mb-6">Nuevo Activo</h2>
      <form id="af" class="space-y-4">
        <div class="grid grid-cols-2 gap-4"><div><label class="block text-sm font-medium dark:text-gray-300 mb-1">Nombre *</label><input id="an" required class="input-field"></div><div><label class="block text-sm font-medium dark:text-gray-300 mb-1">Tipo</label><select id="at" class="input-field"><option value="desktop">Desktop</option><option value="laptop">Laptop</option><option value="server">Servidor</option><option value="printer">Impresora</option><option value="network">Red</option><option value="phone">Teléfono</option><option value="software">Software</option><option value="other">Otro</option></select></div></div>
        <div class="grid grid-cols-2 gap-4"><div><label class="block text-sm font-medium dark:text-gray-300 mb-1">Marca</label><input id="ab" class="input-field"></div><div><label class="block text-sm font-medium dark:text-gray-300 mb-1">Modelo</label><input id="am" class="input-field"></div></div>
        <div class="grid grid-cols-2 gap-4"><div><label class="block text-sm font-medium dark:text-gray-300 mb-1">Serial</label><input id="as" class="input-field"></div><div><label class="block text-sm font-medium dark:text-gray-300 mb-1">Ubicación</label><input id="al" class="input-field"></div></div>
        <div><label class="block text-sm font-medium dark:text-gray-300 mb-1">Asignado a</label><select id="aa" class="input-field"><option value="">Nadie</option>${ags.map(a=>`<option value="${a.id}">${a.name}</option>`).join('')}</select></div>
        <div><label class="block text-sm font-medium dark:text-gray-300 mb-1">Notas</label><textarea id="ano" rows="2" class="input-field"></textarea></div>
        <button type="submit" class="btn-primary w-full justify-center">Crear Activo</button></form></div></div>`;
    $('af').onsubmit=async e=>{e.preventDefault();const r=await POST('/api/assets',{name:$('an').value,type:$('at').value,brand:$('ab').value,model:$('am').value,serial_number:$('as').value,location:$('al').value,assigned_to:$('aa').value||null,notes:$('ano').value});if(r.id)location.hash='#assets'};
    return;
  }
  app().innerHTML=layout('Activo',loading,'assets');
  try{
    const a=await GET(`/api/assets/${id}`);
    main().innerHTML=`<div class="space-y-6">
      <div class="flex items-center gap-3"><a href="#assets" class="text-gray-400 hover:text-gray-600"><i class="fas fa-arrow-left"></i></a><h2 class="text-xl font-bold dark:text-white">${a.name}</h2><span class="badge bg-gray-200 dark:bg-gray-700 text-gray-700 dark:text-gray-300 font-mono">${a.asset_tag}</span><span class="text-xs px-2 py-0.5 rounded-full capitalize ${a.status==='active'?'bg-green-100 text-green-700':a.status==='maintenance'?'bg-yellow-100 text-yellow-700':'bg-gray-100 text-gray-600'}">${a.status}</span></div>
      <div class="grid lg:grid-cols-3 gap-6">
        <div class="lg:col-span-2 space-y-4">
          <div class="card p-5 grid grid-cols-2 gap-4 text-sm">${[['Tipo',a.type],['Marca',a.brand],['Modelo',a.model],['Serial',a.serial_number],['Ubicación',a.location],['IP',a.ip_address],['Asignado',a.assigned_user],['Compra',fmtDate(a.purchase_date)],['Garantía',fmtDate(a.warranty_until)]].map(([k,v])=>`<div><span class="text-gray-500 block text-xs">${k}</span><span class="dark:text-white font-medium">${v||'—'}</span></div>`).join('')}</div>
          <div class="card"><div class="p-5 border-b border-gray-200 dark:border-gray-700"><h3 class="font-semibold dark:text-white">Mantenimientos (${a.maintenance?.length||0})</h3></div>
          <div class="divide-y divide-gray-100 dark:divide-gray-700">${a.maintenance?.length?a.maintenance.map(m=>`<div class="p-4 text-sm"><div class="flex justify-between mb-1"><span class="font-medium dark:text-white capitalize">${m.type}</span><span class="text-gray-400 text-xs">${fmtDate(m.performed_at)}</span></div><p class="text-gray-600 dark:text-gray-300">${m.description}</p>${m.cost?`<p class="text-xs text-gray-400 mt-1">Costo: $${m.cost}</p>`:''}</div>`).join(''):'<p class="p-5 text-gray-400 text-sm">Sin registros de mantenimiento</p>'}</div></div>
        </div>
        <div class="space-y-4">
          <div class="card p-5"><h3 class="font-semibold dark:text-white mb-3">Tickets Relacionados</h3>${a.tickets?.length?a.tickets.map(t=>`<a href="#tickets/${t.id}" class="block p-2 hover:bg-gray-50 dark:hover:bg-gray-700/30 rounded text-sm"><span class="text-[#007A33] font-medium">#${t.id}</span> ${t.subject}</a>`).join(''):'<p class="text-gray-400 text-sm">Ninguno</p>'}</div>
        </div>
      </div></div>`;
  }catch(e){main().innerHTML=`<p class="text-red-500 p-8">Error: ${e.message}</p>`}
}

/* ═══════════════════════════════════════
   KNOWLEDGE BASE
   ═══════════════════════════════════════ */
async function pgKB(param){
  if(param&&!isNaN(param))return pgKBDetail(param);
  app().innerHTML=layout('Base de Conocimiento',loading,'knowledge');
  try{
    const d=await GET('/api/knowledge');const u=getUser();const isAg=['admin','agent'].includes(u.role);
    main().innerHTML=`<div class="space-y-4">
      <div class="flex justify-between items-center"><h2 class="text-xl font-bold dark:text-white"><i class="fas fa-book mr-2 text-gray-400"></i>${d.length} artículos</h2>${isAg?'<a href="#knowledge/new" class="btn-primary"><i class="fas fa-plus mr-2"></i>Nuevo Artículo</a>':''}</div>
      <div class="grid md:grid-cols-2 lg:grid-cols-3 gap-4">${d.length?d.map(a=>`<div class="card p-5 hover:shadow-md transition-shadow cursor-pointer group" onclick="location.hash='#knowledge/${a.id}'"><div class="flex items-center gap-2 mb-2">${a.is_pinned?'<i class="fas fa-thumbtack text-yellow-500"></i>':''}<span class="text-xs text-gray-400"><i class="fas ${a.category_icon||'fa-folder'} mr-1"></i>${a.category_name||'Sin categoría'}</span></div><h3 class="font-semibold dark:text-white mb-2 group-hover:text-[#007A33] transition-colors">${a.title}</h3><div class="flex justify-between text-xs text-gray-400"><span><i class="fas fa-eye mr-1"></i>${a.views}</span><span>${ago(a.updated_at)}</span></div></div>`).join(''):'<div class="col-span-3 text-center py-10 text-gray-400">No hay artículos publicados</div>'}</div>
    </div>`;
  }catch(e){main().innerHTML=`<p class="text-red-500 p-8">Error: ${e.message}</p>`}
}

async function pgKBDetail(id){
  if(id==='new'){
    app().innerHTML=layout('Nuevo Artículo','','knowledge');
    const cats=await GET('/api/knowledge/categories');
    main().innerHTML=`<div class="max-w-3xl mx-auto"><div class="card p-6"><h2 class="text-xl font-bold dark:text-white mb-6">Nuevo Artículo</h2>
      <form id="kf" class="space-y-4"><div><label class="block text-sm font-medium dark:text-gray-300 mb-1">Título *</label><input id="kt" required class="input-field"></div>
      <div><label class="block text-sm font-medium dark:text-gray-300 mb-1">Contenido *</label><textarea id="kc" rows="10" required class="input-field"></textarea></div>
      <div class="grid grid-cols-2 gap-4"><div><label class="block text-sm font-medium dark:text-gray-300 mb-1">Categoría</label><select id="kcat" class="input-field"><option value="">Ninguna</option>${cats.map(c=>`<option value="${c.id}">${c.name}</option>`).join('')}</select></div><div><label class="block text-sm font-medium dark:text-gray-300 mb-1">Estado</label><select id="ks" class="input-field"><option value="draft">Borrador</option><option value="published">Publicado</option></select></div></div>
      <button type="submit" class="btn-primary w-full justify-center">Guardar Artículo</button></form></div></div>`;
    $('kf').onsubmit=async e=>{e.preventDefault();const r=await POST('/api/knowledge',{title:$('kt').value,content:$('kc').value,category_id:$('kcat').value||null,status:$('ks').value});if(r.id)location.hash='#knowledge'};
    return;
  }
  app().innerHTML=layout('Artículo',loading,'knowledge');
  try{
    const a=await GET(`/api/knowledge/${id}`);
    main().innerHTML=`<div class="max-w-3xl mx-auto space-y-4">
      <a href="#knowledge" class="text-gray-400 hover:text-gray-600 text-sm"><i class="fas fa-arrow-left mr-1"></i>Volver a artículos</a>
      <div class="card p-6"><div class="mb-4 flex flex-wrap gap-3"><span class="text-xs bg-gray-100 dark:bg-gray-700 text-gray-600 dark:text-gray-300 px-2 py-1 rounded"><i class="fas fa-folder mr-1"></i>${a.category_name||'Sin categoría'}</span><span class="text-xs text-gray-400"><i class="fas fa-eye mr-1"></i>${a.views} vistas</span><span class="text-xs text-gray-400"><i class="fas fa-clock mr-1"></i>${fmtDate(a.updated_at)}</span></div>
      <h1 class="text-2xl font-bold dark:text-white mb-4">${a.title}</h1>
      <div class="prose dark:prose-invert max-w-none text-gray-700 dark:text-gray-300 leading-relaxed">${a.content}</div></div>
    </div>`;
  }catch(e){main().innerHTML=`<p class="text-red-500 p-8">Error: ${e.message}</p>`}
}

/* ═══════════════════════════════════════
   USERS (Admin only)
   ═══════════════════════════════════════ */
async function pgUsers(){
  app().innerHTML=layout('Usuarios',loading,'users');
  try{
    const d=await GET('/api/admin/users');
    const byRole={};d.forEach(u=>{byRole[u.role]=(byRole[u.role]||0)+1});
    main().innerHTML=`<div class="space-y-4">
      <div class="flex justify-between items-center"><h2 class="text-xl font-bold dark:text-white">${d.length} usuarios</h2><button id="nuBtn" class="btn-primary"><i class="fas fa-plus mr-2"></i>Nuevo</button></div>
      <div class="flex gap-3">${Object.entries(byRole).map(([r,c])=>`<span class="text-xs px-3 py-1.5 rounded-full ${r==='admin'?'bg-green-100 text-green-700':r==='agent'?'bg-blue-100 text-blue-700':'bg-gray-100 text-gray-600'} capitalize font-medium">${r}: ${c}</span>`).join('')}</div>
      <div class="card overflow-x-auto"><table class="w-full text-sm"><thead class="bg-gray-50 dark:bg-gray-700/50"><tr><th class="text-left px-5 py-3 text-xs text-gray-500 uppercase">Nombre</th><th class="text-left px-5 py-3 text-xs text-gray-500 uppercase">Email</th><th class="text-left px-5 py-3 text-xs text-gray-500 uppercase">Rol</th><th class="text-left px-5 py-3 text-xs text-gray-500 uppercase">Estado</th><th class="text-left px-5 py-3 text-xs text-gray-500 uppercase">Último acceso</th></tr></thead>
      <tbody class="divide-y divide-gray-100 dark:divide-gray-700">${d.map(u=>`<tr class="hover:bg-gray-50 dark:hover:bg-gray-700/30"><td class="px-5 py-3 font-medium dark:text-white">${u.name}</td><td class="px-5 py-3 text-gray-500">${u.email}</td><td class="px-5 py-3"><span class="text-xs px-2 py-0.5 rounded-full font-medium capitalize ${u.role==='admin'?'bg-green-100 text-green-700':u.role==='agent'?'bg-blue-100 text-blue-700':'bg-gray-100 text-gray-600'}">${u.role}</span></td><td class="px-5 py-3"><span class="text-xs px-2 py-0.5 rounded-full ${u.active?'bg-green-100 text-green-700':'bg-red-100 text-red-700'}">${u.active?'Activo':'Inactivo'}</span></td><td class="px-5 py-3 text-gray-500 text-xs">${u.last_login?ago(u.last_login):'Nunca'}</td></tr>`).join('')}</tbody></table></div>
    </div>`;
    $('nuBtn').onclick=()=>{
      const n=prompt('Nombre:'),e=prompt('Email:'),p=prompt('Contraseña:'),r=prompt('Rol (admin/agent/client):','client');
      if(n&&e&&p)POST('/api/admin/users',{name:n,email:e,password:p,role:r||'client'}).then(()=>pgUsers());
    };
  }catch(e){main().innerHTML=`<p class="text-red-500 p-8">Error: ${e.message}</p>`}
}

/* ═══════════════════════════════════════
   SETTINGS (Admin only)
   ═══════════════════════════════════════ */
async function pgSettings(){
  app().innerHTML=layout('Configuración',loading,'settings');
  try{
    const[s,sts,sla]=await Promise.all([GET('/api/admin/settings'),GET('/api/admin/statuses'),GET('/api/admin/sla')]);
    main().innerHTML=`<div class="space-y-6">
      <div class="card p-5"><h3 class="font-semibold dark:text-white mb-4"><i class="fas fa-cog mr-2 text-gray-400"></i>General</h3><form id="sf" class="space-y-3">
        <div class="grid grid-cols-2 gap-4"><div><label class="text-sm text-gray-500">Nombre App</label><input id="sn" class="input-field" value="${s.app_name||'HelpDesk ITSM'}"></div><div><label class="text-sm text-gray-500">Empresa</label><input id="sc" class="input-field" value="${s.company_name||''}"></div></div>
        <div><label class="text-sm text-gray-500">API Key Gemini (IA)</label><input id="sk" type="password" class="input-field" value="${s.gemini_api_key||''}" placeholder="Dejar vacío para desactivar IA"></div>
        <button type="submit" class="btn-primary">Guardar</button></form></div>
      <div class="card p-5"><h3 class="font-semibold dark:text-white mb-4"><i class="fas fa-tasks mr-2 text-gray-400"></i>Estados de Ticket</h3><div class="flex flex-wrap gap-2">${sts.map(s=>`<span class="badge text-white" style="background:${s.color}"><i class="fas ${s.icon} mr-1"></i>${s.name}${s.is_closed?' (cierre)':''}</span>`).join('')}</div></div>
      <div class="card p-5"><h3 class="font-semibold dark:text-white mb-4"><i class="fas fa-stopwatch mr-2 text-gray-400"></i>Políticas SLA</h3><table class="w-full text-sm"><thead><tr><th class="text-left py-2 text-xs text-gray-500 uppercase">Nombre</th><th class="text-left py-2 text-xs text-gray-500 uppercase">Prioridad</th><th class="text-left py-2 text-xs text-gray-500 uppercase">Respuesta</th><th class="text-left py-2 text-xs text-gray-500 uppercase">Resolución</th></tr></thead><tbody>${sla.map(p=>`<tr class="border-t border-gray-100 dark:border-gray-700"><td class="py-2 dark:text-white">${p.name}</td><td class="py-2 capitalize text-gray-500">${p.priority}</td><td class="py-2 text-gray-500">${p.response_hours}h</td><td class="py-2 text-gray-500">${p.resolution_hours}h</td></tr>`).join('')}</tbody></table></div>
    </div>`;
    $('sf').onsubmit=async e=>{e.preventDefault();await PUT('/api/admin/settings',{app_name:$('sn').value,company_name:$('sc').value,gemini_api_key:$('sk').value});alert('✅ Configuración guardada')};
  }catch(e){main().innerHTML=`<p class="text-red-500 p-8">Error: ${e.message}</p>`}
}

function pg404(){app().innerHTML=layout('404','<div class="text-center py-20"><i class="fas fa-exclamation-triangle text-4xl text-gray-300 mb-4 block"></i><h2 class="text-2xl font-bold text-gray-400">Página no encontrada</h2><a href="#dashboard" class="text-[#007A33] hover:underline mt-4 inline-block">Ir al Dashboard →</a></div>')}
