// tt-overlay.js — content script TikTok (isolated world).
// Injeta um botão "Save" no canto superior direito de cada card de vídeo que
// aparece no feed (For You, Following, perfil, etc). Quando clicado, busca o
// item correspondente no cache do inject-tt.js (via window.postMessage bridge)
// e enfileira um download direto pelo SW — sem precisar abrir o painel lateral.
//
// Estratégia:
//   1. MutationObserver detecta <a href="/@user/video/ID"> novos no DOM
//   2. Pra cada um, anexa um botão flutuante no card pai
//   3. Click → solicita item via __is_ext_tt_get_item → SW enfileira
//
// Importante: respeita o switch ON/OFF da extensão (mesmo flag do panel).

(function () {
  if (window.__IS_TT_OVERLAY__) return;
  window.__IS_TT_OVERLAY__ = true;

  // Flag global ON/OFF (mesma do panel — controlada pelo popup)
  let _extEnabled = true;
  try {
    chrome.storage.local.get('is_settings').then(s => {
      _extEnabled = (s['is_settings']?.extension_enabled) !== false;
      if (_extEnabled) injectAllButtons();
      else removeAllButtons();
    });
    chrome.runtime.onMessage.addListener((msg) => {
      if (msg?.type !== 'IS_EXT_ENABLED_CHANGED') return;
      _extEnabled = !!msg.enabled;
      if (_extEnabled) injectAllButtons();
      else removeAllButtons();
    });
  } catch (_) {}

  // CSS do botão Save flutuante (injeta uma vez)
  const STYLE_ID = 'is-tt-save-style';
  if (!document.getElementById(STYLE_ID)) {
    const s = document.createElement('style');
    s.id = STYLE_ID;
    s.textContent = `
      .is-tt-save-wrap {
        position: absolute;
        top: 12px;
        right: 12px;
        z-index: 999999;
        pointer-events: auto;
      }
      .is-tt-save-btn {
        display: inline-flex;
        align-items: center;
        gap: 6px;
        background: rgba(0,0,0,0.62);
        backdrop-filter: blur(6px);
        -webkit-backdrop-filter: blur(6px);
        color: #fff;
        border: 1px solid rgba(255,255,255,0.18);
        border-radius: 999px;
        padding: 6px 12px;
        font: 600 12px/1 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
        cursor: pointer;
        transition: background .15s ease, transform .1s ease;
        box-shadow: 0 2px 8px rgba(0,0,0,.35);
      }
      .is-tt-save-btn:hover { background: rgba(59,130,246,0.92); transform: scale(1.04); }
      .is-tt-save-btn:active { transform: scale(0.97); }
      .is-tt-save-btn.is-busy { background: rgba(59,130,246,0.85); cursor: wait; }
      .is-tt-save-btn.is-done { background: rgba(34,197,94,0.92); }
      .is-tt-save-btn.is-err { background: rgba(244,63,94,0.92); }
      .is-tt-save-btn svg { display: block; width: 14px; height: 14px; }
    `;
    (document.head || document.documentElement).appendChild(s);
  }

  // Procura o melhor container pai pra ancorar o botão. Idealmente o card que
  // tem position:relative ou onde o vídeo aparece. Fallback: o pai do próprio <a>.
  function pickAnchorContainer(linkEl) {
    // Sobe até no máximo 5 níveis procurando um elemento que tenha position
    // relative/absolute (pra absolute posicionar bem dentro)
    let cur = linkEl;
    for (let i = 0; i < 5 && cur; i++) {
      const cs = window.getComputedStyle(cur);
      if (cs.position === 'relative' || cs.position === 'absolute') {
        return cur;
      }
      cur = cur.parentElement;
    }
    return linkEl.parentElement || linkEl;
  }

  // Extrai { username, video_id } de href tipo /@user/video/1234567890
  function parseVideoHref(href) {
    if (!href) return null;
    const m = href.match(/\/@([^/?#]+)\/video\/(\d+)/);
    if (!m) return null;
    return { username: m[1], video_id: m[2] };
  }

  // Comunica com inject-tt.js pra buscar o item completo
  function requestItemFromInject(video_id, timeoutMs = 1500) {
    return new Promise((resolve) => {
      const requestId = 'gi_' + Math.random().toString(36).slice(2);
      let done = false;
      const t = setTimeout(() => { if (!done) { done = true; window.removeEventListener('message', listener); resolve(null); } }, timeoutMs);
      const listener = (event) => {
        if (event.source !== window) return;
        const d = event.data;
        if (!d || d.__is_ext_tt_get_item_reply !== true || d.requestId !== requestId) return;
        done = true; clearTimeout(t); window.removeEventListener('message', listener);
        resolve(d.item || null);
      };
      window.addEventListener('message', listener);
      window.postMessage({ __is_ext_tt_get_item: true, video_id, requestId }, '*');
    });
  }

  // Marca o link como processado pra não adicionar botão duplicado
  const PROCESSED_ATTR = 'data-is-save-injected';

  function buildButton(parsed, linkEl) {
    const wrap = document.createElement('div');
    wrap.className = 'is-tt-save-wrap';
    wrap.setAttribute('data-video-id', parsed.video_id);
    wrap.innerHTML = `
      <button type="button" class="is-tt-save-btn" title="Baixar com as suas configurações">
        <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">
          <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/>
          <polyline points="7 10 12 15 17 10"/>
          <line x1="12" y1="15" x2="12" y2="3"/>
        </svg>
        <span class="is-tt-save-label">Save</span>
      </button>
    `;
    const btn = wrap.querySelector('.is-tt-save-btn');
    const label = wrap.querySelector('.is-tt-save-label');

    // Previne que o click bubblee pro <a> (que abriria o vídeo)
    btn.addEventListener('click', async (e) => {
      e.preventDefault();
      e.stopPropagation();
      if (btn.classList.contains('is-busy') || btn.classList.contains('is-done')) return;

      btn.classList.add('is-busy');
      label.textContent = 'Buscando...';

      const item = await requestItemFromInject(parsed.video_id);
      if (!item) {
        // Não tem cache — pede pro user rolar pra carregar (a API só envia
        // ao scroll). Não dá pra forçar fetch sem reabrir o vídeo.
        btn.classList.remove('is-busy'); btn.classList.add('is-err');
        label.textContent = 'Sem dados — role e tente';
        setTimeout(() => { btn.classList.remove('is-err'); label.textContent = 'Save'; }, 3500);
        return;
      }

      label.textContent = 'Enfileirando...';
      try {
        const r = await new Promise((resolve) => {
          chrome.runtime.sendMessage({ type: 'ENQUEUE_DOWNLOAD', items: [item] }, (res) => {
            if (chrome.runtime.lastError) resolve({ ok: false, error: chrome.runtime.lastError.message });
            else resolve(res || { ok: false, error: 'sem resposta' });
          });
        });
        if (r.ok) {
          btn.classList.remove('is-busy'); btn.classList.add('is-done');
          label.textContent = '✓ Salvando';
        } else {
          btn.classList.remove('is-busy'); btn.classList.add('is-err');
          label.textContent = (r.error || 'erro').slice(0, 14);
          setTimeout(() => { btn.classList.remove('is-err'); label.textContent = 'Save'; }, 3500);
        }
      } catch (err) {
        btn.classList.remove('is-busy'); btn.classList.add('is-err');
        label.textContent = 'erro';
        setTimeout(() => { btn.classList.remove('is-err'); label.textContent = 'Save'; }, 3500);
      }
    });

    return wrap;
  }

  function injectButtonFor(linkEl) {
    if (!_extEnabled) return;
    if (linkEl.hasAttribute(PROCESSED_ATTR)) return;
    const href = linkEl.getAttribute('href') || '';
    const parsed = parseVideoHref(href);
    if (!parsed) return;

    linkEl.setAttribute(PROCESSED_ATTR, '1');

    const container = pickAnchorContainer(linkEl);
    // Garante position:relative no container pra o botão se posicionar bem
    const cs = window.getComputedStyle(container);
    if (cs.position === 'static') container.style.position = 'relative';

    const btn = buildButton(parsed, linkEl);
    container.appendChild(btn);
  }

  function injectAllButtons() {
    if (!_extEnabled) return;
    const links = document.querySelectorAll('a[href*="/video/"]');
    for (const a of links) injectButtonFor(a);
  }

  function removeAllButtons() {
    document.querySelectorAll('.is-tt-save-wrap').forEach(el => el.remove());
    document.querySelectorAll(`[${PROCESSED_ATTR}]`).forEach(el => el.removeAttribute(PROCESSED_ATTR));
  }

  // MutationObserver pra detectar cards novos (TikTok é SPA, scroll infinito)
  function startObserver() {
    let scheduled = false;
    const obs = new MutationObserver(() => {
      if (scheduled) return;
      scheduled = true;
      // Debounce: agrupa múltiplas mutations em 1 scan a cada 200ms
      setTimeout(() => { scheduled = false; injectAllButtons(); }, 200);
    });
    obs.observe(document.body || document.documentElement, { childList: true, subtree: true });
  }

  // Boot
  if (document.readyState === 'loading') {
    document.addEventListener('DOMContentLoaded', () => { injectAllButtons(); startObserver(); }, { once: true });
  } else {
    injectAllButtons();
    startObserver();
  }
  console.log('[IS-Ext/TT-Overlay] botão Save ativo');
})();
