/* global React, Icon, fmtViews, fmtDate, ytThumb, CARS, TOPICS, DIFF_LABEL, DIY_LABEL, TYPE_LABEL */

// ============================================================
// BUSCA FULL-TEXT NAS TRANSCRIÇÕES (rev. 14)
// Índice lazy-loaded (transcript-fulltext-index.json, ~3.7MB gzip) — só
// baixa na primeira busca. Cada segmento tem timestamp → link pro momento exato.
// ============================================================
let _ftIndex = null;       // [{id, s:[[start,text],...]}]
let _ftIndexPromise = null;

function _normalize(s) {
  // remove acentos para casar "valvula"/"válvula"
  return (s || '').toLowerCase().normalize('NFD').replace(/[̀-ͯ]/g, '');
}

async function loadFullTextIndex() {
  if (_ftIndex) return _ftIndex;
  if (_ftIndexPromise) return _ftIndexPromise;
  _ftIndexPromise = fetch('transcript-fulltext-index.json')
    .then(r => r.ok ? r.json() : [])
    .then(data => { _ftIndex = data; return data; })
    .catch(() => { _ftIndex = []; return []; });
  return _ftIndexPromise;
}

// Busca termos no texto das transcrições. Retorna até `limit` vídeos, cada um com
// o melhor segmento (mais termos casados) + timestamp + snippet.
async function fullTextSearch(query, limit = 12) {
  const terms = _normalize(query).split(/\s+/).filter(w => w.length > 2);
  if (terms.length === 0) return [];
  const index = await loadFullTextIndex();
  const out = [];
  for (const entry of index) {
    let best = null, bestHits = 0, totalHits = 0;
    for (const [start, text] of entry.s) {
      const norm = _normalize(text);
      let hits = 0;
      for (const t of terms) if (norm.includes(t)) hits++;
      if (hits === 0) continue;
      totalHits += hits;
      if (hits > bestHits) { bestHits = hits; best = { start, text }; }
    }
    if (best) {
      out.push({
        id: entry.id,
        timestamp_s: best.start,
        snippet: best.text,
        termsMatched: bestHits,
        totalHits,
      });
    }
  }
  // Ranqueia: mais termos distintos no melhor segmento, depois total de ocorrências
  out.sort((a, b) => (b.termsMatched - a.termsMatched) || (b.totalHits - a.totalHits));
  return out.slice(0, limit);
}

// ============================================================
// BUSCA HÍBRIDA — semântica (Voyage/Vectorize) + keyword merge
// pool: vídeos candidatos (filtrado por carro/tópico, ou allVideos)
// allVideosMap: map id→v para lookup rápido dos resultados do Worker
// ============================================================
async function hybridSearch(text, pool, allVideos) {
  const words = text.toLowerCase().split(/\s+/).filter(w => w.length > 2);
  const vidMap = Object.fromEntries(allVideos.map(v => [v.id, v]));
  const poolIds = new Set(pool.map(v => v.id));

  // 1. Keyword search no pool (título/resumo/tags)
  const kwScored = pool.map(v => {
    const hay = [v.title, v.summaryCard, v.sintomaPrincipal, v.tags]
      .filter(Boolean).join(' ').toLowerCase();
    let score = 0;
    words.forEach(w => { if (hay.includes(w)) score += 1; });
    return { v, kwScore: score };
  }).filter(x => x.kwScore > 0);

  // 2. Semântica via Worker
  let semanticScored = [];
  try {
    const resp = await fetch('https://tucho-search-worker.paulosgarage.workers.dev/search', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json', 'Origin': 'https://paulosgarage.com' },
      body: JSON.stringify({ q: text, top_k: 20 }),
      signal: AbortSignal.timeout(5000),
    });
    if (resp.ok) {
      const data = await resp.json();
      semanticScored = (data.results || [])
        .map(r => ({ v: vidMap[r.id], score: r.score }))
        .filter(x => x.v && poolIds.has(x.v.id));
    }
  } catch (_) { /* sem semântica */ }

  // 3. Full-text search nas transcrições (lazy-loaded, ~3.7MB na 1ª busca depois cache)
  // Crucial para ferramentas que só aparecem no transcript (ex: "aerógrafo" não está no título)
  const ftScoreMap = new Map(); // id → score (0.38–0.52)
  try {
    const ftResults = await fullTextSearch(text, 15);
    if (ftResults.length > 0) {
      const maxFtHits = Math.max(...ftResults.map(r => r.termsMatched), 1);
      ftResults
        .filter(r => poolIds.has(r.id) && vidMap[r.id])
        .forEach(r => {
          ftScoreMap.set(r.id, 0.38 + (r.termsMatched / maxFtHits) * 0.14);
        });
    }
  } catch (_) { /* sem full-text */ }

  if (semanticScored.length === 0 && ftScoreMap.size === 0) {
    // Só keyword
    const result = kwScored.sort((a, b) => b.kwScore - a.kwScore);
    return result.length > 0 ? result.map(x => ({ v: x.v, score: x.kwScore }))
                              : pool.slice(0, 20).map(v => ({ v, score: 0 }));
  }

  // Merge: semântico + boost keyword + boost full-text
  const kwMap = new Map(kwScored.map(x => [x.v.id, x.kwScore]));
  const maxKw = Math.max(...kwScored.map(x => x.kwScore), 1);

  // Mapa final: id → {v, score}
  const scoreMap = new Map();

  // Seed com resultados semânticos (+ boost kw + boost ft)
  for (const x of semanticScored) {
    const kw = kwMap.get(x.v.id) || 0;
    const kwBoost = (kw / maxKw) * 0.08;
    const ftScore = ftScoreMap.get(x.v.id) || 0;
    // Se full-text score > semântico, eleva parcialmente em direção ao ft score
    const ftBoost = ftScore > x.score ? (ftScore - x.score) * 0.6 : 0;
    scoreMap.set(x.v.id, { v: x.v, score: Math.min(x.score + kwBoost + ftBoost, 0.99) });
  }

  // Full-text que NÃO apareceu no top semântico (caso crítico: aerógrafo só no transcript)
  ftScoreMap.forEach((ftScore, id) => {
    if (!scoreMap.has(id) && vidMap[id]) {
      const kw = kwMap.get(id) || 0;
      const kwBoost = (kw / maxKw) * 0.05;
      scoreMap.set(id, { v: vidMap[id], score: ftScore + kwBoost });
    }
  });

  // Keyword-only (NÃO está em semântico nem full-text)
  for (const x of kwScored) {
    if (!scoreMap.has(x.v.id)) {
      scoreMap.set(x.v.id, { v: x.v, score: 0.30 + (x.kwScore / maxKw) * 0.12 });
    }
  }

  return [...scoreMap.values()].sort((a, b) => b.score - a.score).slice(0, 15);
}

// ============================================================
// AFFILIATE MODAL — popup de opções de compra no Mercado Livre
// ============================================================
// Preços embutidos no build (fetch_ml_prices.py) — sem chamada live.
function AffiliateModal({ name, group, onClose }) {
  // Ordena por preço crescente (sem preço fica por último)
  const sorted = React.useMemo(() => {
    return [...group].sort((a, b) => {
      if (a.price == null && b.price == null) return 0;
      if (a.price == null) return 1;
      if (b.price == null) return -1;
      return a.price - b.price;
    });
  }, [group]);

  const fmtBRL = v => v != null
    ? 'R$ ' + v.toLocaleString('pt-BR', { minimumFractionDigits: 2, maximumFractionDigits: 2 })
    : null;

  // Nota de data da ultima atualizacao de preco
  const priceDate = group.find(g => g.price_updated_at)?.price_updated_at || null;

  // fecha com Esc
  React.useEffect(() => {
    const handler = e => { if (e.key === 'Escape') onClose(); };
    document.addEventListener('keydown', handler);
    return () => document.removeEventListener('keydown', handler);
  }, [onClose]);

  // Portal direto no document.body — evita que transform/overflow do pai quebre o fixed
  const modalContent = (
    <div onClick={onClose} style={{
      position: 'fixed', inset: 0,
      background: 'rgba(0,0,0,0.65)',
      display: 'flex', alignItems: 'center', justifyContent: 'center',
      zIndex: 9999, padding: 16,
    }}>
      <div onClick={e => e.stopPropagation()} style={{
        background: '#ffffff',
        borderRadius: 8,
        maxWidth: 420, width: '100%',
        maxHeight: '82vh', overflowY: 'auto',
        boxShadow: '0 8px 40px rgba(0,0,0,0.45)',
        border: '1px solid var(--pg-rule)',
      }}>
        {/* cabeçalho fixo */}
        <div style={{
          display: 'flex', alignItems: 'center', justifyContent: 'space-between',
          padding: '12px 16px',
          borderBottom: '1px solid var(--pg-rule)',
          position: 'sticky', top: 0, zIndex: 1,
          background: '#ffffff',
        }}>
          <div>
            <div style={{ fontSize: 9, color: 'var(--pg-gray-2)', letterSpacing: '0.1em',
              textTransform: 'uppercase', marginBottom: 3 }}>
              🛒 Comprar no Mercado Livre
            </div>
            <div style={{ fontSize: 14, fontWeight: 700, color: 'var(--pg-ink)' }}>{name}</div>
          </div>
          <button onClick={onClose} style={{
            background: 'none', border: 'none', cursor: 'pointer',
            fontSize: 20, color: 'var(--pg-gray-2)', lineHeight: 1, padding: '4px 6px',
          }} title="Fechar">✕</button>
        </div>

        {/* lista de itens */}
        <div>
          {sorted.map((item) => {
            const displayTitle = item.title;
            const price        = fmtBRL(item.price);
            const unavailable  = item.available === false;
            return (
              <div key={item.item_id} style={{
                display: 'flex', gap: 12, padding: '12px 16px',
                borderBottom: '1px solid var(--pg-rule)',
                opacity: unavailable ? 0.45 : 1,
              }}>
                {/* thumbnail */}
                <div style={{
                  width: 64, height: 64, flexShrink: 0,
                  borderRadius: 6, overflow: 'hidden',
                  background: 'var(--pg-bg)',
                  display: 'flex', alignItems: 'center', justifyContent: 'center',
                }}>
                  {item.thumbnail
                    ? <img src={item.thumbnail} alt="" style={{ width: '100%', height: '100%', objectFit: 'contain' }} />
                    : <span style={{ fontSize: 22, opacity: 0.4 }}>🔧</span>
                  }
                </div>

                {/* info */}
                <div style={{ flex: 1, minWidth: 0, display: 'flex', flexDirection: 'column', gap: 4 }}>
                  <div style={{
                    fontSize: 11, color: 'var(--pg-ink)', lineHeight: 1.4,
                    overflow: 'hidden', display: '-webkit-box',
                    WebkitLineClamp: 2, WebkitBoxOrient: 'vertical',
                  }}>
                    {displayTitle}
                  </div>
                  <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 8, marginTop: 'auto' }}>
                    <div style={{ minWidth: 0 }}>
                      {price
                        ? <span style={{ fontSize: 16, fontWeight: 700, fontFamily: 'var(--font-mono)', color: 'var(--pg-gold-deep)' }}>{price}</span>
                        : <span style={{ fontSize: 10, color: 'var(--pg-gray-2)' }}>preço indisponível</span>
                      }
                      {unavailable && (
                        <div style={{ fontSize: 9, color: '#e55', marginTop: 1 }}>sem estoque</div>
                      )}
                    </div>
                    <a href={item.aff_url} target="_blank" rel="noopener noreferrer sponsored"
                      onClick={onClose}
                      style={{
                        background: unavailable ? '#888' : 'var(--pg-accent)',
                        color: '#fff',
                        borderRadius: 5, padding: '6px 12px',
                        textDecoration: 'none', fontSize: 12, fontWeight: 700,
                        whiteSpace: 'nowrap', flexShrink: 0,
                        lineHeight: 1.3,
                      }}>
                      Ver oferta ↗
                    </a>
                  </div>
                </div>
              </div>
            );
          })}
        </div>

        {/* rodapé */}
        <div style={{ padding: '8px 16px 14px', fontSize: 9, color: 'var(--pg-gray-2)', lineHeight: 1.5 }}>
          * Links de parceiro — se comprar através deles, ajuda a manter o canal sem custo extra pra você.
          {priceDate ? `Preços atualizados em ${priceDate}.` : 'Preços atualizados periodicamente.'}
        </div>
      </div>
    </div>
  );
  return ReactDOM.createPortal(modalContent, document.body);
}


