<!-- ===== TIKTOK ADS ===== -->
<?php if(_nav('tiktok')): ?>
<div class="page" id="page-tiktok">

  <!-- CABECERA -->
  <div class="ph">
    <div>
      <div class="pt">TikTok Ads</div>
      <div class="ps">Business API v1.3 · Campañas · Ad Groups · AVI</div>
    </div>
    <div style="display:flex;gap:6px;align-items:center;flex-wrap:wrap">
      <select id="tt-period-sel" data-change="onTTperiodChange" style="background:var(--bg3);border:1px solid var(--br2);border-radius:6px;padding:5px 10px;font-size:12px;color:var(--t);font-family:var(--fb)">
        <option value="7d">Últimos 7 días</option>
        <option value="30d" selected>Últimos 30 días</option>
        <option value="60d">Últimos 60 días</option>
        <option value="90d">Últimos 90 días</option>
        <option value="custom">Personalizado</option>
      </select>
      <div id="tt-date-custom" style="display:none;gap:6px;align-items:center">
        <input type="date" id="tt-date-from" style="background:var(--bg3);border:1px solid var(--br2);border-radius:6px;padding:5px 8px;font-size:12px;color:var(--t);font-family:var(--fb)">
        <span style="color:var(--m);font-size:12px">—</span>
        <input type="date" id="tt-date-to" style="background:var(--bg3);border:1px solid var(--br2);border-radius:6px;padding:5px 8px;font-size:12px;color:var(--t);font-family:var(--fb)">
        <button data-click="loadTikTokData|__client|custom" style="padding:5px 10px;border-radius:6px;font-size:12px;background:var(--red);border:none;color:#fff;cursor:pointer;font-family:var(--fb)">Aplicar</button>
      </div>
      <button data-click="_scLoadTTWithSel" style="padding:5px 10px;border-radius:6px;font-size:12px;background:var(--bg3);border:1px solid var(--br2);color:var(--t);cursor:pointer;font-family:var(--fb)">↻</button>
    </div>
  </div>

  <!-- CONTEXTO -->
  <div class="ctx-block">
    <div class="ctx-hd"><div class="ctx-icon">🧠</div><div><div class="ctx-title">Contexto del negocio</div><div class="ctx-sub">Objetivo en TikTok, público, tono y estrategia del cliente</div></div></div>
    <textarea class="ctx-ta" id="tiktok-ctx" placeholder="Ej: Ropa femenina, mujeres 18-35, objetivo: ventas, tono juvenil y dinámico, producto estrella: vestidos de temporada..."></textarea>
    <div style="display:flex;align-items:center">
      <button class="ctx-save" data-click="saveCtx|tiktok">Guardar contexto</button>
      <button class="ctx-save" data-click="clearCtx|tiktok" style="background:var(--bg3);border:1px solid var(--br2);color:var(--m);margin-left:6px">Limpiar</button>
      <span class="ctx-saved" id="ctx-saved-tiktok">✓ Guardado</span>
    </div>
  </div>

  <!-- ESTADO: ERROR API -->
  <div id="tt-api-error" style="display:none;margin-bottom:14px;background:rgba(232,39,42,.08);border:1px solid rgba(232,39,42,.25);border-radius:8px;padding:12px 16px">
    <div style="display:flex;align-items:center;gap:10px">
      <div style="font-size:20px">⚠</div>
      <div style="flex:1">
        <div style="font-size:13px;font-weight:600;color:var(--red)">Error al conectar con TikTok Ads</div>
        <div id="tt-api-error-msg" style="font-size:12px;color:var(--m);margin-top:2px"></div>
      </div>
      <button data-click="connectTikTok" style="padding:6px 14px;border-radius:6px;font-size:12px;background:rgba(255,45,85,.15);border:1px solid rgba(255,45,85,.3);color:#ff2d55;cursor:pointer;font-family:var(--fb);white-space:nowrap">🔗 Reconectar</button>
    </div>
  </div>

  <!-- ESTADO: NO CONECTADO -->
  <div id="tt-not-connected" style="display:none;margin:24px 0">
    <div style="background:var(--bg3);border:1px solid var(--br);border-radius:10px;padding:24px;text-align:center">
      <div style="font-size:32px;margin-bottom:10px">🎵</div>
      <div style="font-size:15px;font-weight:600;margin-bottom:6px">TikTok Ads no conectado</div>
      <div style="font-size:13px;color:var(--m);margin-bottom:18px">Conecta la cuenta TikTok de este cliente para ver campañas y métricas</div>
      <button data-click="connectTikTok" style="padding:9px 20px;background:#ff2d55;border:none;border-radius:8px;color:#fff;font-size:13px;font-weight:600;cursor:pointer;font-family:var(--fb)">🔗 Conectar TikTok Ads</button>
      <div style="margin-top:14px;font-size:12px;color:var(--m)">Necesitas <code>TIKTOK_APP_ID</code> y <code>TIKTOK_APP_SECRET</code> en config.php</div>
    </div>
  </div>

  <!-- TABS -->
  <div id="tt-tabs-wrap" style="display:none">
    <div style="display:flex;gap:0;border-bottom:1px solid var(--br);margin-bottom:4px;overflow-x:auto;-webkit-overflow-scrolling:touch">
      <button class="tt-tab active" data-click="switchTTTab|resumen|__el" style="padding:9px 16px;font-size:12px;color:var(--t);background:none;border:none;border-bottom:2px solid #ff2d55;cursor:pointer;font-family:var(--fb)">Resumen</button>
      <button class="tt-tab" data-click="switchTTTab|campanas|__el" style="padding:9px 16px;font-size:12px;color:var(--m);background:none;border:none;border-bottom:2px solid transparent;cursor:pointer;font-family:var(--fb)">Campañas</button>
      <button class="tt-tab" data-click="switchTTTab|adgroups|__el" style="padding:9px 16px;font-size:12px;color:var(--m);background:none;border:none;border-bottom:2px solid transparent;cursor:pointer;font-family:var(--fb)">Ad Groups</button>
      <button class="tt-tab" data-click="switchTTTab|avi|__el" style="padding:9px 16px;font-size:12px;color:var(--m);background:none;border:none;border-bottom:2px solid transparent;cursor:pointer;font-family:var(--fb)">✦ AVI TikTok</button>
      <button class="tt-tab" data-click="switchTTTab|tendencias|__el" style="padding:9px 16px;font-size:12px;color:var(--m);background:none;border:none;border-bottom:2px solid transparent;cursor:pointer;font-family:var(--fb)">📈 Tendencias</button>
      <button class="tt-tab" data-click="switchTTTab|creativos|__el" style="padding:9px 16px;font-size:12px;color:var(--m);background:none;border:none;border-bottom:2px solid transparent;cursor:pointer;font-family:var(--fb)">🎬 Creativos</button>
    </div>

    <!-- TAB: RESUMEN -->
    <div class="tt-panel active" id="ttpanel-resumen">
      <div class="metrics" id="tt-metrics" style="grid-template-columns:repeat(4,minmax(0,1fr))">
        <div class="metric"><div class="ml"><div class="md" style="background:var(--b)"></div>Inversión</div><div class="mv" id="tt-spend">—</div><div class="mdelta" id="tt-spend-d" style="color:var(--m)"></div></div>
        <div class="metric"><div class="ml"><div class="md" style="background:var(--g)"></div>Impresiones</div><div class="mv" id="tt-impr">—</div><div class="mdelta" id="tt-impr-d" style="color:var(--m)"></div></div>
        <div class="metric"><div class="ml"><div class="md" style="background:var(--y)"></div>Clics</div><div class="mv" id="tt-clicks">—</div><div class="mdelta" id="tt-clicks-d" style="color:var(--m)"></div></div>
        <div class="metric"><div class="ml"><div class="md" style="background:var(--red)"></div>CTR</div><div class="mv" id="tt-ctr">—</div><div class="mdelta" id="tt-ctr-d" style="color:var(--m)"></div></div>
        <div class="metric"><div class="ml"><div class="md" style="background:var(--p)"></div>Alcance</div><div class="mv" id="tt-reach">—</div><div class="mdelta" id="tt-reach-d" style="color:var(--m)"></div></div>
        <div class="metric"><div class="ml"><div class="md" style="background:#22c97a"></div>Conversiones</div><div class="mv" id="tt-conv">—</div><div class="mdelta" id="tt-conv-d" style="color:var(--m)"></div></div>
        <div class="metric"><div class="ml"><div class="md" style="background:#f97316"></div>CPA</div><div class="mv" id="tt-cpa">—</div><div class="mdelta" id="tt-cpa-d" style="color:var(--m)"></div></div>
        <div class="metric"><div class="ml"><div class="md" style="background:var(--m)"></div>CPM</div><div class="mv" id="tt-cpm">—</div><div class="mdelta" id="tt-cpm-d" style="color:var(--m)"></div></div>
      </div>
      <div id="tt-ov-loading" style="text-align:center;padding:20px;color:var(--m);font-size:13px">Cargando métricas TikTok...</div>
    </div>

    <!-- TAB: CAMPAÑAS -->
    <div class="tt-panel" id="ttpanel-campanas" style="display:none">
      <div id="tt-camp-loading" style="text-align:center;padding:20px;color:var(--m);font-size:13px">Cargando campañas...</div>
      <div id="tt-camp-wrap" style="display:none">
        <div style="overflow-x:auto">
          <table class="tbl" id="tt-camp-table" style="width:100%">
            <thead><tr>
              <th>Campaña</th><th>Estado</th><th>Objetivo</th><th>Presupuesto</th>
              <th>Inversión</th><th>Impresiones</th><th>Clics</th><th>CTR</th><th>CPM</th><th>Conv.</th><th>CPA</th><th>Acciones</th>
            </tr></thead>
            <tbody id="tt-camp-body"></tbody>
          </table>
        </div>
      </div>
      <div id="tt-camp-empty" style="display:none;text-align:center;padding:30px;color:var(--m);font-size:13px">No hay campañas en el período seleccionado.</div>
    </div>

    <!-- TAB: AD GROUPS -->
    <div class="tt-panel" id="ttpanel-adgroups" style="display:none">
      <div style="display:flex;gap:8px;align-items:center;margin-bottom:12px">
        <select id="tt-ag-camp-filter" data-change="loadTTAdgroups" style="background:var(--bg3);border:1px solid var(--br2);border-radius:6px;padding:5px 10px;font-size:12px;color:var(--t);font-family:var(--fb)">
          <option value="">Todos los ad groups</option>
        </select>
      </div>
      <div id="tt-ag-loading" style="text-align:center;padding:20px;color:var(--m);font-size:13px">Cargando ad groups...</div>
      <div id="tt-ag-wrap" style="display:none">
        <div style="overflow-x:auto">
          <table class="tbl" id="tt-ag-table" style="width:100%">
            <thead><tr>
              <th>Ad Group</th><th>Estado</th><th>Objetivo</th><th>Presupuesto</th>
              <th>Inversión</th><th>Impresiones</th><th>Clics</th><th>CTR</th><th>Conv.</th><th>CPA</th>
            </tr></thead>
            <tbody id="tt-ag-body"></tbody>
          </table>
        </div>
      </div>
      <div id="tt-ag-empty" style="display:none;text-align:center;padding:30px;color:var(--m);font-size:13px">No hay ad groups en el período seleccionado.</div>
    </div>

    <!-- TAB: AVI TIKTOK -->
    <div class="tt-panel" id="ttpanel-avi" style="display:none">
      <div class="avi">
        <div class="avi-hd">
          <div class="avi-orb">✦</div>
          <div><div class="avi-name">AVI · TikTok Ads</div><div class="avi-sub">Estrategia de contenido, copies, segmentación y análisis de campañas</div></div>
        </div>
        <div style="display:flex;flex-wrap:wrap;gap:6px;margin-bottom:10px">
          <button data-click="ttAVIquick|Analiza mis campañas TikTok y dame recomendaciones concretas para mejorar el CTR y reducir el CPM" style="padding:5px 10px;border-radius:7px;font-size:11px;background:var(--bg3);border:1px solid var(--br2);color:var(--t);cursor:pointer;font-family:var(--fb)">📊 Analizar campañas</button>
          <button data-click="ttAVIquick|Crea 3 hooks virales para TikTok con los primeros 3 segundos que detengan el scroll. Adapta cada hook al negocio del cliente" style="padding:5px 10px;border-radius:7px;font-size:11px;background:var(--bg3);border:1px solid var(--br2);color:var(--t);cursor:pointer;font-family:var(--fb)">🎣 Hooks virales</button>
          <button data-click="ttAVIquick|Diseña una estrategia completa de TikTok Ads para este cliente: objetivos, segmentación, formatos de anuncio recomendados, presupuesto y KPIs a medir" style="padding:5px 10px;border-radius:7px;font-size:11px;background:var(--bg3);border:1px solid var(--br2);color:var(--t);cursor:pointer;font-family:var(--fb)">🗺️ Estrategia completa</button>
          <button data-click="ttAVIquick|Escribe 5 copies para anuncios TikTok In-Feed de este cliente. Incluye texto del anuncio, call-to-action y descripción del creativo visual" style="padding:5px 10px;border-radius:7px;font-size:11px;background:var(--bg3);border:1px solid var(--br2);color:var(--t);cursor:pointer;font-family:var(--fb)">✍️ Copies para ads</button>
          <button data-click="ttAVIquick|¿Cómo mejorar mi segmentación en TikTok Ads para este cliente? Dame audiencias específicas, intereses y comportamientos a targetear" style="padding:5px 10px;border-radius:7px;font-size:11px;background:var(--bg3);border:1px solid var(--br2);color:var(--t);cursor:pointer;font-family:var(--fb)">🎯 Segmentación</button>
          <button data-click="ttAVIPauseIneficientes" style="padding:5px 10px;border-radius:7px;font-size:11px;background:rgba(255,45,85,.1);border:1px solid rgba(255,45,85,.3);color:#ff2d55;cursor:pointer;font-family:var(--fb)">✦ Pausar campañas ineficientes</button>
        </div>
        <div class="avi-row">
          <input class="avi-in" id="tt-avi-q" placeholder="Pregunta sobre TikTok Ads, estrategia o contenido..." onkeydown="if(event.key==='Enter')askTTAVI()">
          <button class="avi-send" data-click="askTTAVI">Preguntar</button>
        </div>
        <div class="avi-resp" id="tt-avi-resp"></div>
      </div>
    </div>

    <!-- TAB: TENDENCIAS -->
    <div class="tt-panel" id="ttpanel-tendencias" style="display:none">

      <!-- Card 1: Budget Pacing -->
      <div class="card" id="tt-pacing-card" style="margin-bottom:14px">
        <div class="chd" style="display:flex;align-items:center;justify-content:space-between">
          <span style="font-size:13px;font-weight:600">Budget Pacing</span>
          <span style="font-size:11px;color:var(--m)" id="tt-pacing-days"></span>
        </div>
        <div id="tt-pacing-body" style="padding:12px 0 4px">
          <div style="color:var(--m);font-size:12px;text-align:center;padding:20px">Carga campañas para ver el pacing...</div>
        </div>
      </div>

      <!-- Card 2: Tendencias del nicho con AVI -->
      <div class="card" id="tt-trends-card" style="margin-bottom:14px">
        <div class="chd" style="display:flex;align-items:center;justify-content:space-between">
          <span style="font-size:13px;font-weight:600">Tendencias para el nicho</span>
          <button data-click="loadTTTrends" style="padding:5px 10px;border-radius:7px;font-size:11px;background:rgba(155,127,244,.1);border:1px solid rgba(155,127,244,.2);color:var(--p);cursor:pointer;font-family:var(--fb)">✦ Analizar tendencias con AVI</button>
        </div>
        <div class="avi-resp" id="tt-trends-resp" style="margin-top:8px"></div>
      </div>

      <!-- Card 3: Comparativa vs período anterior -->
      <div class="card" id="tt-compare-card">
        <div class="chd">
          <span style="font-size:13px;font-weight:600">Comparativa vs período anterior</span>
        </div>
        <div id="tt-compare-body" style="padding:8px 0">
          <div style="color:var(--m);font-size:12px;text-align:center;padding:20px">Haz clic en "Analizar tendencias" para cargar la comparativa...</div>
        </div>
      </div>

    </div><!-- /ttpanel-tendencias -->

    <!-- ═══ TAB: CREATIVOS ═══ -->
    <div class="tt-panel" id="ttpanel-creativos" style="display:none">

      <!-- Hook Generator -->
      <div class="card" style="margin-bottom:14px">
        <div class="chd"><div class="ctit">🎣 Generador de Hooks</div><div class="cs">Primeros 3 segundos que detienen el scroll</div></div>
        <div style="display:flex;flex-wrap:wrap;gap:6px;margin-bottom:12px">
          <button data-click="ttGenerateHook|curiosidad" style="padding:5px 12px;border-radius:7px;font-size:11px;background:var(--bg3);border:1px solid var(--br2);color:var(--t);cursor:pointer;font-family:var(--fb)">🤔 Curiosidad</button>
          <button data-click="ttGenerateHook|shock"      style="padding:5px 12px;border-radius:7px;font-size:11px;background:var(--bg3);border:1px solid var(--br2);color:var(--t);cursor:pointer;font-family:var(--fb)">😲 Shock / Dato</button>
          <button data-click="ttGenerateHook|pregunta"   style="padding:5px 12px;border-radius:7px;font-size:11px;background:var(--bg3);border:1px solid var(--br2);color:var(--t);cursor:pointer;font-family:var(--fb)">❓ Pregunta directa</button>
          <button data-click="ttGenerateHook|problema"   style="padding:5px 12px;border-radius:7px;font-size:11px;background:var(--bg3);border:1px solid var(--br2);color:var(--t);cursor:pointer;font-family:var(--fb)">😤 Problema real</button>
          <button data-click="ttGenerateHook|trending"   style="padding:5px 12px;border-radius:7px;font-size:11px;background:var(--bg3);border:1px solid var(--br2);color:var(--t);cursor:pointer;font-family:var(--fb)">🔥 Formato trending</button>
          <button data-click="ttGenerateHook|todos"      style="padding:5px 12px;border-radius:7px;font-size:11px;background:#ff2d55;border:none;color:#fff;cursor:pointer;font-family:var(--fb);font-weight:600">✦ Todos los tipos</button>
        </div>
        <div class="avi-resp" id="tt-hooks-resp"></div>
      </div>

      <!-- Ad Copy Generator -->
      <div class="card" style="margin-bottom:14px">
        <div class="chd"><div class="ctit">📝 Copies de Anuncio</div><div class="cs">Texto del anuncio, caption y CTA para TikTok</div></div>
        <div style="display:flex;flex-wrap:wrap;gap:6px;margin-bottom:12px">
          <button data-click="ttGenerateCopy|caption"   style="padding:5px 12px;border-radius:7px;font-size:11px;background:var(--bg3);border:1px solid var(--br2);color:var(--t);cursor:pointer;font-family:var(--fb)">📌 Caption post</button>
          <button data-click="ttGenerateCopy|aida"      style="padding:5px 12px;border-radius:7px;font-size:11px;background:var(--bg3);border:1px solid var(--br2);color:var(--t);cursor:pointer;font-family:var(--fb)">🎯 Framework AIDA</button>
          <button data-click="ttGenerateCopy|pas"       style="padding:5px 12px;border-radius:7px;font-size:11px;background:var(--bg3);border:1px solid var(--br2);color:var(--t);cursor:pointer;font-family:var(--fb)">⚡ Framework PAS</button>
          <button data-click="ttGenerateCopy|cta"       style="padding:5px 12px;border-radius:7px;font-size:11px;background:var(--bg3);border:1px solid var(--br2);color:var(--t);cursor:pointer;font-family:var(--fb)">🛒 CTAs variados</button>
          <button data-click="ttGenerateCopy|hashtags"  style="padding:5px 12px;border-radius:7px;font-size:11px;background:var(--bg3);border:1px solid var(--br2);color:var(--t);cursor:pointer;font-family:var(--fb)"># Hashtag strategy</button>
        </div>
        <div class="avi-resp" id="tt-copy-resp"></div>
      </div>

      <!-- Script Generator -->
      <div class="card" style="margin-bottom:14px">
        <div class="chd"><div class="ctit">🎬 Script Completo</div><div class="cs">Guión con segundos marcados para grabación</div></div>
        <div style="display:flex;align-items:center;gap:10px;margin-bottom:12px;flex-wrap:wrap">
          <div style="display:flex;gap:6px">
            <button id="tt-script-15"  data-click="ttSelectDuration|15"  style="padding:5px 14px;border-radius:7px;font-size:11px;background:#ff2d55;border:none;color:#fff;cursor:pointer;font-family:var(--fb);font-weight:600">15s</button>
            <button id="tt-script-30"  data-click="ttSelectDuration|30"  style="padding:5px 14px;border-radius:7px;font-size:11px;background:var(--bg3);border:1px solid var(--br2);color:var(--t);cursor:pointer;font-family:var(--fb)">30s</button>
            <button id="tt-script-60"  data-click="ttSelectDuration|60"  style="padding:5px 14px;border-radius:7px;font-size:11px;background:var(--bg3);border:1px solid var(--br2);color:var(--t);cursor:pointer;font-family:var(--fb)">60s</button>
          </div>
          <select id="tt-script-format" style="padding:5px 10px;border-radius:7px;font-size:11px;background:var(--bg3);border:1px solid var(--br2);color:var(--t);font-family:var(--fb)">
            <option value="educativo">Educativo / Tutorial</option>
            <option value="testimonial">Testimonial / Caso de éxito</option>
            <option value="problema_solucion">Problema → Solución</option>
            <option value="trending">Formato trending (POV / stitch)</option>
            <option value="oferta">Oferta directa (directo a conversión)</option>
          </select>
          <button data-click="ttGenerateScript" style="padding:5px 14px;border-radius:7px;font-size:11px;background:rgba(255,45,85,.12);border:1px solid rgba(255,45,85,.3);color:#ff2d55;cursor:pointer;font-family:var(--fb);font-weight:600">✦ Generar script</button>
        </div>
        <div class="avi-resp" id="tt-script-resp"></div>
        <div id="tt-script-copy-wrap" style="display:none;margin-top:8px">
          <button data-click="ttCopyScript" style="padding:4px 12px;border-radius:6px;font-size:11px;background:var(--bg3);border:1px solid var(--br2);color:var(--m);cursor:pointer;font-family:var(--fb)">Copiar script</button>
        </div>
      </div>

      <!-- Creative Fatigue -->
      <div class="card">
        <div class="chd">
          <div class="ctit">🔄 Fatiga Creativa</div>
          <button data-click="ttAnalyzeCreativeFatigue" style="padding:5px 10px;border-radius:7px;font-size:11px;background:rgba(155,127,244,.1);border:1px solid rgba(155,127,244,.2);color:var(--p);cursor:pointer;font-family:var(--fb)">✦ Analizar con AVI</button>
        </div>
        <div id="tt-fatigue-summary" style="display:flex;gap:10px;flex-wrap:wrap;margin:10px 0 4px">
          <div style="font-size:12px;color:var(--m);padding:12px;text-align:center;width:100%">Analiza tus campañas para detectar señales de fatiga creativa (CPM subiendo, CTR bajando).</div>
        </div>
        <div class="avi-resp" id="tt-fatigue-resp" style="margin-top:8px"></div>
      </div>

    </div><!-- /ttpanel-creativos -->

  </div><!-- /tt-tabs-wrap -->