// ============================================================
// VIDEO PAGE — individual video view
// ============================================================
function VideoPage({ video, allVideos, onBack, onOpen, onOpenCar }) {
  if (!video) return null;

  // Relacionados: (mesmo carro + mesmo tópico) > mesmo carro > mesmo tópico > resto
  // Prioridade intersection garante que vídeo de pintura mostre outros de pintura antes
  // de vídeos genéricos do mesmo carro.
  const related = (() => {
    const pool       = allVideos.filter(v => v.id !== video.id);
    const byCar      = pool.filter(v => video.car && v.car === video.car);
    const byTopic    = pool.filter(v => video.topics && v.topics && v.topics.some(t => (video.topics||[]).includes(t)));
    const byTopicSet = new Set(byTopic.map(v => v.id));
    const byCarSet   = new Set(byCar.map(v => v.id));
    const both       = byCar.filter(v => byTopicSet.has(v.id));
    const carOnly    = byCar.filter(v => !byTopicSet.has(v.id));
    const topicOnly  = byTopic.filter(v => !byCarSet.has(v.id));
    const seen = new Set();
    const out  = [];
    for (const v of [...both, ...carOnly, ...topicOnly, ...pool]) {
      if (!seen.has(v.id)) { seen.add(v.id); out.push(v); }
      if (out.length === 10) break;
    }
    return out;
  })();

  // Série: outros episódios da mesma série
  const seriesVideos = video.isSeries && video.seriesName
    ? allVideos
        .filter(v => v.id !== video.id && v.seriesName === video.seriesName)
        .sort((a, b) => (a.seriesPart || 0) - (b.seriesPart || 0))
    : [];

  // Descrição: summaryCard como principal; se muito curto (<80 chars), usa a descrição original do YouTube
  const rawSummary = video.summaryCard || '';
  const rawDescription = (video.description || '').split('\n')[0].trim(); // só primeiro parágrafo
  const description = rawSummary.length >= 80
    ? rawSummary
    : rawSummary
      ? rawSummary + (rawDescription && rawDescription !== rawSummary ? ' ' + rawDescription : '')
      : rawDescription;

  // helper — cabeçalho de seção da sidebar
  const SideH = ({children}) => (
    <div style={{fontSize:10,fontWeight:700,letterSpacing:'0.14em',textTransform:'uppercase',
      borderBottom:'1.5px solid var(--pg-black)',paddingBottom:4,marginBottom:10,marginTop:18}}>
      {children}
    </div>
  );

  // helper — formata torque para exibição
  const fmtTorque = (t) => {
    if (t.display) return t.display;
    const comp = t.component && t.component !== 'desconhecido' ? ` — ${t.component}` : '';
    return `${t.value_nm} kgf·m${comp}`;
  };
  const isLowConf = (t) => t.confidence === 'low' || t.confidence === 'medium_low';

  // formata segundos → M:SS, MM:SS ou H:MM:SS
  const fmtTs = (s) => {
    const h = Math.floor(s / 3600);
    const m = Math.floor((s % 3600) / 60);
    const sec = s % 60;
    if (h > 0) return `${h}:${String(m).padStart(2,'0')}:${String(sec).padStart(2,'0')}`;
    return `${m}:${String(sec).padStart(2,'0')}`;
  };

  // dados técnicos curados
  const torques = (video.curatedTorqueSpecs || []).filter(t => t.display || t.value_nm);

  // jump points — tool/part mentions merged into Dados Técnicos (dedup by nome)
  const jumpPoints = video.jumpPoints || [];
  const jpToolItems = jumpPoints
    .filter(jp => jp.t === 'tool_mention' && jp.l)
    .map(jp => ({name: jp.l, timestamp_s: jp.s}));
  const jpPartItems = jumpPoints
    .filter(jp => jp.t === 'part_mention' && jp.l)
    .map(jp => ({name: jp.l, timestamp_s: jp.s}));

  const _mergeByName = (curated, extras) => {
    const seen = new Set(curated.map(x => (x.name || x).toLowerCase().trim()));
    return [...curated, ...extras.filter(x => !seen.has((x.name || x).toLowerCase().trim()))];
  };
  const tools    = _mergeByName(video.curatedTools || [], jpToolItems);
  const replaced = _mergeByName(video.curatedPartsReplaced || [], jpPartItems);
  const hasTechData = torques.length || tools.length || replaced.length;

  // estado para "ver mais" nas listas de peças e ferramentas
  const TECH_LIMIT = 5;
  const [showAllParts, setShowAllParts] = React.useState(false);
  const [showAllTools, setShowAllTools] = React.useState(false);
  // modal de afiliados ML
  const [affModal, setAffModal] = React.useState(null); // {name, group:[{item_id,aff_url,title}]}
  return (
    <div className="video-page">
      <div style={{padding:'10px 18px 0'}}>
        <a className="back-link" href="#" onClick={(e)=>{e.preventDefault();onBack();}}>
          ◂ VOLTAR AO PORTAL
        </a>
      </div>

      {/* ── grid principal: player + sidebar ── */}
      <div className="video-page__body">

        {/* coluna esquerda: player + título + tags + descrição */}
        <div>
          <div className="video-page__player">
            <iframe
              src={`https://www.youtube.com/embed/${video.id}?rel=0`}
              title={video.title}
              allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
              allowFullScreen
            />
          </div>
          <h1 className="video-page__title">{video.title}</h1>

          <div className="video-page__tags">
            {(video.topics||[]).slice(0,1).map(t => (
              <span key={t} className="tag-chip">{t.toUpperCase()}</span>
            ))}
            {video.type && TYPE_LABEL[video.type] && (
              <span className="tag-chip">{TYPE_LABEL[video.type]}</span>
            )}
            {video.carId && video.car && onOpenCar && (
              <span
                className="tag-chip tag-chip--car"
                style={{cursor:'pointer',borderColor:'var(--pg-gold)',color:'var(--pg-gold-deep)'}}
                onClick={() => {
                  const carObj = ((window.__PG_DATA__||{}).cars||[]).find(c => c.id === video.carId);
                  if (carObj) onOpenCar(carObj);
                }}
                title={`Ver todos os vídeos do ${video.car}`}
              >
                🚗 {video.carModel || video.car}
              </span>
            )}
            <span className="tag-chip">DURAÇÃO {video.duration}</span>
            <span className="tag-chip">{fmtViews(video.views)} VIEWS</span>
            <span className="tag-chip">{fmtDate(video.date)}</span>
            {video.isSeries && video.seriesPart && (
              <span className="tag-chip tag-chip--series"
                style={{borderColor:'var(--pg-accent)',color:'var(--pg-accent)'}}>
                📺 PARTE {video.seriesPart}{video.seriesTotal ? ` DE ${video.seriesTotal}` : ''}
              </span>
            )}
          </div>

          {description && (
            <div style={{marginTop:14}}>
              <div style={{fontSize:10,fontWeight:700,letterSpacing:'0.14em',textTransform:'uppercase',
                borderBottom:'1px solid var(--pg-rule)',paddingBottom:3,marginBottom:8}}>
                Sobre este vídeo
              </div>
              <p style={{marginTop:6,fontSize:13.5,lineHeight:1.6}}>{description}</p>
            </div>
          )}
        </div>

        {/* ── sidebar direita: dados técnicos + série ── */}
        <aside className="video-side">

          {/* dados técnicos curados */}
          {!hasTechData && (
            <div style={{
              marginBottom:16, padding:'14px 12px',
              border:'1px dashed var(--pg-rule)',
              textAlign:'center', color:'var(--pg-gray-2)',
            }}>
              <div style={{fontSize:22,marginBottom:6}}>🔩</div>
              <div style={{fontSize:11,fontWeight:700,letterSpacing:'0.1em',textTransform:'uppercase',marginBottom:4}}>
                Sem dados técnicos
              </div>
              <div style={{fontSize:11,lineHeight:1.5}}>
                Nenhuma ferramenta, peça ou torque identificado neste vídeo.
              </div>
            </div>
          )}
          {!!hasTechData && (
            <div>
              <div style={{display:'flex',alignItems:'center',justifyContent:'space-between',
                borderBottom:'1.5px solid var(--pg-gold)',paddingBottom:5,marginBottom:12}}>
                <span style={{fontSize:10,fontWeight:700,letterSpacing:'0.14em',textTransform:'uppercase',
                  color:'var(--pg-gold-deep)'}}>⚙ Dados Técnicos</span>
                <span style={{fontSize:9,fontFamily:'var(--font-mono)',color:'var(--pg-gray-2)',
                  background:'var(--pg-bg)',padding:'1px 6px',border:'1px solid var(--pg-rule)'}}>
                  CURADO
                </span>
              </div>

              {/* torques — destaque máximo */}
              {torques.length > 0 && (
                <div style={{marginBottom:14}}>
                  <div style={{fontSize:9,fontWeight:700,letterSpacing:'0.12em',textTransform:'uppercase',
                    color:'var(--pg-gray-2)',marginBottom:7}}>🔩 TORQUES</div>
                  <div style={{display:'flex',flexDirection:'column',gap:6}}>
                    {torques.map((t, i) => {
                      const comp = t.component && t.component !== 'desconhecido' ? t.component : null;
                      const val  = t.display || (t.value_nm ? `${Math.round(parseFloat(t.value_nm))} N·m` : null);
                      const tsUrl = t.timestamp_s != null
                        ? `https://www.youtube.com/watch?v=${video.id}&t=${t.timestamp_s}s`
                        : null;
                      const tsFmt = t.timestamp_s != null ? fmtTs(t.timestamp_s) : null;
                      return (
                        <div key={i} style={{
                          background: isLowConf(t) ? 'var(--pg-bg)' : '#fff8e6',
                          border:`1px solid ${isLowConf(t) ? 'var(--pg-rule)' : 'var(--pg-gold)'}`,
                          borderLeft:`3px solid ${isLowConf(t) ? 'var(--pg-rule)' : 'var(--pg-gold)'}`,
                          padding:'7px 10px',
                          opacity: isLowConf(t) ? 0.75 : 1,
                        }}>
                          {/* componente — para o que é esse torque */}
                          {comp && (
                            <div style={{fontSize:11,color:'var(--pg-ink)',marginBottom:3,lineHeight:1.3}}>
                              {comp}
                            </div>
                          )}
                          {/* valor + timestamp */}
                          <div style={{display:'flex',alignItems:'baseline',gap:8,flexWrap:'wrap'}}>
                            <span style={{fontWeight:700,fontFamily:'var(--font-mono)',fontSize:13,
                              color:'var(--pg-gold-deep)'}}>
                              {val}
                            </span>
                            {isLowConf(t) && (
                              <span style={{fontSize:9,color:'var(--pg-gray-2)'}}>⚠ verificar</span>
                            )}
                            {tsUrl && (
                              <a href={tsUrl} target="_blank" rel="noopener noreferrer"
                                style={{fontSize:10,color:'var(--pg-accent)',fontFamily:'var(--font-mono)',
                                  textDecoration:'none',marginLeft:'auto'}}>
                                ▶ {tsFmt}
                              </a>
                            )}
                          </div>
                          {/* nota opcional */}
                          {t.note && (
                            <div style={{fontSize:10,color:'var(--pg-gray-2)',marginTop:3,fontStyle:'italic',
                              lineHeight:1.35}}>
                              {t.note}
                            </div>
                          )}
                        </div>
                      );
                    })}
                  </div>
                </div>
              )}

              {/* peças substituídas */}
              {replaced.length > 0 && (
                <div style={{marginBottom:14}}>
                  <div style={{fontSize:9,fontWeight:700,letterSpacing:'0.12em',textTransform:'uppercase',
                    color:'var(--pg-gray-2)',marginBottom:7}}>⚙ PEÇAS SUBSTITUÍDAS</div>
                  <div style={{display:'flex',flexDirection:'column',gap:0}}>
                    {(showAllParts ? replaced : replaced.slice(0, TECH_LIMIT)).map((p, i) => {
                      const name = p.name || p;
                      const tsUrl = p.timestamp_s != null
                        ? `https://www.youtube.com/watch?v=${video.id}&t=${p.timestamp_s}s`
                        : null;
                      const tsFmt = p.timestamp_s != null ? fmtTs(p.timestamp_s) : null;
                      return (
                        <div key={i} style={{
                          display:'flex', alignItems:'baseline', justifyContent:'space-between',
                          gap:6, padding:'5px 0',
                          borderBottom:'1px solid var(--pg-rule)',
                        }}>
                          <span style={{fontSize:12,color:'var(--pg-ink)',lineHeight:1.35,
                            minWidth:0,flex:'1 1 0',wordBreak:'break-word'}}>
                            → {name}
                          </span>
                          {tsUrl && (
                            <a href={tsUrl} target="_blank" rel="noopener noreferrer"
                              style={{fontSize:10,fontFamily:'var(--font-mono)',color:'var(--pg-accent)',
                                textDecoration:'none',whiteSpace:'nowrap',flexShrink:0}}
                              title={`Ver no vídeo em ${tsFmt}`}>
                              ▶ {tsFmt}
                            </a>
                          )}
                        </div>
                      );
                    })}
                  </div>
                  {replaced.length > TECH_LIMIT && (
                    <button onClick={() => setShowAllParts(v => !v)}
                      style={{marginTop:6,fontSize:10,color:'var(--pg-accent)',background:'none',
                        border:'none',cursor:'pointer',padding:'2px 0',fontFamily:'var(--font-mono)'}}>
                      {showAllParts ? '▲ ver menos' : `▼ ver mais ${replaced.length - TECH_LIMIT} itens`}
                    </button>
                  )}
                </div>
              )}

              {/* ferramentas */}
              {tools.length > 0 && (
                <div style={{marginBottom:6}}>
                  <div style={{fontSize:9,fontWeight:700,letterSpacing:'0.12em',textTransform:'uppercase',
                    color:'var(--pg-gray-2)',marginBottom:7}}>🔧 FERRAMENTAS</div>
                  <div style={{display:'flex',flexDirection:'column',gap:0}}>
                    {(showAllTools ? tools : tools.slice(0, TECH_LIMIT)).map((t, i) => {
                      const name = t.name || t;
                      const tsUrl = t.timestamp_s != null
                        ? `https://www.youtube.com/watch?v=${video.id}&t=${t.timestamp_s}s`
                        : null;
                      const tsFmt = t.timestamp_s != null ? fmtTs(t.timestamp_s) : null;
                      return (
                        <div key={i} style={{
                          display:'flex', alignItems:'baseline', justifyContent:'space-between',
                          gap:6, padding:'5px 0',
                          borderBottom:'1px solid var(--pg-rule)',
                        }}>
                          <span style={{fontSize:12,color:'var(--pg-ink)',lineHeight:1.35,
                            minWidth:0,flex:'1 1 0',wordBreak:'break-word'}}>
                            → {name}
                          </span>
                          <span style={{display:'flex',gap:6,alignItems:'baseline',flexShrink:0}}>
                            {t.affiliateGroup ? (
                              <button
                                onClick={() => setAffModal({ name, group: t.affiliateGroup })}
                                style={{fontSize:10,color:'#fff',background:'var(--pg-accent)',
                                  borderRadius:3,padding:'1px 5px',border:'none',cursor:'pointer',
                                  whiteSpace:'nowrap',lineHeight:1.6,fontFamily:'inherit'}}
                                title="Ver opções no Mercado Livre">
                                🛒 ML ↗
                              </button>
                            ) : t.affiliateUrl ? (
                              <a href={t.affiliateUrl} target="_blank" rel="noopener noreferrer sponsored"
                                style={{fontSize:10,color:'#fff',background:'var(--pg-accent)',
                                  borderRadius:3,padding:'1px 5px',textDecoration:'none',
                                  whiteSpace:'nowrap',lineHeight:1.6}}
                                title="Ver no Mercado Livre">
                                ML ↗
                              </a>
                            ) : null}
                            {tsUrl && (
                              <a href={tsUrl} target="_blank" rel="noopener noreferrer"
                                style={{fontSize:10,fontFamily:'var(--font-mono)',color:'var(--pg-accent)',
                                  textDecoration:'none',whiteSpace:'nowrap'}}
                                title={`Ver no vídeo em ${tsFmt}`}>
                                ▶ {tsFmt}
                              </a>
                            )}
                          </span>
                        </div>
                      );
                    })}
                  </div>
                  {tools.length > TECH_LIMIT && (
                    <button onClick={() => setShowAllTools(v => !v)}
                      style={{marginTop:6,fontSize:10,color:'var(--pg-accent)',background:'none',
                        border:'none',cursor:'pointer',padding:'2px 0',fontFamily:'var(--font-mono)'}}>
                      {showAllTools ? '▲ ver menos' : `▼ ver mais ${tools.length - TECH_LIMIT} itens`}
                    </button>
                  )}
                </div>
              )}
            </div>
          )}

          {/* notas do procedimento */}
          {video.procedureNotes && (
            <div style={{
              marginTop:!!hasTechData ? 14 : 0,
              marginBottom:16,
              padding:'9px 11px',
              background:'var(--pg-bg)',
              border:'1px solid var(--pg-rule)',
              borderLeft:'3px solid var(--pg-gold)',
            }}>
              <div style={{fontSize:9,fontWeight:700,letterSpacing:'0.12em',textTransform:'uppercase',
                color:'var(--pg-gray-2)',marginBottom:5}}>📋 NOTAS DO PROCEDIMENTO</div>
              <p style={{fontSize:11.5,lineHeight:1.6,color:'var(--pg-ink)',margin:0}}>
                {video.procedureNotes}
              </p>
            </div>
          )}

          {/* série */}
          {seriesVideos.length > 0 && (
            <div style={{marginTop: hasTechData ? 20 : 0}}>
              <SideH>📺 Série: {video.seriesName}</SideH>
              <div className="related-list">
                {seriesVideos.slice(0, 5).map(v => (
                  <div key={v.id} className="card-row" onClick={()=>onOpen(v)}
                    style={v.seriesPart === video.seriesPart ? {opacity:0.5,pointerEvents:'none'} : {}}>
                    <div className="thumb" style={{width:72}}>
                      <img src={ytThumb(v.id)} alt="" loading="lazy" />
                      <div className="duration">{v.duration}</div>
                    </div>
                    <div>
                      <div className="card-row__title" style={{fontSize:11}}>
                        {v.seriesPart && <span style={{fontFamily:'var(--font-mono)',fontSize:9,
                          color:'var(--pg-gray-2)',marginRight:5}}>EP {v.seriesPart}</span>}
                        {v.title}
                      </div>
                      <div className="card-row__meta">{fmtViews(v.views)} views</div>
                    </div>
                  </div>
                ))}
              </div>
            </div>
          )}
        </aside>
      </div>

      {/* ── carrossel de relacionados — largura total, abaixo do player ── */}
      {related.length > 0 && (
        <div className="vp-carousel-section">
          <div className="vp-carousel-header">Vídeos relacionados</div>
          <div className="vp-carousel">
            {related.map(v => (
              <div key={v.id} className="vp-carousel__card" onClick={()=>onOpen(v)}>
                <div className="vp-carousel__thumb">
                  <img src={ytThumb(v.id)} alt="" loading="lazy" />
                  <div className="vp-carousel__dur">{v.duration}</div>
                </div>
                <div className="vp-carousel__info">
                  <div className="vp-carousel__title">{v.title}</div>
                  <div className="vp-carousel__meta">{fmtViews(v.views)} views · {fmtDate(v.date)}</div>
                </div>
              </div>
            ))}
          </div>
        </div>
      )}

      {/* modal de opções de afiliado */}
      {affModal && (
        <AffiliateModal
          name={affModal.name}
          group={affModal.group}
          onClose={() => setAffModal(null)}
        />
      )}

    </div>
  );
}

// ============================================================
// HOME (main page with panels)
// ============================================================
function Home({ data, onOpen, onOpenCar, onOpenTopic, onSearch, heroLayout, forcedPanel, tuchoQuery }) {
  const [expanded, setExpanded] = React.useState(forcedPanel || 'cars');  // 'cars' | 'topics' | 'tucho' | null
  const [activeTopic, setActiveTopic] = React.useState('motor');

  React.useEffect(() => {
    if (forcedPanel) setExpanded(forcedPanel);
  }, [forcedPanel]); // só dispara quando forcedPanel muda, não quando expanded muda

  const panelsCls = 'panels ' + (expanded ? ('expanded-' + expanded) : '');

  const panelsBlock = (
    <>
      <div className="section-head">
        <h2>▸ Escolha sua jornada</h2>
        <span className="tag">3 CAMINHOS</span>
        <span className="sub">clique num painel para expandir · <span className="kbd">1</span> <span className="kbd">2</span> <span className="kbd">3</span> atalhos</span>
      </div>
      <div className={panelsCls}>
        <div
          className={'panel' + (expanded === 'cars' ? ' is-expanded' : ' is-collapsed')}
          onClick={() => setExpanded('cars')}
        >
          <CarsPanel
            expanded={expanded === 'cars'}
            onCar={onOpenCar}
          />
        </div>
        <div
          className={'panel' + (expanded === 'topics' ? ' is-expanded' : ' is-collapsed')}
          onClick={() => setExpanded('topics')}
        >
          <TopicsPanel
            expanded={expanded === 'topics'}
            activeTopic={activeTopic}
            setActiveTopic={setActiveTopic}
            topicVideos={data.byTopic}
            onOpen={onOpen}
            onOpenTopic={onOpenTopic}
          />
        </div>
        <div
          className={'panel tucho' + (expanded === 'tucho' ? ' is-expanded' : ' is-collapsed')}
          onClick={() => setExpanded('tucho')}
        >
          <TuchoPanel
            expanded={expanded === 'tucho'}
            allVideos={[...data.top, ...data.recent, ...Object.values(data.byTopic).flat()]}
            onOpen={onOpen}
            onSearch={onSearch}
            initialQuery={tuchoQuery}
          />
        </div>
      </div>
    </>
  );

  // SIDEBAR layout: jornada à esquerda (~70%), lateral reservada à direita (~30%).
  // #1 (rev. 15): cabeçalho "Portal de Conhecimento" removido.
  // #2 (rev. 15): Últimos/Mais vistos movidos para baixo da jornada;
  //   coluna lateral reservada para conteúdo interativo futuro.
  if (heroLayout === 'sidebar') {
    return (
      <div className="page">
        <div className="hero-sidebar-layout">
          <div className="hero-sidebar-layout__main">
            {panelsBlock}
          </div>
          <div className="hero-sidebar-layout__aside">
            <div className="aside-reserved">
              <span className="aside-reserved__tag">EM BREVE</span>
              <p className="aside-reserved__text">Espaço reservado para novidades interativas.</p>
            </div>
          </div>
        </div>
        <HeroSidebarList recent={data.recent} top={data.top} onOpen={onOpen} horizontal />
        <StatStrip />
      </div>
    );
  }

  // default / strip / carousel layouts: hero em cima, jornada embaixo
  return (
    <div className="page">
      <div className="section-head">
        <h2>Portal de Conhecimento</h2>
        <span className="tag">v1.0 · DIY</span>
        <span className="sub">
          atualizado {fmtDate(data.channel.lastVideoAt)} · {data.channel.recentVideoCount} vídeos nos últimos 30 dias
        </span>
      </div>

      {heroLayout === 'strip'
        ? <HeroStrip recent={data.recent} top={data.top} onOpen={onOpen} />
        : <HeroSection recent={data.recent} top={data.top} onOpen={onOpen} />}

      {panelsBlock}

      <StatStrip />

      <div className="section-head">
        <h2>▸ Por carro — navegação rápida</h2>
        <span className="tag">6 MODELOS</span>
        <span className="sub">todos populares · manutenção DIY acessível</span>
      </div>

      <div className="cargrid" style={{gridTemplateColumns:'repeat(6, 1fr)', gap: 12, marginBottom: 28}}>
        {CARS.map(c => (
          <div key={c.id} className="carcard" onClick={() => onOpenCar && onOpenCar(c)}>
            <div className="carcard__img">
              <img src={`assets/cars/${c.id}.png`} alt={c.name} loading="lazy" />
            </div>
            <div className="carcard__body">
              <div className="carcard__name">{c.name}</div>
              <div className="carcard__spec">{c.spec}</div>
              <div className="carcard__count"><span className="n">{c.count}</span> vídeos</div>
            </div>
          </div>
        ))}
      </div>
    </div>
  );
}