</div><!-- /page-tiktok -->

<script>
// ── TikTok Ads — Variables ─────────────────────────────────────────────────
let ttCurrentPeriod = '30d';
let ttCampaigns     = [];

// ── Cambio de período ──────────────────────────────────────────────────────
function onTTperiodChange() {
  const sel = document.getElementById('tt-period-sel').value;
  const custom = document.getElementById('tt-date-custom');
  if (sel === 'custom') { custom.style.display = 'flex'; return; }
  custom.style.display = 'none';
  loadTikTokData(currentClient, sel);
}

// ── Tab switching ──────────────────────────────────────────────────────────
function switchTTTab(tab, btn) {
  document.querySelectorAll('.tt-tab').forEach(t => {
    t.style.borderBottomColor = 'transparent';
    t.style.color = 'var(--m)';
  });
  btn.style.borderBottomColor = '#ff2d55';
  btn.style.color = 'var(--t)';

  document.querySelectorAll('.tt-panel').forEach(p => p.style.display = 'none');
  document.getElementById('ttpanel-' + tab).style.display = 'block';

  if (tab === 'campanas' && ttCampaigns.length === 0) loadTTCampaigns();
  if (tab === 'adgroups') loadTTAdgroups();
  if (tab === 'creativos') {
    // Pre-select 15s on first visit
    ttSelectDuration(_ttScriptDuration);
  }
  if (tab === 'tendencias') {
    renderTTPacing(ttCampaigns);
    const sel = document.getElementById('tt-period-sel')?.value || ttCurrentPeriod;
    const from = document.getElementById('tt-date-from')?.value || '';
    const to   = document.getElementById('tt-date-to')?.value || '';
    loadTTCompare(sel, from, to);
  }
}