// ============================================================
// ABOUT PAGE — helper de estatísticas reais
// ============================================================
function AboutStats() {
  const ch = (window.__PG_DATA__ || {}).channel || {};
  const totalVideos   = ch.totalVideos     || 766;
  const totalViews    = ch.totalViews      || 0;
  const contentHours  = ch.totalContentHours || 191;

  function fmtMi(n) {
    if (!n) return '—';
    return (n / 1_000_000).toFixed(1).replace('.', ',') + ' mi';
  }

  // Anos de canal: do primeiro vídeo (2015) ao último registrado
  const lastYear = ch.lastVideoAt ? ch.lastVideoAt.slice(0, 4) : '2026';
  const yearsActive = parseInt(lastYear) - 2015 + 1;

  return (
    <div className="about-stats">
      <div className="about-stat">
        <div className="about-stat__val">{totalVideos}</div>
        <div className="about-stat__label">Vídeos publicados</div>
      </div>
      <div className="about-stat">
        <div className="about-stat__val">{fmtMi(totalViews)}</div>
        <div className="about-stat__label">Views acumuladas</div>
      </div>
      <div className="about-stat">
        {/* Inscritos: atualizar manualmente quando disponível */}
        <div className="about-stat__val">47<span>k+</span></div>
        <div className="about-stat__label">Inscritos</div>
      </div>
      <div className="about-stat">
        <div className="about-stat__val">{contentHours}<span>h</span></div>
        <div className="about-stat__label">De conteúdo técnico</div>
      </div>
      <div className="about-stat">
        <div className="about-stat__val">{yearsActive}</div>
        <div className="about-stat__label">Anos de canal</div>
      </div>
      <div className="about-stat">
        <div className="about-stat__val">6</div>
        <div className="about-stat__label">Carros documentados</div>
      </div>
    </div>
  );
}

function AboutPage() {
  const totalVideos = ((window.__PG_DATA__ || {}).channel || {}).totalVideos || 766;
  return (
    <div className="page about-page">

      {/* ── HERO ── */}
      <div className="about-hero">
        <div className="about-hero__eyebrow">▸ SOBRE O CANAL</div>
        <h1 className="about-hero__title">Faça você mesmo.<br/>De verdade.</h1>
        <p className="about-hero__sub">
          Paulo's Garage é um canal de mecânica DIY criado para quem quer colocar
          a mão na graxa, aprender o procedimento correto e não depender de oficina
          para tudo. Desde 2015, sem cortar caminho na informação.
        </p>
      </div>

      {/* ── HISTÓRIA ── */}
      <div className="section-head" style={{marginTop: 36}}>
        <h2>▸ A história</h2>
        <span className="tag">COMO COMEÇOU</span>
      </div>
      <div className="about-grid">
        <div className="about-block">
          <div className="about-block__num">01</div>
          <h3 className="about-block__title">O problema</h3>
          <p className="about-block__text">
            Quem tenta aprender mecânica de forma independente esbarra sempre no mesmo
            muro: informação fragmentada, desatualizada ou simplesmente errada.
            Fóruns de época, grupos, manuais técnicos — tudo espalhado e difícil de
            cruzar com a realidade do carro brasileiro popular.
          </p>
        </div>
        <div className="about-block">
          <div className="about-block__num">02</div>
          <h3 className="about-block__title">A solução</h3>
          <p className="about-block__text">
            Começou como um blog, mas ficou claro rápido que vídeo era o formato certo
            — dá pra mostrar o parafuso escondido, o torque exato, a mão na peça.
            O canal nasceu disso: documentar as próprias manutenções com o nível de
            detalhe que eu gostaria de ter encontrado quando estava aprendendo.
          </p>
        </div>
        <div className="about-block">
          <div className="about-block__num">03</div>
          <h3 className="about-block__title">A filosofia</h3>
          <p className="about-block__text">
            Sou entusiasta, aprendi na prática — lendo manual, pesquisando fórum,
            errando e corrigindo. Não tenho formação formal em mecânica automotiva.
            Exatamente por isso a régua é alta: informação técnica correta, procedimento
            completo, sem atalho e sem achismo. Tem muita informação ruim na internet.
            Aqui não.
          </p>
        </div>
      </div>

      {/* ── OS CARROS ── */}
      <div className="section-head" style={{marginTop: 36}}>
        <h2>▸ Os carros</h2>
        <span className="tag">6 MODELOS</span>
        <span className="sub">cada um com seu propósito</span>
      </div>
      <p className="about-text">
        Cada carro do canal existe por uma razão — seja pelo desafio mecânico, pela
        utilidade prática ou pelo valor histórico. O limite é espaço físico, não
        falta de vontade. De uma Brasília de 1979 a um CR-V de 2009, os procedimentos
        mostrados cobrem desde mecânica simples e acessível até manutenções mais
        elaboradas que a maioria evita levar para oficina.
      </p>
      <div className="about-cars">
        {CARS.map(c => (
          <div key={c.id} className="about-car">
            <img src={`assets/cars/${c.id}.png`} alt={c.name} />
            <div className="about-car__name">{c.name}</div>
            <div className="about-car__spec">{c.spec}</div>
          </div>
        ))}
      </div>

      {/* ── TUCHO ── */}
      <div className="section-head" style={{marginTop: 36}}>
        <h2>▸ O TUCHO</h2>
        <span className="tag">IA · ASSISTENTE</span>
      </div>
      <div className="about-tucho">
        <div className="about-tucho__img">
          <img src="assets/tucho/normal.png" alt="TUCHO" />
        </div>
        <div className="about-tucho__text">
          <h3>Um nome que vem da oficina</h3>
          <p>
            O nome TUCHO surgiu durante a retífica do motor da S10 — o tucho
            hidráulico é aquele componente que a maioria conhece pelo barulho
            característico quando o óleo demora a chegar, mas que poucos sabem
            exatamente o que faz. Um item comum, técnico e com nome quase engraçado.
            Perfeito para o assistente de busca do canal.
          </p>
          <p>
            O TUCHO vasculha o acervo de {totalVideos} vídeos e transcrições para encontrar
            o procedimento certo para o seu problema. Descreve o sintoma em português
            comum — ele entende de mecânica.
          </p>
          <a className="about-tucho__cta" href="#" onClick={(e)=>{e.preventDefault(); window.__goTucho && window.__goTucho();}}>
            Perguntar ao TUCHO ▸
          </a>
        </div>
      </div>

      {/* ── NÚMEROS ── */}
      <div className="section-head" style={{marginTop: 36}}>
        <h2>▸ O canal em números</h2>
        <span className="tag">DESDE 2015</span>
      </div>
      <AboutStats />

      {/* ── CONTATO / REDES ── */}
      <div className="section-head" style={{marginTop: 36}}>
        <h2>▸ Redes e contato</h2>
        <span className="tag">SIGA O CANAL</span>
      </div>
      <div className="about-social">
        <a className="about-social__card" href="https://youtube.com/PaulosGarage" target="_blank" rel="noopener">
          <svg viewBox="0 0 24 24" width="28" height="20" fill="#FF0000"><path d="M23 7s-.3-2-1.2-2.8c-1.1-1.2-2.4-1.2-3-1.3C16.2 3 12 3 12 3s-4.2 0-6.8.2c-.6.1-1.9.1-3 1.3C1.3 5 1 7 1 7S.7 9.1.7 11.3v2c0 2.1.3 4.2.3 4.2s.3 2 1.2 2.8c1.1 1.2 2.6 1.1 3.3 1.2C7.2 21.7 12 21.7 12 21.7s4.2 0 6.8-.3c.6-.1 1.9-.1 3-1.3.9-.8 1.2-2.8 1.2-2.8s.3-2.1.3-4.2v-2C23.3 9.1 23 7 23 7zM9.7 15.5V8.4l8.1 3.6-8.1 3.5z"/></svg>
          <div>
            <div className="about-social__name">YouTube</div>
            <div className="about-social__handle">youtube.com/PaulosGarage</div>
          </div>
        </a>
        <a className="about-social__card" href="https://instagram.com/PaulosGarageBR" target="_blank" rel="noopener">
          <svg viewBox="0 0 24 24" width="24" height="24" fill="currentColor"><path d="M12 2.2c3.2 0 3.6 0 4.9.1 3.3.2 4.8 1.7 5 5 .1 1.3.1 1.6.1 4.8s0 3.6-.1 4.8c-.2 3.3-1.7 4.8-5 5-1.3.1-1.6.1-4.9.1s-3.6 0-4.8-.1c-3.3-.2-4.8-1.7-5-5C2 16.6 2 16.3 2 12s0-3.6.1-4.8c.2-3.3 1.7-4.8 5-5C8.4 2.2 8.8 2.2 12 2.2zm0 1.8c-3.2 0-3.5 0-4.7.1-2.3.1-3.3 1.1-3.4 3.4C3.8 8.7 3.8 9 3.8 12s0 3.3.1 4.5c.1 2.3 1.1 3.3 3.4 3.4 1.2.1 1.5.1 4.7.1s3.5 0 4.7-.1c2.3-.1 3.3-1.1 3.4-3.4.1-1.2.1-1.5.1-4.5s0-3.3-.1-4.5c-.1-2.3-1.1-3.3-3.4-3.4-1.2-.1-1.5-.1-4.7-.1zM12 7a5 5 0 1 1 0 10A5 5 0 0 1 12 7zm0 1.8a3.2 3.2 0 1 0 0 6.4 3.2 3.2 0 0 0 0-6.4zM17.2 5.8a1.2 1.2 0 1 1 0 2.4 1.2 1.2 0 0 1 0-2.4z"/></svg>
          <div>
            <div className="about-social__name">Instagram</div>
            <div className="about-social__handle">@PaulosGarageBR</div>
          </div>
        </a>
        <a className="about-social__card" href="https://tiktok.com/@PaulosGarageBR" target="_blank" rel="noopener">
          <svg viewBox="0 0 24 24" width="22" height="24" fill="currentColor"><path d="M19.6 3h-3.2v12.1a2.8 2.8 0 1 1-2.7-3 3 3 0 0 1 .9.1V8.9a6.2 6.2 0 0 0-.9-.1A6.1 6.1 0 1 0 19.8 15V8.6a9.3 9.3 0 0 0 5.4 1.7V7.1a5.6 5.6 0 0 1-5.6-4.1z"/></svg>
          <div>
            <div className="about-social__name">TikTok</div>
            <div className="about-social__handle">@PaulosGarageBR</div>
          </div>
        </a>
        <a className="about-social__card about-social__card--email" href="mailto:paulosgarage@gmail.com">
          <svg viewBox="0 0 24 24" width="24" height="24" fill="none" stroke="currentColor" strokeWidth="1.8"><rect x="2" y="4" width="20" height="16" rx="2"/><path d="M2 7l10 7 10-7"/></svg>
          <div>
            <div className="about-social__name">E-mail</div>
            <div className="about-social__handle">paulosgarage@gmail.com</div>
          </div>
        </a>
      </div>

      {/* ── PARCERIAS ── */}
      <div className="about-parceria">
        <div className="about-parceria__label">▸ PARCERIAS</div>
        <p>
          O canal está aberto a parcerias com marcas e fabricantes do setor automotivo
          que compartilhem o compromisso com informação técnica de qualidade.
          Entre em contato pelo e-mail acima.
        </p>
      </div>

    </div>
  );
}

// ============================================================
// TOPIC PAGE — página de detalhe por assunto
// ============================================================
const TOPIC_EMOJI = {
  motor: '⚙', freios: '🛑', suspensao: '🔩', eletrica: '⚡',
  cambio: '🔄', arrefecimento: '💧', carroceria: '🚗', dicas: '💡',
  revisao: '📋', compra_venda: '💰', combustivel: '⛽', pneus: '⬤',
  ferramentas: '🔧', direcao: '🎯', lavagem: '🪣', interior: '🪑', outro: '📦',
};