// ── Cargar datos principales ───────────────────────────────────────────────
async function loadTikTokData(clientId, period) {
  if (!clientId || clientId === 'all') return;
  ttCurrentPeriod = period || ttCurrentPeriod;

  // Mostrar loading, ocultar estados anteriores
  document.getElementById('tt-not-connected').style.display = 'none';
  document.getElementById('tt-api-error').style.display     = 'none';
  document.getElementById('tt-tabs-wrap').style.display     = 'none';
  document.getElementById('tt-ov-loading').style.display    = 'block';
  ['tt-spend','tt-impr','tt-clicks','tt-ctr','tt-reach','tt-conv','tt-cpa','tt-cpm']
    .forEach(id => { const el = document.getElementById(id); if(el) el.textContent = '…'; });

  const params = buildTTParams(clientId);
  try {
    const d = await fetch(`api/tiktok-data.php?action=overview&${params}`).then(r => r.json());
    if (!d.ok) {
      if (d.error === 'tiktok_not_connected') {
        document.getElementById('tt-not-connected').style.display = 'block';
      } else {
        showTTError(d.message || d.error);
      }
      document.getElementById('tt-ov-loading').style.display = 'none';
      return;
    }
    document.getElementById('tt-tabs-wrap').style.display  = 'block';
    document.getElementById('tt-ov-loading').style.display = 'none';
    const v = d.data;
    const setMetric = (id, fmt, raw) => {
      const el = document.getElementById(id);
      if (el) { el.textContent = fmt || '—'; el.dataset.raw = raw || 0; }
    };
    setMetric('tt-spend',  v.spend_fmt,  v.spend);
    setMetric('tt-impr',   v.impr_fmt,   v.impressions);
    setMetric('tt-clicks', v.clicks_fmt, v.clicks);
    setMetric('tt-ctr',    v.ctr_fmt,    v.ctr);
    setMetric('tt-reach',  v.reach_fmt,  v.reach);
    setMetric('tt-conv',   v.conv_fmt,   v.conversions);
    setMetric('tt-cpa',    v.cpa_fmt,    v.cpa);
    setMetric('tt-cpm',    v.cpm_fmt,    v.cpm);
    // Limpiar deltas al recargar datos
    ['tt-spend-d','tt-impr-d','tt-clicks-d','tt-ctr-d','tt-reach-d','tt-conv-d','tt-cpa-d','tt-cpm-d']
      .forEach(id => { const el = document.getElementById(id); if(el) el.textContent=''; });
    // Resetear lista de campañas para forzar recarga con el nuevo período
    ttCampaigns = [];
  } catch(e) {
    showTTError('Error de red al cargar TikTok');
    document.getElementById('tt-ov-loading').style.display = 'none';
  }
}

// ── Cargar campañas ────────────────────────────────────────────────────────
async function loadTTCampaigns() {
  if (!currentClient || currentClient === 'all') return;
  document.getElementById('tt-camp-loading').style.display = 'block';
  document.getElementById('tt-camp-wrap').style.display    = 'none';
  document.getElementById('tt-camp-empty').style.display   = 'none';

  try {
    const d = await fetch(`api/tiktok-data.php?action=campaigns&${buildTTParams(currentClient)}`).then(r => r.json());
    document.getElementById('tt-camp-loading').style.display = 'none';
    if (!d.ok || !d.data?.length) {
      document.getElementById('tt-camp-empty').style.display = 'block'; return;
    }
    ttCampaigns = d.data;
    renderTTCampaigns(d.data);
    populateTTCampFilter(d.data);
  } catch(e) {
    document.getElementById('tt-camp-loading').style.display = 'none';
    document.getElementById('tt-camp-empty').style.display   = 'block';
  }
}

function renderTTCampaigns(list) {
  const tbody = document.getElementById('tt-camp-body');
  tbody.innerHTML = list.map(c => `
    <tr id="tt-camp-row-${esc(c.id)}">
      <td style="max-width:180px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap" title="${esc(c.name)}">${esc(c.name)}</td>
      <td><span id="tt-camp-status-${esc(c.id)}" style="padding:2px 8px;border-radius:10px;font-size:11px;
          background:${c.status_raw==='ENABLE'?'rgba(34,201,122,.15)':'rgba(255,69,58,.12)'};
          color:${c.status_raw==='ENABLE'?'#22c97a':'#f87171'}">${esc(c.status)}</span></td>
      <td style="font-size:11px;color:var(--m)">${esc(c.objective||'—')}</td>
      <td style="white-space:nowrap">
        <span id="tt-camp-budget-${esc(c.id)}">${esc(c.budget_fmt)}</span>
        <button onclick="ttChangeBudget('${esc(c.id)}',${c.budget})" title="Cambiar presupuesto"
          style="margin-left:4px;padding:1px 5px;font-size:10px;border-radius:4px;background:var(--bg3);border:1px solid var(--br2);color:var(--m);cursor:pointer">✎</button>
      </td>
      <td style="color:var(--t);font-weight:500">${esc(c.spend_fmt)}</td>
      <td>${esc(String(c.impressions||0))}</td>
      <td>${esc(String(c.clicks||0))}</td>
      <td>${esc(c.ctr_fmt)}</td>
      <td>${esc(c.cpm_fmt)}</td>
      <td>${esc(String(c.conversions||0))}</td>
      <td>${esc(c.cpa_fmt)}</td>
      <td style="white-space:nowrap">
        ${c.status_raw==='ENABLE'
          ? `<button onclick="ttPauseCampaign('${esc(c.id)}',this)"
               style="padding:3px 8px;font-size:11px;border-radius:5px;background:rgba(255,69,58,.12);border:1px solid rgba(255,69,58,.3);color:#f87171;cursor:pointer;font-family:var(--fb)">⏸ Pausar</button>`
          : `<button onclick="ttActivateCampaign('${esc(c.id)}',this)"
               style="padding:3px 8px;font-size:11px;border-radius:5px;background:rgba(34,201,122,.12);border:1px solid rgba(34,201,122,.3);color:#22c97a;cursor:pointer;font-family:var(--fb)">▶ Activar</button>`
        }
      </td>
    </tr>`).join('');
  document.getElementById('tt-camp-wrap').style.display = 'block';
}