function TopicPage({ topic, allVideos, onBack, onOpen, onOpenCar, onSearch, initialCar, onCarFilter }) {
  // L2#3: activeCar agora é o carId canônico (não o nome display), pra evitar
  // filtro impreciso por contaminação de tag (Fit aparecendo em Ford KA, etc.).
  // initialCar: carId pré-selecionado quando a página é aberta via URL /carros/{car}/{topic}/
  const [activeCar, setActiveCar] = React.useState(initialCar || null);
  // L2#3/#7: paginação incremental — "ver mais" cresce o limite (24 → 24+24...).
  const [showCount, setShowCount] = React.useState(24);

  // Sincroniza com initialCar quando topic/initialCar mudam (ex: popstate)
  React.useEffect(() => { setActiveCar(initialCar || null); }, [topic && topic.id, initialCar]);

  // Notifica app.jsx quando o filtro de carro muda → atualiza URL
  const handleSetActiveCar = (carId) => {
    setActiveCar(carId);
    if (onCarFilter) onCarFilter(carId, topic);
  };

  if (!topic) return null;

  // Vídeos deste assunto
  const topicVideos = allVideos.filter(v => (v.topics || []).includes(topic.id));

  // L2#2: só os 6 carros reais (sem Fiesta/Strada de tags). Agrupa por carId
  // canônico (não pelo v.car display, que pode ter contaminação).
  const REAL_CARS = ['gol', 'brasilia', 'ka', 's10', 'fit', 'crv'];
  const carMap = new Map();
  topicVideos.forEach(v => {
    if (!v.carId || !REAL_CARS.includes(v.carId)) return;
    carMap.set(v.carId, (carMap.get(v.carId) || 0) + 1);
  });
  // Label legível para cada carId
  const CAR_LABEL = { gol:'Volkswagen Gol', brasilia:'Volkswagen Brasilia', ka:'Ford KA',
                      s10:'Chevrolet S10', fit:'Honda Fit', crv:'Honda CR-V' };
  const carList = [...carMap.entries()]
    .sort((a, b) => b[1] - a[1])
    .filter(([, n]) => n >= 2)
    .map(([cid, n]) => [cid, CAR_LABEL[cid] || cid, n]);

  const totalViews = topicVideos.reduce((s, v) => s + (v.views || 0), 0);

  // L2#3: filtra por carId canônico (não por v.car string)
  const filteredVideos = activeCar
    ? topicVideos.filter(v => v.carId === activeCar)
    : topicVideos;

  // Reset de paginação ao trocar de filtro
  React.useEffect(() => { setShowCount(24); }, [activeCar]);

  const topVideos    = [...topicVideos].sort((a, b) => (b.views || 0) - (a.views || 0)).slice(0, 6);
  const recentVideos = [...topicVideos].sort((a, b) => new Date(b.date) - new Date(a.date)).slice(0, 6);

  // Acha o CARS por carId canônico
  const findCarById = (cid) => typeof CARS !== 'undefined' ? CARS.find(c => c.id === cid) : null;

  return (
    <div className="page car-page">
      <a className="back-link" href="#" onClick={e => { e.preventDefault(); onBack(); }}>
        ◂ VOLTAR AO PORTAL
      </a>

      {/* ── HEADER (L2#6 rev. 15.2): 2 colunas — assunto à esquerda, Tucho à direita ── */}
      <div className="topic-head-grid">
        <div className="car-page__header topic-head-grid__main">
          <div className="car-page__hero-left" style={{ alignItems: 'center', padding: '0 0 0 20px', gap: 18 }}>
            <div style={{ fontSize: 56, lineHeight: 1, flexShrink: 0 }}>
              {TOPIC_EMOJI[topic.id] || '📂'}
            </div>
            <div className="car-page__info">
              <div className="car-page__brand">ASSUNTO</div>
              <h1 className="car-page__model" style={{fontSize: 32, lineHeight: 1.1}}>{topic.label}</h1>
              <div className="car-page__spec">
                {topicVideos.length} VÍDEOS · {carList.length} VEÍCULOS · {fmtViews(totalViews)} VIEWS
              </div>
            </div>
          </div>
        </div>
        <div className="topic-head-grid__tucho">
          {/* Tucho — busca dentro do assunto (movido pra cá pra ocupar metade da linha) */}
          <TopicTucho
            topic={topic}
            topicVideos={topicVideos}
            allVideos={allVideos}
            onOpen={onOpen}
            onSearch={onSearch}
          />
        </div>
      </div>

      {/* ── BODY ── */}
      <div className="car-page__body">
        <div className="car-page__main">

          {/* Navegue por veículo (L2#2 rev. 15.2: só os 6 carros reais) */}
          {carList.length > 0 && (
            <>
              <div className="section-head" style={{ marginTop: 20 }}>
                <h2>▸ Navegue por veículo</h2>
                <span className="tag">{carList.length} VEÍCULOS</span>
                {activeCar && (() => {
                  const carObj = findCarById(activeCar);
                  return carObj && onOpenCar ? (
                    <button className="back-link" style={{marginLeft:8,fontSize:11}}
                      onClick={() => onOpenCar(carObj)}>
                      → Ver página do {CAR_LABEL[activeCar] || activeCar}
                    </button>
                  ) : null;
                })()}
                {activeCar && (
                  <button className="car-page__clear" onClick={() => handleSetActiveCar(null)}>
                    ✕ limpar filtro
                  </button>
                )}
              </div>
              <div className="car-page__topic-grid">
                {carList.map(([cid, label, count]) => (
                  <button
                    key={cid}
                    className={'car-page__topic-card' + (activeCar === cid ? ' is-active' : '')}
                    onClick={() => handleSetActiveCar(activeCar === cid ? null : cid)}
                  >
                    <span className="car-page__topic-label">{label}</span>
                    <span className="car-page__topic-count">{count} vídeos</span>
                  </button>
                ))}
              </div>
            </>
          )}

          {/* Lista de vídeos */}
          <div className="section-head" style={{ marginTop: 20 }}>
            <h2>{activeCar ? `▸ ${CAR_LABEL[activeCar] || activeCar}` : '▸ Todos os vídeos'}</h2>
            <span className="tag">{filteredVideos.length} VÍDEOS</span>
          </div>
          <div className="car-page__video-grid">
            {filteredVideos.slice(0, showCount).map(v => (
              <div key={v.id} className="vid-mini" onClick={() => onOpen(v)}>
                <div className="thumb">
                  <img src={ytThumb(v.id)} alt="" loading="lazy" />
                  <div className="duration">{v.duration}</div>
                </div>
                <div className="vid-mini__body">
                  <div className="vid-mini__title">{v.title}</div>
                  <div className="vid-mini__meta">{fmtViews(v.views)} views · {fmtDate(v.date)}</div>
                  <VideoBadges v={v} />
                </div>
              </div>
            ))}
          </div>
          {/* L2#3 rev. 15.2: mensagem com lógica corrigida + "ver mais" incremental */}
          {filteredVideos.length > showCount && (
            <div style={{ marginTop: 14, display: 'flex', alignItems: 'center', gap: 16, flexWrap: 'wrap' }}>
              <button className="back-link" style={{fontFamily:'var(--font-mono)',fontSize:11}}
                onClick={() => setShowCount(c => c + 24)}>
                ▾ Ver mais 24 vídeos
              </button>
              <span style={{ fontFamily: 'var(--font-mono)', fontSize: 11, color: 'var(--pg-gray-2)', textTransform: 'uppercase', letterSpacing: '0.1em' }}>
                Mostrando {showCount} de {filteredVideos.length}
                {!activeCar && ' — escolha um veículo acima para filtrar'}
              </span>
            </div>
          )}
        </div>

        {/* ── sidebar ── */}
        <aside className="car-page__aside">
          <div className="car-page__aside-block">
            <div className="car-page__aside-head">🏆 MAIS VISTOS</div>
            {topVideos.map(v => (
              <div key={v.id} className="hsl__row" onClick={() => onOpen(v)}>
                <div className="thumb hsl__thumb">
                  <img src={ytThumb(v.id)} alt="" loading="lazy" />
                  <div className="duration">{v.duration}</div>
                </div>
                <div>
                  <div className="hsl__title">{v.title}</div>
                  <div className="hsl__meta">{fmtViews(v.views)} views</div>
                </div>
              </div>
            ))}
          </div>
          <div className="car-page__aside-block">
            <div className="car-page__aside-head">📌 ÚLTIMOS</div>
            {recentVideos.map(v => (
              <div key={v.id} className="hsl__row" onClick={() => onOpen(v)}>
                <div className="thumb hsl__thumb">
                  <img src={ytThumb(v.id)} alt="" loading="lazy" />
                  <div className="duration">{v.duration}</div>
                </div>
                <div>
                  <div className="hsl__title">{v.title}</div>
                  <div className="hsl__meta">{fmtDate(v.date)}</div>
                </div>
              </div>
            ))}
          </div>
        </aside>
      </div>
    </div>
  );
}

// ============================================================
// CAR PAGE — Por Carro / detalhe (Light + Complete)
// ============================================================

// Map system id → Icon (expandido na rev. 14)
const SYS_ICO = {
  motor: Icon.Piston, freios: Icon.Brake, suspensao: Icon.Spring,
  eletrica: Icon.Bolt, arrefecimento: Icon.Bulb, cambio: Icon.Wrench,
  direcao: Icon.Wrench, combustivel: Icon.Wrench, escapamento: Icon.Wrench,
  carroceria: Icon.Paint, funilaria: Icon.Paint, interior: Icon.Wrench,
  pneus: Icon.Wrench, lavagem: Icon.Bulb,
  Piston: Icon.Piston, Brake: Icon.Brake, Spring: Icon.Spring,
  Bolt: Icon.Bolt, Bulb: Icon.Bulb, Wrench: Icon.Wrench, Paint: Icon.Paint,
};

// Labels amigáveis por topic id (rev. 14 — antes só vinham do car-page-data.js)
const SYS_LABELS = {
  motor: 'Motor', freios: 'Freios', suspensao: 'Suspensão',
  eletrica: 'Elétrica', arrefecimento: 'Arrefecimento', cambio: 'Câmbio',
  direcao: 'Direção', combustivel: 'Combustível', escapamento: 'Escapamento',
  carroceria: 'Carroceria', funilaria: 'Funilaria & Pintura', interior: 'Interior',
  pneus: 'Pneus & Rodas', lavagem: 'Lavagem & Detalhamento',
};

// Topics que NÃO são "sistemas" — content type, não navegamos por eles
const NON_SYSTEM_TOPICS = new Set([
  'dicas', 'revisao', 'ferramentas', 'outro', 'compra_venda',
]);

// Enriquece car.systems (legado) com contagens reais e thumbnail do mais visto
function buildRealSystems(carSystems, allVideos) {
  return carSystems
    .map(s => {
      const vids = allVideos.filter(v => (v.topics || []).includes(s.id));
      const topVideo = vids.length > 0
        ? vids.reduce((best, v) => ((v.views||0) > (best.views||0) ? v : best), vids[0])
        : null;
      return { ...s, count: vids.length, topVideo };
    })
    .filter(s => s.count > 0)
    .sort((a, b) => b.count - a.count);
}

// (rev. 14) Deriva sistemas direto dos topics dos vídeos do carro (allVideos já filtrado por carId).
// Substitui a lista hardcoded de car-page-data.js — pega todos os tópicos cobertos pelo canal para este carro.
function buildSystemsFromVideos(allVideos) {
  const counts = {};
  const topVids = {};
  for (const v of allVideos) {
    for (const t of (v.topics || [])) {
      if (NON_SYSTEM_TOPICS.has(t)) continue;
      counts[t] = (counts[t] || 0) + 1;
      const cur = topVids[t];
      if (!cur || (v.views || 0) > (cur.views || 0)) topVids[t] = v;
    }
  }
  return Object.entries(counts)
    .map(([id, count]) => ({
      id,
      label: SYS_LABELS[id] || (id.charAt(0).toUpperCase() + id.slice(1)),
      ico: id,
      count,
      topVideo: topVids[id] || null,
    }))
    .sort((a, b) => b.count - a.count);
}

const TUCHO_HINTS_CAR = [
  "Como trocar o fluido de freio?",
  "Por que o carro não pega?",
  "Barulho na suspensão, o que pode ser?",
];

// ---------- Helpers para abrir LISTA filtrada (rev. 15) ----------
// Converte IDs de vídeo ou um tópico numa lista de {v, score} para a
// página de resultados (TuchoResultsPage). Usado ao clicar em
// "problemas comuns" e "navegue por sistema".
function _scoredFromIds(ids, allVideos) {
  const map = Object.fromEntries(allVideos.map(v => [v.id, v]));
  return (ids || [])
    .map((id, i) => ({ v: map[id], score: i === 0 ? 3 : i < 3 ? 2 : 1 }))
    .filter(x => x.v);
}
function _scoredFromTopic(topicId, allVideos) {
  const vids = allVideos.filter(v => (v.topics || []).includes(topicId));
  vids.sort((a, b) => (b.views || 0) - (a.views || 0));
  return vids.map((v, i) => ({ v, score: i === 0 ? 3 : i < 3 ? 2 : 1 }));
}
// Abre a lista de um "problema comum" (usa videoIds do cluster)
function openProblemList(problem, car, allVideos, onSearch) {
  if (!onSearch) return;
  const scored = _scoredFromIds(problem.videoIds, allVideos);
  if (scored.length === 0) return;
  onSearch(problem.label, scored, { label: `${car.make} ${car.model}`, carId: car.id });
}
// Abre a lista de um "sistema" (filtra por tópico no carro atual)
function openSystemList(system, car, allVideos, onSearch) {
  if (!onSearch) return;
  const scored = _scoredFromTopic(system.id, allVideos);
  if (scored.length === 0) return;
  onSearch(system.label, scored, { label: `${car.make} ${car.model}`, carId: car.id });
}

// ---------- Stat icon row helper ----------
function CarStat({ icon: ICO, value, label }) {
  return (
    <div className="cp-stat">
      <div className="cp-stat__icon"><ICO /></div>
      <div>
        <div className="cp-stat__v">{value}</div>
        <div className="cp-stat__k">{label}</div>
      </div>
    </div>
  );
}

// ---------- TUCHO ask ----------
function CarTucho({ car, allVideos, onOpen, onSearch, variant }) {
  const [q, setQ] = React.useState("");
  const [loading, setLoading] = React.useState(false);
  const [answer, setAnswer] = React.useState(null);
  const [picks, setPicks] = React.useState([]);

  const ask = async (question) => {
    const text = (question || q).trim();
    if (!text || loading) return;
    setLoading(true);
    setAnswer(null);

    // ── Busca híbrida (semântica + keyword) filtrada pelo carro ─
    const allScored = await hybridSearch(text, allVideos, allVideos);
    const p = allScored.slice(0, 3).map(x => x.v);
    setPicks(p);

    // Navegar para TuchoResultsPage com contexto do carro
    if (onSearch) {
      const toTitle = s => (s || '').toLowerCase().replace(/\b\w/g, c => c.toUpperCase());
      const context = {
        label: `${toTitle(car.make)} ${toTitle(car.model)}`,
        carId: car.id || car.carId,
        make: toTitle(car.make),
        model: toTitle(car.model),
      };
      onSearch(text, allScored, context);
      setLoading(false);
      return;
    }

    // Frase canônica (decisão de produto rev. 14): sem LLM
    setAnswer(`Boa pergunta! Dei uma vasculhada nos vídeos do ${car.model} e achei uns que devem te ajudar. Confere os que separei aí embaixo — passo-a-passo, do jeito que o Paulo mostra.`);
    setLoading(false);
  };

  const cls = "cp-tucho" + (variant === "hero" ? " cp-tucho--hero" : "");

  return (
    <div className={cls}>
      <div className="cp-tucho__mascot" />
      <div>
        <div className="cp-tucho__head">
          <span className="cp-tucho__title">Pergunte ao TUCHO</span>
          <span className="cp-tucho__ai-tag">IA</span>
          <span className="cp-tucho__scope">▸ buscando só no {car.model}</span>
        </div>
        <form className="cp-tucho__form" onSubmit={(e) => { e.preventDefault(); ask(); }}>
          <input
            placeholder="Ex: freio baixo, motor falhando, barulho na suspensão..."
            value={q}
            onChange={(e) => setQ(e.target.value)}
          />
          <button type="submit" disabled={loading}>
            <Icon.Search style={{width:14,height:14}} />
            {loading ? "..." : "Buscar"}
          </button>
        </form>
        <div className="cp-tucho__chips">
          {TUCHO_HINTS_CAR.map(h => (
            <button key={h} className="cp-tucho__chip" onClick={() => { setQ(h); ask(h); }}>
              {h}
            </button>
          ))}
        </div>
        {(answer || picks.length > 0) && (
          <div className="cp-tucho__results">
            {answer && <div className="cp-tucho__answer">{answer}</div>}
            <div className="cp-tucho__results-grid">
              {picks.map(v => (
                <div key={v.id} className="vid-mini" onClick={() => onOpen(v)}>
                  <div className="thumb" style={{aspectRatio:"16/9"}}>
                    <img src={ytThumb(v.id)} alt="" />
                    <div className="duration">{v.duration}</div>
                  </div>
                  <div className="vid-mini__body">
                    <div className="vid-mini__title">{v.title}</div>
                    <div className="vid-mini__meta">{fmtViews(v.views)} views</div>
                  </div>
                </div>
              ))}
            </div>
          </div>
        )}
      </div>
    </div>
  );
}

// ---------- TUCHO ask — por Assunto ----------
const TUCHO_HINTS_TOPIC = [
  "Como resolver barulho?",
  "Custo médio do reparo?",
  "Posso fazer em casa?",
];

function TopicTucho({ topic, topicVideos, allVideos, onOpen, onSearch }) {
  const [q, setQ] = React.useState("");
  const [loading, setLoading] = React.useState(false);
  const [answer, setAnswer] = React.useState(null);
  const [picks, setPicks] = React.useState([]);

  const ask = async (question) => {
    const text = (question || q).trim();
    if (!text || loading) return;
    setLoading(true);
    setAnswer(null);

    const pool = topicVideos.length > 0 ? topicVideos : allVideos;

    // ── Busca híbrida (semântica + keyword) filtrada pelo tópico ─
    const allScored = await hybridSearch(text, pool, allVideos);
    const p = allScored.slice(0, 3).map(x => x.v);
    setPicks(p);

    if (onSearch) {
      const context = { label: topic.label, topicId: topic.id };
      onSearch(text, allScored, context);
      setLoading(false);
      return;
    }

    // Frase canônica (decisão de produto rev. 14): sem LLM
    setAnswer(`Separei os vídeos mais relevantes sobre "${text}" em ${topic.label}. Dá uma olhada aí embaixo!`);
    setLoading(false);
  };

  return (
    <div className="cp-tucho">
      <div className="cp-tucho__mascot" />
      <div>
        <div className="cp-tucho__head">
          <span className="cp-tucho__title">Pergunte ao TUCHO</span>
          <span className="cp-tucho__ai-tag">IA</span>
          <span className="cp-tucho__scope">▸ buscando em {topic.label}</span>
        </div>
        <form className="cp-tucho__form" onSubmit={(e) => { e.preventDefault(); ask(); }}>
          <input
            placeholder="Ex: barulho, como trocar, sintomas..."
            value={q}
            onChange={(e) => setQ(e.target.value)}
          />
          <button type="submit" disabled={loading}>
            <Icon.Search style={{width:14,height:14}} />
            {loading ? "..." : "Buscar"}
          </button>
        </form>
        <div className="cp-tucho__chips">
          {TUCHO_HINTS_TOPIC.map(h => (
            <button key={h} className="cp-tucho__chip" onClick={() => { setQ(h); ask(h); }}>
              {h}
            </button>
          ))}
        </div>
        {(answer || picks.length > 0) && (
          <div className="cp-tucho__results">
            {answer && <div className="cp-tucho__answer">{answer}</div>}
            <div className="cp-tucho__results-grid">
              {picks.map(v => (
                <div key={v.id} className="vid-mini" onClick={() => onOpen(v)}>
                  <div className="thumb" style={{aspectRatio:"16/9"}}>
                    <img src={ytThumb(v.id)} alt="" />
                    <div className="duration">{v.duration}</div>
                  </div>
                  <div className="vid-mini__body">
                    <div className="vid-mini__title">{v.title}</div>
                    <div className="vid-mini__meta">{fmtViews(v.views)} views</div>
                  </div>
                </div>
              ))}
            </div>
          </div>
        )}
      </div>
    </div>
  );
}

// ---------- Helpers para stats reais do carro ----------
function realCarStats(allVideos, carMeta) {
  const totalViews   = allVideos.reduce((s, v) => s + (v.views || 0), 0);
  const totalLikes   = allVideos.reduce((s, v) => s + (v.likes || 0), 0);
  const totalSecs    = allVideos.reduce((s, v) => s + (v.durationSecs || 0), 0);
  const totalHours   = Math.round(totalSecs / 3600);
  const fmtV = n => n >= 1_000_000 ? (n/1_000_000).toFixed(1).replace('.', ',') + ' mi'
                  : n >= 1_000     ? Math.round(n/1_000) + ' mil'
                  : String(n);
  return {
    videos:  allVideos.length  || (carMeta.stats && carMeta.stats.videos),
    hours:   totalHours + 'h'  || (carMeta.stats && carMeta.stats.hours),
    likes:   fmtV(totalLikes)  || (carMeta.stats && carMeta.stats.likes),
    views:   fmtV(totalViews)  || (carMeta.stats && carMeta.stats.views),
    systems: (carMeta.stats && carMeta.stats.systems) || (carMeta.coverage && carMeta.coverage.length) || 6,
  };
}