async function ttPauseCampaign(campId, btn) {
  const origText = btn.textContent;
  btn.disabled = true; btn.textContent = '…';
  const token = document.querySelector('meta[name="dm-csrf"]')?.content || '';
  try {
    const d = await fetch(`api/tiktok-data.php?client_id=${currentClient}`, {
      method:'POST', headers:{'Content-Type':'application/json','X-CSRF-Token':token},
      body: JSON.stringify({action:'pause_campaign', campaign_id: campId}),
    }).then(r => r.json());
    if (!d.ok) { showToast('✗ ' + (d.error||'Error al pausar'), 'var(--red)'); btn.disabled=false; btn.textContent=origText; return; }
    showToast('✓ Campaña pausada', 'var(--g)');
    const statusEl = document.getElementById('tt-camp-status-' + campId);
    if (statusEl) { statusEl.textContent='Pausada'; statusEl.style.background='rgba(255,69,58,.12)'; statusEl.style.color='#f87171'; }
    btn.outerHTML = `<button onclick="ttActivateCampaign('${campId}',this)"
      style="padding:3px 8px;font-size:11px;border-radius:5px;background:rgba(34,201,122,.12);border:1px solid rgba(34,201,122,.3);color:#22c97a;cursor:pointer;font-family:var(--fb)">▶ Activar</button>`;
  } catch(e) { showToast('✗ Error de red', 'var(--red)'); btn.disabled=false; btn.textContent=origText; }
}

async function ttActivateCampaign(campId, btn) {
  const origText = btn.textContent;
  btn.disabled = true; btn.textContent = '…';
  const token = document.querySelector('meta[name="dm-csrf"]')?.content || '';
  try {
    const d = await fetch(`api/tiktok-data.php?client_id=${currentClient}`, {
      method:'POST', headers:{'Content-Type':'application/json','X-CSRF-Token':token},
      body: JSON.stringify({action:'activate_campaign', campaign_id: campId}),
    }).then(r => r.json());
    if (!d.ok) { showToast('✗ ' + (d.error||'Error al activar'), 'var(--red)'); btn.disabled=false; btn.textContent=origText; return; }
    showToast('✓ Campaña activada', 'var(--g)');
    const statusEl = document.getElementById('tt-camp-status-' + campId);
    if (statusEl) { statusEl.textContent='Activa'; statusEl.style.background='rgba(34,201,122,.15)'; statusEl.style.color='#22c97a'; }
    btn.outerHTML = `<button onclick="ttPauseCampaign('${campId}',this)"
      style="padding:3px 8px;font-size:11px;border-radius:5px;background:rgba(255,69,58,.12);border:1px solid rgba(255,69,58,.3);color:#f87171;cursor:pointer;font-family:var(--fb)">⏸ Pausar</button>`;
  } catch(e) { showToast('✗ Error de red', 'var(--red)'); btn.disabled=false; btn.textContent=origText; }
}

async function ttChangeBudget(campId, currentBudget) {
  const newBudget = prompt(`Nuevo presupuesto diario (actual: $${currentBudget}):`, currentBudget);
  if (!newBudget || isNaN(parseFloat(newBudget)) || parseFloat(newBudget) <= 0) return;
  const token = document.querySelector('meta[name="dm-csrf"]')?.content || '';
  try {
    const d = await fetch(`api/tiktok-data.php?client_id=${currentClient}`, {
      method:'POST', headers:{'Content-Type':'application/json','X-CSRF-Token':token},
      body: JSON.stringify({action:'change_tiktok_budget', campaign_id: campId, budget: parseFloat(newBudget)}),
    }).then(r => r.json());
    if (!d.ok) { showToast('✗ ' + (d.error||'Error al cambiar presupuesto'), 'var(--red)'); return; }
    const budgetEl = document.getElementById('tt-camp-budget-' + campId);
    if (budgetEl) budgetEl.textContent = '$' + parseFloat(newBudget).toLocaleString();
    showToast('✓ ' + (d.message || 'Presupuesto actualizado'), 'var(--g)');
  } catch(e) { showToast('✗ Error de red', 'var(--red)'); }
}

function populateTTCampFilter(list) {
  const sel = document.getElementById('tt-ag-camp-filter');
  sel.innerHTML = '<option value="">Todos los ad groups</option>' +
    list.map(c => `<option value="${esc(c.id)}">${esc(c.name)}</option>`).join('');
}

// ── Cargar Ad Groups ───────────────────────────────────────────────────────
async function loadTTAdgroups() {
  if (!currentClient || currentClient === 'all') return;
  document.getElementById('tt-ag-loading').style.display = 'block';
  document.getElementById('tt-ag-wrap').style.display    = 'none';
  document.getElementById('tt-ag-empty').style.display   = 'none';

  const campId = document.getElementById('tt-ag-camp-filter').value;
  const extra  = campId ? `&campaign_id=${encodeURIComponent(campId)}` : '';
  try {
    const d = await fetch(`api/tiktok-data.php?action=adgroups&${buildTTParams(currentClient)}${extra}`).then(r => r.json());
    document.getElementById('tt-ag-loading').style.display = 'none';
    if (!d.ok || !d.data?.length) {
      document.getElementById('tt-ag-empty').style.display = 'block'; return;
    }
    const tbody = document.getElementById('tt-ag-body');
    tbody.innerHTML = d.data.map(g => `
      <tr>
        <td style="max-width:200px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap" title="${esc(g.name)}">${esc(g.name)}</td>
        <td><span style="padding:2px 8px;border-radius:10px;font-size:11px;
            background:${g.status_raw==='ENABLE'?'rgba(34,201,122,.15)':'rgba(255,69,58,.12)'};
            color:${g.status_raw==='ENABLE'?'#22c97a':'#f87171'}">${esc(g.status)}</span></td>
        <td style="font-size:11px;color:var(--m)">${esc(g.goal||'—')}</td>
        <td>${esc(g.budget_fmt)}</td>
        <td style="font-weight:500">${esc(g.spend_fmt)}</td>
        <td>${esc(String(g.impressions||0))}</td>
        <td>${esc(String(g.clicks||0))}</td>
        <td>${esc(g.ctr_fmt)}</td>
        <td>${esc(String(g.conversions||0))}</td>
        <td>${esc(g.cpa_fmt)}</td>
      </tr>`).join('');
    document.getElementById('tt-ag-wrap').style.display = 'block';
  } catch(e) {
    document.getElementById('tt-ag-loading').style.display = 'none';
    document.getElementById('tt-ag-empty').style.display   = 'block';
  }
}

// ── AVI TikTok ────────────────────────────────────────────────────────────
function ttAVIPauseIneficientes() {
  const campContext = ttCampaigns.length
    ? ttCampaigns.map(c =>
        `- ${c.name} | Estado: ${c.status} | Inversión: ${c.spend_fmt} | CTR: ${c.ctr_fmt} | CPM: ${c.cpm_fmt} | Conv: ${c.conversions} | CPA: ${c.cpa_fmt}`
      ).join('\n')
    : 'No hay datos de campañas cargados aún.';
  const q = `Analiza estas campañas TikTok Ads y dime cuáles deberían pausarse por ser ineficientes (alto CPM, bajo CTR, sin conversiones, CPA excesivo). Para cada una justifica la decisión y sugiere qué acciones tomar en las activas para mejorar resultados:\n\n${campContext}`;
  document.getElementById('tt-avi-q').value = q;
  askTTAVI();
  switchTTTab('avi', document.querySelector('.tt-tab[onclick*="avi"]'));
}

function ttAVIquick(q) {
  document.getElementById('tt-avi-q').value = q;
  askTTAVI();
}

async function askTTAVI() {
  const q = document.getElementById('tt-avi-q').value.trim();
  if (!q) return;
  const resp = document.getElementById('tt-avi-resp');
  resp.innerHTML = '<span style="color:var(--m);font-size:12px">AVI analizando...</span>';

  const c = CLIENTS?.find(x => x.id == currentClient) || {};
  const ctx = document.getElementById('tiktok-ctx')?.value || '';
  const brandCtx = typeof getBrandContext === 'function' ? getBrandContext() : '';

  try {
    const token = document.querySelector('meta[name="dm-csrf"]')?.content || '';
    const d = await fetch('api/avi.php', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json', 'X-CSRF-Token': token },
      body: JSON.stringify({
        question: q, section: 'tiktok',
        client_name: c.name || '', client_url: c.url || '',
        client_industry: c.industry || '', client_ctx: ctx, brand_ctx: brandCtx,
      }),
    }).then(r => r.json());
    resp.innerHTML = typeof renderMD === 'function'
      ? renderMD(d.response || 'Sin respuesta')
      : (d.response || 'Sin respuesta').replace(/\n/g, '<br>');
  } catch(e) {
    resp.innerHTML = '<span style="color:#f87171">Error al contactar AVI.</span>';
  }
  document.getElementById('tt-avi-q').value = '';
}

// ── Conectar TikTok OAuth ─────────────────────────────────────────────────
function connectTikTok() {
  if (!currentClient || currentClient === 'all') {
    alert('Selecciona un cliente primero.'); return;
  }
  window.open(`api/tiktok-oauth.php?client_id=${currentClient}`, '_blank', 'width=600,height=700');
}

// ── Helpers ───────────────────────────────────────────────────────────────
function buildTTParams(clientId) {
  const sel  = document.getElementById('tt-period-sel')?.value || ttCurrentPeriod;
  let params = `client_id=${clientId}&period=${sel}`;
  if (sel === 'custom') {
    const from = document.getElementById('tt-date-from')?.value;
    const to   = document.getElementById('tt-date-to')?.value;
    if (from && to) params += `&date_from=${from}&date_to=${to}`;
  }
  return params;
}

function showTTError(msg) {
  const errDiv = document.getElementById('tt-api-error');
  const errMsg = document.getElementById('tt-api-error-msg');
  if (errDiv) errDiv.style.display = 'block';
  if (errMsg) {
    const friendly = msg && msg.toLowerCase().includes('token')
      ? 'El token de acceso expiró. Reconecta la cuenta TikTok.'
      : (msg || 'No se pudo obtener datos. Verifica las credenciales.');
    errMsg.textContent = friendly;
  }
  document.getElementById('tt-tabs-wrap').style.display = 'none';
  ['tt-spend','tt-impr','tt-clicks','tt-ctr','tt-reach','tt-conv','tt-cpa','tt-cpm']
    .forEach(function(id){ const el=document.getElementById(id); if(el)el.textContent='—'; });
}

function esc(s) {
  return String(s || '').replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;').replace(/"/g,'&quot;');
}

// ── renderTTPacing — calcula budget pacing del mes ────────────────────────
function renderTTPacing(camps) {
  const body = document.getElementById('tt-pacing-body');
  const daysEl = document.getElementById('tt-pacing-days');
  if (!body) return;

  const today = new Date();
  const endOfMonth = new Date(today.getFullYear(), today.getMonth() + 1, 0);
  const daysLeft = endOfMonth.getDate() - today.getDate() + 1;
  const daysTotal = endOfMonth.getDate();
  const daysPassed = daysTotal - daysLeft;

  if (daysEl) daysEl.textContent = daysLeft + ' días restantes en el mes';

  const activeCamps = (camps || []).filter(c => c.status_raw === 'ENABLE');

  if (!activeCamps.length) {
    body.innerHTML = '<div style="color:var(--m);font-size:12px;text-align:center;padding:20px">No hay campañas activas para calcular el pacing.</div>';
    return;
  }

  const totalDailyBudget = activeCamps.reduce((sum, c) => sum + (c.budget || 0), 0);
  const totalMonthBudget = totalDailyBudget * daysTotal;
  const projectedSpend   = totalDailyBudget * daysTotal; // basado en ritmo actual
  const currentSpend     = activeCamps.reduce((sum, c) => sum + (c.spend || 0), 0);
  const expectedByNow    = totalDailyBudget * daysPassed;
  const pacingPct        = expectedByNow > 0 ? (currentSpend / expectedByNow) * 100 : 0;
  const projectedEnd     = daysPassed > 0 ? (currentSpend / daysPassed) * daysTotal : 0;
  const budgetAvail      = projectedSpend - currentSpend;

  let barColor = 'var(--g)';
  let statusText = 'En ritmo';
  if (pacingPct > 100) { barColor = 'var(--red)'; statusText = 'Sobre ritmo'; }
  else if (pacingPct > 80) { barColor = 'var(--y)'; statusText = 'Cerca del límite'; }
  const barWidth = Math.min(pacingPct, 120).toFixed(1);

  body.innerHTML = `
    <div style="display:flex;justify-content:space-between;font-size:11px;color:var(--m);margin-bottom:6px">
      <span>Gasto actual: <strong style="color:var(--t)">$${currentSpend.toFixed(2)}</strong></span>
      <span>Esperado a hoy: <strong style="color:var(--t)">$${expectedByNow.toFixed(2)}</strong></span>
      <span style="color:${barColor};font-weight:600">${statusText}</span>
    </div>
    <div style="background:var(--bg3);border-radius:6px;height:10px;overflow:hidden;margin-bottom:10px">
      <div style="background:${barColor};height:100%;width:${barWidth}%;transition:width .4s;border-radius:6px"></div>
    </div>
    <div style="display:flex;gap:18px;flex-wrap:wrap;font-size:12px">
      <div>📅 <span style="color:var(--m)">Proyección fin de mes:</span> <strong>$${projectedEnd.toFixed(2)}</strong></div>
      <div>💰 <span style="color:var(--m)">Presupuesto disponible:</span> <strong>$${Math.max(budgetAvail,0).toFixed(2)}</strong></div>
      <div>📊 <span style="color:var(--m)">Pacing:</span> <strong style="color:${barColor}">${pacingPct.toFixed(1)}%</strong></div>
      <div>🗓 <span style="color:var(--m)">Días restantes:</span> <strong>${daysLeft}</strong></div>
    </div>`;
}

// ── loadTTTrends — análisis de tendencias con AVI ─────────────────────────
function loadTTTrends() {
  const ctx  = document.getElementById('tiktok-ctx')?.value || '';
  const campSummary = ttCampaigns.length
    ? ttCampaigns.slice(0,5).map(c =>
        `- ${c.name} | Inversión: ${c.spend_fmt} | CTR: ${c.ctr_fmt} | CPM: ${c.cpm_fmt} | Conv: ${c.conversions}`
      ).join('\n')
    : 'Sin campañas cargadas.';

  const prompt = `Eres un experto en TikTok Ads y marketing de contenidos. Analiza el siguiente contexto de negocio y campañas activas, y proporciona:

1. **Tendencias de contenido en TikTok** para este nicho específico (formatos que están funcionando ahora)
2. **Formatos de anuncio recomendados** (In-Feed Ads, TopView, Spark Ads, Brand Takeover) con justificación para este negocio
3. **5 ideas de hooks virales** adaptadas al negocio (primeros 3 segundos que detengan el scroll)
4. **Hashtags trending** relevantes para el nicho (mínimo 10)
5. **Tipos de música/sonidos** que funcionan mejor en este nicho en TikTok

**Contexto del cliente:**
${ctx || 'No especificado — basa las recomendaciones en mejores prácticas generales de TikTok Ads.'}

**Campañas actuales:**
${campSummary}

Sé específico, accionable y usa emojis para hacer la respuesta fácil de leer.`;

  const respEl = document.getElementById('tt-trends-resp');
  if (respEl) { respEl.style.display='block'; respEl.textContent='✦ AVI analizando tendencias...'; }
  callAVI(prompt, ctx, 'tt-trends-resp', '✦ AVI analizando tendencias...', 'tiktok');

  // También cargar comparativa
  const sel  = document.getElementById('tt-period-sel')?.value || ttCurrentPeriod;
  const from = document.getElementById('tt-date-from')?.value || '';
  const to   = document.getElementById('tt-date-to')?.value || '';
  loadTTCompare(sel, from, to);
}