// ---------- Hero compacto 3-col ----------
function CarHeroCompactLight({ car, allVideos, onOpen, onSearch, variant }) {
  if (variant === "complete") {
    const stats = realCarStats(allVideos, car);
    // Ferramentas reais de __PG_DATA__.toolsByCar, fallback para car-page-data.js
    const pgTools = ((window.__PG_DATA__ || {}).toolsByCar || {})[car.id] || [];
    const tools = pgTools.length ? pgTools : (car.tools || []);
    const max = Math.max(1, ...tools.map(t => t.count));
    return (
      <div className="cp-hero-compact-light cp-hero-compact-light--3col">
        <div className="cp-hcl__photo-card">
          <div className="cp-hcl__make">{car.make} {car.model}</div>
          <div className="cp-hcl__specs">
            <span>{car.yearStart || (car.years && car.years.split(" ")[0])}</span>
            <span>{(car.engine || "").replace(/^Motor\s+/i, "")}</span>
            <span>{car.fuel}</span>
          </div>
          <div className="cp-hcl__photo-wrap">
            <img className="cp-hcl__photo" src={car.heroImage} alt={`${car.make} ${car.model}`}
              onError={e => { e.currentTarget.style.opacity = '0.3'; }} />
          </div>
        </div>
        <div className="cp-hcl__center">
          <div className="cp-hcl__tucho">
            <CarTucho car={car} allVideos={allVideos} onOpen={onOpen} onSearch={onSearch} variant="compact" />
          </div>
          <div className="cp-hcl__stats">
            <div className="cp-hcl__stats-head">
              <span className="cp-hcl__stats-label">▸ Resumo do carro</span>
            </div>
            <div className="cp-hcl__stats-grid">
              <CarStat icon={Icon.Piston} value={stats.videos}  label="Vídeos" />
              <CarStat icon={Icon.Wrench} value={stats.hours}   label="De conteúdo" />
              <CarStat icon={Icon.Bolt}   value={stats.likes}   label="Likes" />
              <CarStat icon={Icon.Bulb}   value={stats.views}   label="Views" />
              <CarStat icon={Icon.Brake}  value={stats.systems} label="Sistemas" />
            </div>
          </div>
        </div>
        <div className="cp-hcl__rightcol">
          <div className="cp-hcl__panel cp-hcl__panel--full">
            <div className="cp-hcl__panel-head">
              <span className="cp-hcl__panel-label">▸ Ferramentas mais citadas</span>
            </div>
            <div className="cp-tools cp-tools--fill">
              {tools.slice(0, 7).map(t => (
                <div key={t.tool || t.name} className="cp-tools__row">
                  <div className="cp-tools__name">{t.tool || t.name}</div>
                  <div className="cp-tools__count">{t.count}×</div>
                  <div className="cp-tools__bar"><span style={{width: (t.count / max * 100) + "%"}} /></div>
                </div>
              ))}
            </div>
          </div>
        </div>
      </div>
    );
  }

  // light variant
  const stats = realCarStats(allVideos, car);
  return (
    <div className="cp-hero-compact-light cp-hero-compact-light--3col">
      <div className="cp-hcl__photo-card">
        <div className="cp-hcl__make">{car.make} {car.model}</div>
        <div className="cp-hcl__specs">
          <span>{car.yearStart || (car.years && car.years.split(" ")[0])}</span>
          <span>{(car.engine || "").replace(/^Motor\s+/i, "")}</span>
          <span>{car.fuel}</span>
        </div>
        <div className="cp-hcl__photo-wrap">
          <img className="cp-hcl__photo" src={car.heroImage} alt={`${car.make} ${car.model}`}
            onError={e => { e.currentTarget.style.opacity = '0.3'; }} />
        </div>
      </div>

      <div className="cp-hcl__center">
        <div className="cp-hcl__tucho">
          <CarTucho car={car} allVideos={allVideos} onOpen={onOpen} onSearch={onSearch} variant="compact" />
        </div>
        <div className="cp-hcl__panel">
          <div className="cp-hcl__panel-head">
            <span className="cp-hcl__panel-label">▸ Problemas comuns</span>
          </div>
          <ul className="cp-hcl__list">
            {/* Problemas reais (rev. 14): __PG_DATA__.problemsByCar; fallback para car-page-data.js */}
            {(((window.__PG_DATA__ || {}).problemsByCar || {})[car.id]?.problemas
                || car.problems || []).slice(0, 5).map(p => (
              <li key={p.id} className="cp-hcl__list-row cp-hcl__list-row--clickable"
                  onClick={() => openProblemList(p, car, allVideos, onSearch)}
                  title={`Ver vídeos: ${p.label}`}>
                <span className="cp-hcl__list-bullet">!</span>
                <span className="cp-hcl__list-name">{p.label}</span>
                <span className="cp-hcl__list-count">{p.videoCount}</span>
              </li>
            ))}
          </ul>
        </div>
      </div>

      <div className="cp-hcl__rightcol">
        <div className="cp-hcl__stats">
          <div className="cp-hcl__stats-head">
            <span className="cp-hcl__stats-label">▸ Resumo do carro</span>
          </div>
          <div className="cp-hcl__stats-grid">
            <CarStat icon={Icon.Piston} value={stats.videos}  label="Vídeos" />
            <CarStat icon={Icon.Wrench} value={stats.hours}   label="De conteúdo" />
            <CarStat icon={Icon.Bolt}   value={stats.likes}   label="Likes" />
            <CarStat icon={Icon.Bulb}   value={stats.views}   label="Views" />
            <CarStat icon={Icon.Brake}  value={stats.systems} label="Sistemas" />
          </div>
        </div>
        <div className="cp-hcl__panel">
          <div className="cp-hcl__panel-head">
            <span className="cp-hcl__panel-label">▸ Navegue por sistema</span>
          </div>
          <ul className="cp-hcl__list">
            {/* Rev. 14: deriva sistemas direto dos topics dos videos do carro */}
            {buildSystemsFromVideos(allVideos).slice(0, 6).map(s => {
              const ICO = SYS_ICO[s.ico] || SYS_ICO[s.id] || Icon.Wrench;
              return (
                <li key={s.id} className="cp-hcl__list-row cp-hcl__list-row--clickable"
                    onClick={() => openSystemList(s, car, allVideos, onSearch)}
                    title={`Ver vídeos: ${s.label}`}>
                  <span className="cp-hcl__list-ico"><ICO /></span>
                  <span className="cp-hcl__list-name">{s.label}</span>
                  <span className="cp-hcl__list-count">{s.count}</span>
                </li>
              );
            })}
          </ul>
        </div>
      </div>
    </div>
  );
}

// ---------- CTA: ver análise completa ----------
function CompleteCTA({ car, onOpenComplete }) {
  return (
    <div className="cp-cta">
      <div className="cp-cta__icon">
        <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round">
          <path d="M3 21h18M5 21V10M10 21V6M15 21v-9M20 21V3" />
        </svg>
      </div>
      <div className="cp-cta__main">
        <div className="cp-cta__title">Análise completa do {car.model}</div>
        <div className="cp-cta__desc">
          Explore problemas comuns, sistemas, séries, estatísticas detalhadas, últimos e mais vistos, e as ferramentas mais citadas.
        </div>
      </div>
      <ul className="cp-cta__features">
        <li>Problemas comuns</li>
        <li>Navegue por sistema</li>
        <li>Séries e projetos</li>
        <li>Estatísticas do carro</li>
        <li>Mais vistos e últimos</li>
        <li>Ferramentas mais citadas</li>
      </ul>
      <div>
        <button className="cp-cta__btn" onClick={onOpenComplete}>
          <svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round">
            <path d="M3 21h18M5 21V10M10 21V6M15 21v-9M20 21V3" />
          </svg>
          Ver análise completa
        </button>
        <span className="cp-cta__btn-sub">▸ Dashboard completo disponível</span>
      </div>
    </div>
  );
}

// ---------- Light view ----------
function CarPageLight({ car, allVideos, onOpen, onOpenComplete, onSearch }) {
  return (
    <>
      <CarHeroCompactLight car={car} allVideos={allVideos} onOpen={onOpen} onSearch={onSearch} variant="light" />
      <CompleteCTA car={car} onOpenComplete={onOpenComplete} />
    </>
  );
}

// ============================================================
// COMPLETE / Dashboard
// ============================================================
function ProblemsDetailed({ problems, allVideos, onOpen, onSearch, car }) {
  // Map id -> video (allVideos já é filtrado pelo carro em CarPage)
  const byId = React.useMemo(() => {
    const m = {};
    (allVideos || []).forEach(v => { m[v.id] = v; });
    return m;
  }, [allVideos]);

  return (
    <div className="cp-section">
      <div className="cp-section__head">
        <div className="cp-section__icon"><Icon.Bolt /></div>
        <div className="cp-section__title">Problemas comuns</div>
        <span className="cp-section__sub">Seleção automática com base no conteúdo</span>
      </div>
      <div className="cp-problems-detailed">
        {problems.slice(0, 4).map((p) => {
          // Rev. 14: usa videoIds reais do cluster (não mais cycling aleatório).
          // Fallback para allVideos se o problema vier do car-page-data.js antigo.
          const ids = p.videoIds && p.videoIds.length
            ? p.videoIds
            : allVideos.slice(0, 3).map(v => v.id);
          const vids = ids.map(id => byId[id]).filter(Boolean);
          const v0 = vids[0] || null;
          const thumbs = vids.slice(0, 3);
          return (
            <div key={p.id} className="cp-problems-detailed__row"
              onClick={() => {
                // #5: abre a LISTA de vídeos do problema (não mais o 1º vídeo)
                if (onSearch && car) openProblemList(p, car, allVideos, onSearch);
                else if (onOpen && v0) onOpen(v0);
              }}>
              <div className="cp-problems-detailed__main">
                <div className="cp-problem__alert">!</div>
                <div>
                  <div className="cp-problem__title">{p.label}</div>
                  <div className="cp-problems-detailed__count">{p.videoCount} vídeos · confiança {(p.confidence * 100).toFixed(0)}%</div>
                  <div className="cp-problems-detailed__symptom">{p.symptom}</div>
                </div>
              </div>
              <div className="cp-problems-detailed__thumbs">
                {thumbs.map((v, i) => (
                  <div key={v.id || i} className="cp-problem__thumb">
                    <img src={ytThumb(v.id)} alt="" loading="lazy" />
                    <div className="duration">{v.duration}</div>
                  </div>
                ))}
                {p.videoCount > 3 && (
                  <div className="cp-problems-detailed__more">+{p.videoCount - 3}<br/>vídeos</div>
                )}
              </div>
            </div>
          );
        })}
      </div>
    </div>
  );
}

function SystemsBig({ systems, allVideos, onOpen, onSearch, car }) {
  // Rev. 14: prefere derivar do topics real; fallback para car.systems legado
  const realSystems = buildSystemsFromVideos(allVideos);
  if (realSystems.length === 0) return null;
  return (
    <div className="cp-section">
      <div className="cp-section__head">
        <div className="cp-section__icon"><Icon.Wrench /></div>
        <div className="cp-section__title">Navegue por sistema</div>
        <span className="cp-section__sub">Explore todos os sistemas cobertos para este carro</span>
      </div>
      <div className="cp-systems cp-systems--big">
        {realSystems.slice(0, 6).map(s => {
          const ICO = SYS_ICO[s.ico] || SYS_ICO[s.id] || Icon.Wrench;
          const coverVid = s.topVideo;
          return (
            <div key={s.id} className="cp-system" style={{cursor: 'pointer'}}
              onClick={() => {
                // #5: abre a LISTA de vídeos do sistema (não mais o vídeo de capa)
                if (onSearch && car) openSystemList(s, car, allVideos, onSearch);
                else if (coverVid && onOpen) onOpen(coverVid);
              }}>
              <div className="cp-system__cover">
                {coverVid
                  ? <img src={ytThumb(coverVid.id)} alt="" style={{width:"100%",height:"100%",objectFit:"cover",opacity:0.55}} />
                  : <div style={{width:"100%",height:"100%",background:"var(--pg-surface-2)"}} />
                }
                <div className="cp-system__overlay"><ICO /></div>
              </div>
              <div className="cp-system__body">
                <div className="cp-system__label" style={{textAlign:"left"}}>{s.label}</div>
                <div className="cp-system__count" style={{textAlign:"left"}}>{s.count} vídeo{s.count !== 1 ? 's' : ''}</div>
              </div>
            </div>
          );
        })}
      </div>
    </div>
  );
}

// (rev. 15) Componente Trail removido — Trilha Recomendada não tinha conteúdo
// nem ação. Reintroduzir só com curadoria real (decisão de produto).

function Series({ carId, allVideos, onOpen }) {
  // Usa seriesByCar do data-embed (gerado por build_data_embed.py)
  const pgData = window.__PG_DATA__ || {};
  const seriesByCar = pgData.seriesByCar || {};
  const realSeries = (carId ? seriesByCar[carId] : null) || [];

  if (realSeries.length === 0) return null;

  return (
    <div className="cp-section">
      <div className="cp-section__head">
        <div className="cp-section__icon"><Icon.Piston /></div>
        <div className="cp-section__title">Séries em destaque</div>
      </div>
      <div className="cp-series">
        {realSeries.slice(0, 4).map(s => (
          <div key={s.name} className="cp-serie" style={{cursor:'pointer'}}
            onClick={() => {
              const first = allVideos.find(v => v.id === s.firstEpisodeId);
              if (first && onOpen) onOpen(first);
            }}
          >
            <div className="cp-serie__cover">
              <img src={ytThumb(s.firstEpisodeId)} alt="" style={{width:"100%",height:"100%",objectFit:"cover"}} />
            </div>
            <div>
              <div className="cp-serie__title">{s.name}</div>
              <div className="cp-serie__meta">{s.episodes} episódio{s.episodes !== 1 ? 's' : ''}</div>
            </div>
          </div>
        ))}
      </div>
    </div>
  );
}

function MostViewedRail({ videos, onOpen }) {
  return (
    <div className="cp-section">
      <div className="cp-section__head">
        <div className="cp-section__title" style={{fontSize:14}}>Mais vistos</div>
      </div>
      <div className="cp-mostviewed">
        {videos.slice(0, 6).map(v => (
          <div key={v.id} className="card-row" onClick={() => onOpen(v)}>
            <div className="thumb">
              <img src={ytThumb(v.id)} alt="" loading="lazy" />
              <div className="duration">{v.duration}</div>
            </div>
            <div>
              <div className="card-row__title">{v.title}</div>
              <div className="card-row__meta">{fmtViews(v.views)} views · {fmtDate(v.date)}</div>
            </div>
          </div>
        ))}
      </div>
    </div>
  );
}

function LatestRail({ videos, onOpen }) {
  return (
    <div className="cp-section">
      <div className="cp-section__head">
        <div className="cp-section__title" style={{fontSize:14}}>Últimos vídeos</div>
      </div>
      <div className="cp-mostviewed">
        {videos.slice(0, 6).map(v => (
          <div key={v.id} className="card-row" onClick={() => onOpen(v)}>
            <div className="thumb">
              <img src={ytThumb(v.id)} alt="" loading="lazy" />
              <div className="duration">{v.duration}</div>
            </div>
            <div>
              <div className="card-row__title">{v.title}</div>
              <div className="card-row__meta">{fmtDate(v.date)} · {fmtViews(v.views)} views</div>
            </div>
          </div>
        ))}
      </div>
    </div>
  );
}