// ── loadTTCompare — datos del período anterior ────────────────────────────
async function loadTTCompare(period, from, to) {
  if (!currentClient || currentClient === 'all') return;
  const compareBody = document.getElementById('tt-compare-body');
  if (compareBody) compareBody.innerHTML = '<div style="color:var(--m);font-size:12px;text-align:center;padding:16px">Cargando comparativa...</div>';

  let params = `action=compare&client_id=${currentClient}&period=${period}`;
  if (period === 'custom' && from && to) params += `&date_from=${from}&date_to=${to}`;

  try {
    const d = await fetch(`api/tiktok-data.php?${params}`).then(r => r.json());
    if (!d.ok || !d.prev) {
      if (compareBody) compareBody.innerHTML = '<div style="color:var(--m);font-size:12px;text-align:center;padding:16px">No hay datos del período anterior disponibles.</div>';
      return;
    }
    // Build curr object from current metric elements
    const curr = {
      spend:       parseFloat(document.getElementById('tt-spend')?.dataset?.raw || 0),
      impressions: parseFloat(document.getElementById('tt-impr')?.dataset?.raw  || 0),
      clicks:      parseFloat(document.getElementById('tt-clicks')?.dataset?.raw || 0),
      ctr:         parseFloat(document.getElementById('tt-ctr')?.dataset?.raw   || 0),
      reach:       parseFloat(document.getElementById('tt-reach')?.dataset?.raw  || 0),
      conversions: parseFloat(document.getElementById('tt-conv')?.dataset?.raw   || 0),
      cpa:         parseFloat(document.getElementById('tt-cpa')?.dataset?.raw    || 0),
      cpm:         parseFloat(document.getElementById('tt-cpm')?.dataset?.raw    || 0),
    };
    renderTTDeltas(d.prev, curr);
    renderTTCompareTable(d.prev, curr, compareBody);
  } catch(e) {
    if (compareBody) compareBody.innerHTML = '<div style="color:var(--m);font-size:12px;text-align:center;padding:16px">Error al cargar comparativa.</div>';
  }
}

// ── renderTTDeltas — badges delta en tab Resumen ──────────────────────────
function renderTTDeltas(prev, curr) {
  // Métricas donde ▲ = bueno: impressions, clicks, ctr, reach, conversions
  // Métricas donde ▼ = bueno (costos): spend, cpa, cpm
  const metrics = [
    { id:'tt-spend-d',   prev:prev.spend,       curr:curr.spend,       lowerIsBetter:false, fmt:'$' },
    { id:'tt-impr-d',    prev:prev.impressions,  curr:curr.impressions,  lowerIsBetter:false, fmt:''  },
    { id:'tt-clicks-d',  prev:prev.clicks,       curr:curr.clicks,       lowerIsBetter:false, fmt:''  },
    { id:'tt-ctr-d',     prev:prev.ctr,          curr:curr.ctr,          lowerIsBetter:false, fmt:'%' },
    { id:'tt-reach-d',   prev:prev.reach,        curr:curr.reach,        lowerIsBetter:false, fmt:''  },
    { id:'tt-conv-d',    prev:prev.conversions,  curr:curr.conversions,  lowerIsBetter:false, fmt:''  },
    { id:'tt-cpa-d',     prev:prev.cpa,          curr:curr.cpa,          lowerIsBetter:true,  fmt:'$' },
    { id:'tt-cpm-d',     prev:prev.cpm,          curr:curr.cpm,          lowerIsBetter:true,  fmt:'$' },
  ];
  metrics.forEach(m => {
    const el = document.getElementById(m.id);
    if (!el) return;
    if (!m.prev || m.prev === 0) { el.textContent = ''; return; }
    const delta = ((m.curr - m.prev) / m.prev) * 100;
    const isGood = m.lowerIsBetter ? delta < 0 : delta > 0;
    const arrow  = delta > 0 ? '▲' : '▼';
    const color  = isGood ? 'var(--g)' : 'var(--red)';
    el.style.color = color;
    el.textContent  = `${arrow} ${Math.abs(delta).toFixed(1)}%`;
    el.style.fontSize = '11px';
  });
}

// ── renderTTCompareTable — tabla comparativa en tab Tendencias ─────────────
function renderTTCompareTable(prev, curr, container) {
  if (!container) return;
  // lowerIsBetter para cpa y cpm
  const rows = [
    { label:'Inversión',     pv:prev.spend,       cv:curr.spend,       lowerIsBetter:false, fmt:v=>'$'+v.toFixed(2) },
    { label:'Impresiones',   pv:prev.impressions,  cv:curr.impressions,  lowerIsBetter:false, fmt:v=>Math.round(v).toLocaleString() },
    { label:'Clics',         pv:prev.clicks,       cv:curr.clicks,       lowerIsBetter:false, fmt:v=>Math.round(v).toLocaleString() },
    { label:'CTR',           pv:prev.ctr,          cv:curr.ctr,          lowerIsBetter:false, fmt:v=>v.toFixed(2)+'%' },
    { label:'Alcance',       pv:prev.reach,        cv:curr.reach,        lowerIsBetter:false, fmt:v=>Math.round(v).toLocaleString() },
    { label:'Conversiones',  pv:prev.conversions,  cv:curr.conversions,  lowerIsBetter:false, fmt:v=>Math.round(v).toLocaleString() },
    { label:'CPA',           pv:prev.cpa,          cv:curr.cpa,          lowerIsBetter:true,  fmt:v=>v>0?'$'+v.toFixed(2):'—' },
    { label:'CPM',           pv:prev.cpm,          cv:curr.cpm,          lowerIsBetter:true,  fmt:v=>'$'+v.toFixed(2) },
  ];

  const rowsHtml = rows.map(r => {
    const delta = (r.pv && r.pv !== 0) ? ((r.cv - r.pv) / r.pv) * 100 : null;
    let deltaHtml = '—';
    if (delta !== null) {
      const isGood = r.lowerIsBetter ? delta < 0 : delta > 0;
      const arrow  = delta > 0 ? '▲' : '▼';
      const color  = isGood ? 'var(--g)' : 'var(--red)';
      deltaHtml = `<span style="color:${color};font-weight:600">${arrow} ${Math.abs(delta).toFixed(1)}%</span>`;
    }
    return `<tr>
      <td style="padding:7px 10px;font-size:12px;color:var(--t)">${r.label}</td>
      <td style="padding:7px 10px;font-size:12px;text-align:right">${r.fmt(r.cv)}</td>
      <td style="padding:7px 10px;font-size:12px;text-align:right;color:var(--m)">${r.fmt(r.pv)}</td>
      <td style="padding:7px 10px;font-size:12px;text-align:right">${deltaHtml}</td>
    </tr>`;
  }).join('');

  container.innerHTML = `
    <div style="overflow-x:auto">
      <table style="width:100%;border-collapse:collapse">
        <thead>
          <tr style="border-bottom:1px solid var(--br2)">
            <th style="padding:7px 10px;font-size:11px;color:var(--m);text-align:left;font-weight:500">Métrica</th>
            <th style="padding:7px 10px;font-size:11px;color:var(--m);text-align:right;font-weight:500">Período actual</th>
            <th style="padding:7px 10px;font-size:11px;color:var(--m);text-align:right;font-weight:500">Período anterior</th>
            <th style="padding:7px 10px;font-size:11px;color:var(--m);text-align:right;font-weight:500">Delta %</th>
          </tr>
        </thead>
        <tbody>${rowsHtml}</tbody>
      </table>
    </div>`;
}

// ── Tab Creativos — helpers ────────────────────────────────────────────────
let _ttScriptDuration = 15;

function ttSelectDuration(d) {
  _ttScriptDuration = d;
  [15,30,60].forEach(v => {
    const b = document.getElementById('tt-script-' + v);
    if (!b) return;
    b.style.background = v === d ? '#ff2d55' : 'var(--bg3)';
    b.style.color      = v === d ? '#fff'    : 'var(--t)';
    b.style.border     = v === d ? 'none'    : '1px solid var(--br2)';
    b.style.fontWeight = v === d ? '600'     : '400';
  });
}

function _ttCreativosCtx() {
  const c = (typeof CLIENTS !== 'undefined' ? CLIENTS : []).find(x => x.id == currentClient) || {};
  const extraCtx = document.getElementById('tiktok-ctx')?.value || '';
  const campSummary = ttCampaigns.length
    ? ttCampaigns.slice(0, 5).map(c =>
        `- ${c.name} | Inversión: ${c.spend_fmt} | CTR: ${c.ctr_fmt} | CPM: ${c.cpm_fmt} | Conv: ${c.conversions}`
      ).join('\n')
    : 'Sin campañas cargadas.';
  return `Cliente: ${c.name || 'ID ' + currentClient} | Industria: ${c.industry || '—'} | Web: ${c.url || '—'}\nContexto TikTok: ${extraCtx || 'No especificado'}\nCampañas activas:\n${campSummary}`;
}