function CarPageComplete({ car, carId, allVideos, onOpen, onSearch }) {
  const mostViewed = [...allVideos].sort((a, b) => (b.views || 0) - (a.views || 0)).slice(0, 6);
  const latest = [...allVideos].sort((a, b) => (b.date || "").localeCompare(a.date || "")).slice(0, 6);
  // Problemas reais por carro (rev. 14): __PG_DATA__.problemsByCar; fallback para car-page-data.js
  const realProblems = ((window.__PG_DATA__ || {}).problemsByCar || {})[carId]?.problemas || car.problems || [];
  return (
    <>
      <CarHeroCompactLight car={car} allVideos={allVideos} onOpen={onOpen} onSearch={onSearch} variant="complete" />
      <div className="cp-dash">
        <div className="cp-dash__main">
          <ProblemsDetailed problems={realProblems} allVideos={allVideos} onOpen={onOpen} onSearch={onSearch} car={car} />
          <SystemsBig systems={car.systems} allVideos={allVideos} onOpen={onOpen} onSearch={onSearch} car={car} />
          <Series carId={carId} allVideos={allVideos} onOpen={onOpen} />
          {/* #6: Trilha Recomendada removida (não existia conteúdo nem ação) */}
        </div>
        <div className="cp-dash__rail">
          <MostViewedRail videos={mostViewed} onOpen={onOpen} />
          <LatestRail videos={latest} onOpen={onOpen} />
        </div>
      </div>
    </>
  );
}

// ============================================================
// CAR PAGE WRAPPER (toolbar + view switch)
// ============================================================
function CarPage({ carId, allVideos, onOpen, onBack, view, setView, onSearch }) {
  const pgData = window.__PG_CAR_DATA__ || {};
  // Injeta `id` no objeto do carro para que CarTucho saiba o carId canônico
  const rawData = pgData[carId] || pgData.gol || null;
  const data = rawData ? { ...rawData, id: carId || 'gol' } : null;

  // Filtra vídeos apenas do carro atual usando o campo carId normalizado
  // carId aqui é o ID canônico curto (ex: "gol", "brasilia", "ka")
  const carVideos = React.useMemo(() => {
    if (!carId) return allVideos;
    return allVideos.filter(v => v.carId === carId);
  }, [allVideos, carId]);

  if (!data) {
    return (
      <div className="page">
        <a className="back-link" href="#" onClick={(e) => { e.preventDefault(); onBack(); }}>◂ VOLTAR</a>
        <p style={{padding:"40px", color:"var(--pg-gray-2)", fontFamily:"var(--font-mono)"}}>
          Dados do carro não encontrados.
        </p>
      </div>
    );
  }

  return (
    <div className="page">
      <div className="cp-toolbar">
        <a className="back-link" href="#" onClick={(e) => { e.preventDefault(); onBack(); }}>
          ◂ VOLTAR
        </a>
        <span className="cp-toolbar__label">▸ Modo de visualização:</span>
        <button
          className={"cp-toolbar__btn" + (view === "light" ? " is-active" : "")}
          onClick={() => setView("light")}
        >
          Visão rápida
        </button>
        <button
          className={"cp-toolbar__btn" + (view === "complete" ? " is-active" : "")}
          onClick={() => setView("complete")}
        >
          Análise completa ▸
        </button>
        <span className="cp-toolbar__spacer" />
        <span className="cp-toolbar__hint">
          {view === "light"
            ? "Versão leve · carregamento rápido"
            : "Dashboard completo · todos os dados"}
        </span>
      </div>

      <div className="breadcrumb" style={{padding:"0 0 10px"}}>
        <a href="#" onClick={(e) => { e.preventDefault(); onBack(); }}>Início</a>
        <span className="sep">/</span>
        <span>Por Carro</span>
        <span className="sep">/</span>
        <span>{data.make}</span>
        <span className="sep">/</span>
        <span className="here">{data.model}</span>
      </div>

      {view === "light" ? (
        <CarPageLight
          car={data}
          allVideos={carVideos}
          onOpen={onOpen}
          onSearch={onSearch}
          onOpenComplete={() => setView("complete")}
        />
      ) : (
        <CarPageComplete
          car={data}
          carId={carId}
          allVideos={carVideos}
          onOpen={onOpen}
          onSearch={onSearch}
        />
      )}
    </div>
  );
}

// ============================================================
// SEARCH PAGE — resultados da busca via Tucho
// ============================================================
function SearchPage({ query, results, allVideos, onBack, onOpen, onOpenCar }) {
  const [sortBy, setSortBy] = React.useState('relevance'); // 'relevance' | 'views' | 'date'

  if (!query) return null;

  // Recomputa resultados se necessário (results já vem pontuado por relevância)
  const sorted = React.useMemo(() => {
    if (!results || results.length === 0) return [];
    if (sortBy === 'views') return [...results].sort((a, b) => (b.views || 0) - (a.views || 0));
    if (sortBy === 'date')  return [...results].sort((a, b) => (b.date || '').localeCompare(a.date || ''));
    return results; // relevance — já ordenado
  }, [results, sortBy]);

  const totalViews = sorted.reduce((s, v) => s + (v.views || 0), 0);

  // Agrupa por carro para filtro rápido
  const carMap = new Map();
  sorted.forEach(v => { if (v.carModel) carMap.set(v.carModel, (carMap.get(v.carModel) || 0) + 1); });
  const carList = [...carMap.entries()].sort((a, b) => b[1] - a[1]).filter(([, n]) => n >= 2);

  const [activeCar, setActiveCar] = React.useState(null);
  const displayed = activeCar ? sorted.filter(v => v.carModel === activeCar) : sorted;

  return (
    <div className="page car-page">
      <a className="back-link" href="#" onClick={e => { e.preventDefault(); onBack(); }}>
        ◂ VOLTAR AO PORTAL
      </a>

      {/* ── HEADER ── */}
      <div className="car-page__header">
        <div className="car-page__hero-left" style={{ alignItems: 'center', padding: '0 0 0 28px', gap: 24 }}>
          <div style={{ fontSize: 56, lineHeight: 1, flexShrink: 0 }}>🔍</div>
          <div className="car-page__info">
            <div className="car-page__brand">BUSCA · TUCHO</div>
            <h1 className="car-page__model" style={{ fontSize: 26 }}>"{query}"</h1>
            <div className="car-page__spec">
              {sorted.length} VÍDEOS ENCONTRADOS · {fmtViews(totalViews)} VIEWS ACUMULADAS
            </div>
          </div>
        </div>
        <div className="car-page__stats-row">
          <div className="car-page__stat">
            <span className="car-page__stat-n">{sorted.length}</span>
            <span className="car-page__stat-l">RESULTADOS</span>
          </div>
          <div className="car-page__stat">
            <span className="car-page__stat-n">{fmtViews(totalViews)}</span>
            <span className="car-page__stat-l">VIEWS</span>
          </div>
          <div className="car-page__stat">
            <span className="car-page__stat-n">{carList.length}</span>
            <span className="car-page__stat-l">VEÍCULOS</span>
          </div>
        </div>
      </div>

      {/* ── FILTROS ── */}
      <div className="car-page__filters" style={{ padding: '12px 24px', display: 'flex', gap: 8, flexWrap: 'wrap', alignItems: 'center', borderBottom: '1px solid var(--pg-rule)' }}>
        <span style={{ fontFamily: 'var(--font-mono)', fontSize: 10, color: 'var(--pg-gray-2)', textTransform: 'uppercase', letterSpacing: '0.1em', marginRight: 4 }}>Ordenar:</span>
        {['relevance', 'views', 'date'].map(s => (
          <button key={s} onClick={() => setSortBy(s)}
            style={{ fontFamily: 'var(--font-mono)', fontSize: 10, textTransform: 'uppercase', letterSpacing: '0.1em',
              padding: '3px 10px', border: '1px solid var(--pg-gray)', borderRadius: 'var(--radius)',
              background: sortBy === s ? 'var(--pg-gold)' : 'transparent',
              color: sortBy === s ? '#000' : 'var(--pg-gray-2)', cursor: 'pointer' }}>
            {s === 'relevance' ? 'Relevância' : s === 'views' ? 'Mais vistos' : 'Mais recentes'}
          </button>
        ))}
        {carList.length > 0 && (
          <>
            <span style={{ fontFamily: 'var(--font-mono)', fontSize: 10, color: 'var(--pg-rule)', margin: '0 4px' }}>|</span>
            <span style={{ fontFamily: 'var(--font-mono)', fontSize: 10, color: 'var(--pg-gray-2)', textTransform: 'uppercase', letterSpacing: '0.1em' }}>Carro:</span>
            <button onClick={() => setActiveCar(null)}
              style={{ fontFamily: 'var(--font-mono)', fontSize: 10, textTransform: 'uppercase',
                padding: '3px 10px', border: '1px solid var(--pg-gray)', borderRadius: 'var(--radius)',
                background: !activeCar ? 'var(--pg-gold)' : 'transparent',
                color: !activeCar ? '#000' : 'var(--pg-gray-2)', cursor: 'pointer' }}>
              Todos
            </button>
            {carList.map(([car, n]) => (
              <button key={car} onClick={() => setActiveCar(activeCar === car ? null : car)}
                style={{ fontFamily: 'var(--font-mono)', fontSize: 10, textTransform: 'uppercase',
                  padding: '3px 10px', border: '1px solid var(--pg-gray)', borderRadius: 'var(--radius)',
                  background: activeCar === car ? 'var(--pg-gold)' : 'transparent',
                  color: activeCar === car ? '#000' : 'var(--pg-gray-2)', cursor: 'pointer' }}>
                {car} ({n})
              </button>
            ))}
          </>
        )}
      </div>

      {/* ── LISTA DE RESULTADOS ── */}
      <div className="car-page__body" style={{ padding: '20px 24px' }}>
        {displayed.length === 0 ? (
          <p style={{ color: 'var(--pg-gray-2)', fontFamily: 'var(--font-mono)', fontSize: 12 }}>
            Nenhum vídeo encontrado para esta busca.
          </p>
        ) : (
          <div className="video-grid" style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(280px, 1fr))', gap: 12 }}>
            {displayed.map(v => (
              <div key={v.id} className="vcard" onClick={() => onOpen(v)}
                style={{ background: '#ffffff', border: '1px solid var(--pg-rule)', borderRadius: 'var(--radius-card)', cursor: 'pointer', overflow: 'hidden' }}>
                <div style={{ position: 'relative' }}>
                  <img src={`https://i.ytimg.com/vi/${v.id}/hqdefault.jpg`} alt="" loading="lazy"
                    style={{ width: '100%', aspectRatio: '16/9', objectFit: 'cover', display: 'block' }} />
                  <div style={{ position: 'absolute', bottom: 4, right: 6, background: 'rgba(0,0,0,.75)', color: '#fff',
                    fontFamily: 'var(--font-mono)', fontSize: 10, padding: '1px 5px', borderRadius: 2 }}>
                    {v.duration}
                  </div>
                </div>
                <div style={{ padding: '8px 10px 10px' }}>
                  <div style={{ fontFamily: 'var(--font-head)', fontSize: 13, fontWeight: 700, lineHeight: 1.3,
                    marginBottom: 4, overflow: 'hidden', display: '-webkit-box', WebkitLineClamp: 2, WebkitBoxOrient: 'vertical' }}>
                    {v.title}
                  </div>
                  {v.sintomaPrincipal && (
                    <div style={{ fontFamily: 'var(--font-mono)', fontSize: 10, color: 'var(--pg-gold-deep)',
                      letterSpacing: '0.05em', marginBottom: 4, overflow: 'hidden', whiteSpace: 'nowrap', textOverflow: 'ellipsis' }}>
                      ▸ {v.sintomaPrincipal}
                    </div>
                  )}
                  <div style={{ fontFamily: 'var(--font-mono)', fontSize: 10, color: 'var(--pg-gray-2)',
                    display: 'flex', gap: 8, textTransform: 'uppercase', letterSpacing: '0.08em' }}>
                    <span>{fmtViews(v.views)} views</span>
                    {v.carModel && <span style={{ color: 'var(--pg-gold-deep)' }}>· {v.carModel}</span>}
                    <span>· {fmtDate(v.date)}</span>
                  </div>
                </div>
              </div>
            ))}
          </div>
        )}
      </div>
    </div>
  );
}

Object.assign(window, { VideoPage, TopicPage, CarPage, Home, AboutPage, SearchPage });