function ttGenerateHook(tipo) {
  const ctx = _ttCreativosCtx();
  const prompts = {
    curiosidad: `Genera 5 hooks de CURIOSIDAD para TikTok Ads adaptados al negocio del cliente. Cada hook debe: tener máx 10 palabras, hacer que el usuario quiera saber más, no revelar la respuesta. Formato: 1. [hook] — por qué funciona (1 línea)`,
    shock:      `Genera 5 hooks de DATO IMPACTANTE o SHOCK para TikTok Ads del cliente. Cada hook: estadística sorprendente o afirmación contraintuitiva, máx 10 palabras. Formato: 1. [hook] — por qué funciona (1 línea)`,
    pregunta:   `Genera 5 hooks de PREGUNTA DIRECTA para TikTok Ads que hagan que el usuario se sienta identificado. Para el negocio del cliente. Máx 10 palabras cada uno. Formato: 1. [hook] — por qué funciona (1 línea)`,
    problema:   `Genera 5 hooks de PROBLEMA REAL que vive la audiencia del cliente. El hook describe el dolor exacto en 10 palabras max. Formato: 1. [hook] — por qué funciona (1 línea)`,
    trending:   `Genera 5 hooks en FORMATOS TRENDING de TikTok (POV:, Me pasó que..., Nadie te dice que..., El secreto que..., Cometí el error de...) adaptados al negocio del cliente. Formato: 1. [hook] — formato usado`,
    todos:      `Genera 1 hook de cada tipo para TikTok Ads del cliente: CURIOSIDAD, DATO SHOCK, PREGUNTA DIRECTA, PROBLEMA REAL y FORMATO TRENDING. Total 5 hooks. Para cada uno: el hook (máx 10 palabras) y por qué funciona (1 línea). Incluye emoji al inicio de cada hook.`,
  };
  const resp = document.getElementById('tt-hooks-resp');
  if (resp) { resp.style.display = 'block'; resp.innerHTML = '<span style="color:var(--m);font-size:12px">✦ AVI generando hooks...</span>'; }
  callAVI(prompts[tipo] || prompts.todos, ctx, 'tt-hooks-resp', '✦ AVI generando hooks...', 'tiktok');
}

function ttGenerateCopy(tipo) {
  const ctx = _ttCreativosCtx();
  const prompts = {
    caption:   `Escribe 3 captions para TikTok Ads del cliente (texto que aparece sobre el video). Cada caption: máx 150 caracteres, con emoji inicial, CTA natural. Formato de anuncio: directo y conversacional.`,
    aida:      `Aplica el framework AIDA para crear 2 copies completos de TikTok Ad para el cliente:\n- Atención (hook 5 palabras)\n- Interés (beneficio clave)\n- Deseo (prueba social o diferenciador)\n- Acción (CTA directo)\nCada copy debe caber en 200 caracteres.`,
    pas:       `Aplica el framework PAS para crear 2 copies de TikTok Ad para el cliente:\n- Problema (el dolor del cliente ideal)\n- Agitación (consecuencias si no lo resuelve)\n- Solución (el producto/servicio)\nCada copy: máx 200 caracteres. Tono directo y empático.`,
    cta:       `Genera 8 variaciones de CTA para TikTok Ads del cliente. Mix de urgencia, curiosidad y valor. Ejemplos de estructura: "Link en bio →", "Agenda GRATIS aquí", "Solo por hoy —". Adapta al negocio específico del cliente.`,
    hashtags:  `Crea una estrategia de hashtags para TikTok Ads del cliente. Incluye:\n- 5 hashtags de nicho (alta relevancia, media competencia)\n- 3 hashtags de tendencia actual (alta visibilidad)\n- 2 hashtags de marca/branded\n- 2 hashtags de audiencia\nPor qué usar cada grupo en 1 línea.`,
  };
  const resp = document.getElementById('tt-copy-resp');
  if (resp) { resp.style.display = 'block'; resp.innerHTML = '<span style="color:var(--m);font-size:12px">✦ AVI generando copy...</span>'; }
  callAVI(prompts[tipo] || prompts.caption, ctx, 'tt-copy-resp', '✦ AVI generando copy...', 'tiktok');
}

function ttGenerateScript() {
  const ctx    = _ttCreativosCtx();
  const dur    = _ttScriptDuration;
  const fmt    = document.getElementById('tt-script-format')?.value || 'educativo';
  const fmtMap = { educativo:'Educativo/Tutorial', testimonial:'Testimonial/Caso de éxito', problema_solucion:'Problema → Solución', trending:'Formato trending (POV/stitch)', oferta:'Oferta directa' };
  const prompt = `Crea un script completo de ${dur} segundos para un TikTok Ad de formato "${fmtMap[fmt]}" para el cliente. El script debe tener TIEMPOS EXACTOS en segundos, qué dice el locutor/actor, qué se ve en pantalla y texto de overlay (si aplica).

Estructura obligatoria con timestamps:
- [0-3s] HOOK: (lo más importante, para el scroll)
- [3-${Math.round(dur*0.5)}s] DESARROLLO: (valor/problema/historia)
- [${Math.round(dur*0.5)}-${dur-3}s] CLÍMAX: (solución/prueba social)
- [${dur-3}-${dur}s] CTA: (llamada a acción clara)

Para cada timestamp incluye: AUDIO (qué dice) | VISUAL (qué se ve) | TEXT (overlay si aplica).
El script debe ser 100% grabable por alguien no profesional, natural y directo.

Contexto del cliente:
${ctx}`;
  const resp = document.getElementById('tt-script-resp');
  if (resp) { resp.style.display = 'block'; resp.innerHTML = '<span style="color:var(--m);font-size:12px">✦ AVI escribiendo script...</span>'; }
  const wrap = document.getElementById('tt-script-copy-wrap');
  callAVI(prompt, ctx, 'tt-script-resp', '✦ AVI escribiendo script...', 'tiktok',
    () => { if (wrap) wrap.style.display = 'block'; }
  );
}

function ttCopyScript() {
  const resp = document.getElementById('tt-script-resp');
  const text = resp ? (resp.innerText || resp.textContent || '') : '';
  if (!text || text.includes('AVI escribiendo')) { showToast('Genera un script primero', 'var(--y)'); return; }
  navigator.clipboard.writeText(text).then(
    () => showToast('✓ Script copiado', 'var(--g)'),
    () => showToast('✗ No se pudo copiar', 'var(--red)')
  );
}

function ttAnalyzeCreativeFatigue() {
  const ctx = _ttCreativosCtx();
  const campData = ttCampaigns.length
    ? ttCampaigns.map(c => `${c.name}: CTR=${c.ctr_fmt} CPM=${c.cpm_fmt} Conv=${c.conversions} Status=${c.status}`).join('\n')
    : 'Sin datos de campañas disponibles.';
  const prompt = `Analiza las señales de FATIGA CREATIVA en las campañas TikTok Ads de este cliente.

Datos actuales de campañas:
${campData}

Proporciona:
1. **Diagnóstico de fatiga** — ¿Hay señales de fatiga? (CPM elevado, CTR cayendo, conv. bajando)
2. **Campañas en riesgo** — cuáles necesitan refresh urgente
3. **Señales a monitorear** — KPIs específicos de TikTok y umbrales de alerta
4. **Plan de refresh** — qué elementos cambiar primero (hook, visual, copy, audiencia) y en qué orden
5. **Frecuencia de rotación** — cada cuántos días/semanas refrescar creativos para este nicho

Sé específico con los datos disponibles y orientado a acción.`;
  const resp = document.getElementById('tt-fatigue-resp');
  if (resp) { resp.style.display = 'block'; resp.innerHTML = '<span style="color:var(--m);font-size:12px">✦ AVI analizando fatiga creativa...</span>'; }
  callAVI(prompt, ctx, 'tt-fatigue-resp', '✦ AVI analizando fatiga creativa...', 'tiktok');
}
</script>
<?php endif; ?>
