// ADAPTADOR — converte o banco real (window.DEPOIMENTOS) no formato das telas.
// Nada hardcoded: tudo vem de dados.js (gerado de banco/depoimentos.json).

const RAW = (window.DEPOIMENTOS || []).slice();

/* ---------- helpers ---------- */
function norm(s) {
  return (s || '').normalize('NFD').replace(/[̀-ͯ]/g, '').toLowerCase();
}
function hexA(hex, a) {
  const h = (hex || '#9AA29D').replace('#', '');
  const n = parseInt(h.length === 3 ? h.split('').map(c => c + c).join('') : h, 16);
  return `rgba(${(n >> 16) & 255}, ${(n >> 8) & 255}, ${n & 255}, ${a})`;
}
function moneyShort(n) {
  if (!n || isNaN(n)) return '';
  if (n >= 1e6) {
    const m = Math.round((n / 1e6) * 10) / 10;
    return 'R$ ' + (Number.isInteger(m) ? m : m.toFixed(1).replace('.', ',')) + ' mi';
  }
  if (n >= 1e3) return 'R$ ' + Math.round(n / 1e3) + ' mil';
  return 'R$ ' + n;
}
function baseName(p) { return (p || '').split('/').pop().split('; ')[0]; }

/* ---------- tipo de depoimento -> rótulo + cor (tema escuro) ---------- */
const TIPO_MAP = {
  'resultado-financeiro':  { label: 'Resultado',   color: '#3ECF8E' },
  'primeira-venda':        { label: '1ª venda',    color: '#5B9DF9' },
  'validacao-metodo':      { label: 'Método',      color: '#FBBF24' },
  'superacao-ceticismo':   { label: 'Ceticismo',   color: '#F43F5E' },
  'reducao-custo':         { label: 'Custo',       color: '#2DD4BF' },
  'velocidade':            { label: 'Velocidade',  color: '#FBBF24' },
  'autoridade':            { label: 'Autoridade',  color: '#B98AFF' },
  'transformacao-pessoal': { label: 'Virada',      color: '#2DD4BF' },
};
function tipoInfo(t) { return TIPO_MAP[t] || { label: 'Outro', color: '#9AA29D' }; }
const TIPO_BY_LABEL = {};
Object.values(TIPO_MAP).forEach(v => { TIPO_BY_LABEL[v.label] = v; });

/* ---------- mídia / fonte ---------- */
function mediaKind(m) {
  return m === 'imagem' ? 'print' : m === 'texto' ? 'text' : m === 'audio' ? 'audio' : 'video';
}
function sourceLabel(f) {
  const s = norm(f);
  if (s.includes('whats')) return 'WhatsApp';
  if (s.includes('call') || s.includes('vid')) return 'Vídeo';
  if (s.includes('insta')) return 'Instagram';
  if (s.includes('print')) return 'Print';
  if (s.includes('text')) return 'Texto';
  return 'Print';
}
const MEDIA_LABEL = { video: 'Vídeo', audio: 'Áudio', print: 'Imagem', text: 'Texto' };

/* ---------- adapta cada depoimento ---------- */
function adapt(d) {
  const ti = tipoInfo(d.tipo_depoimento);
  const valor = typeof d.valor === 'number' ? d.valor : 0;
  const vlabel = d.valor_label || moneyShort(valor) || '';
  const vcurto = valor >= 1000 ? moneyShort(valor) : (vlabel || '');
  const vrs = vcurto.indexOf('R$') === 0;
  return {
    id: d.id,
    nome: d.nome || 'Cliente',
    mercado: d.mercado || '',
    nichoCanon: d.nicho_canon || 'Não classificado',
    tipo: d.tipo_depoimento || '',
    tipoLabel: ti.label,
    tipoColor: ti.color,
    midia: mediaKind(d.midia),
    midiaLabel: MEDIA_LABEL[mediaKind(d.midia)] || 'Mídia',
    fonte: sourceLabel(d.fonte),
    data: d.data || '',
    headline: d.headline || d.transformacao || d.resumo || '',
    valor: valor,
    valorLabel: vlabel,
    valorCurto: vcurto,
    valorRS: vrs,
    valorMag: vrs ? vcurto.replace(/^R\$\s*/, '') : vcurto,
    metrica: d.metrica || '',
    resumo: d.resumo || '',
    citacao: d.citacao || '',
    kill: d.kill || d.transformacao || '',
    antes: d.antes || '',
    depois: d.depois || '',
    transformacao: d.transformacao || '',
    objecoes: d.objecoes_resolvidas || [],
    objecoesCanon: d.objecoes || [],
    classes: d.classes || [],
    nichoInferido: !!d.nicho_inferido,
    forte: d.forca === 'alta',
    origem: baseName(d.origem),
    midiaWeb: d._midia || null,
    _raw: d,
  };
}

const DEPS = RAW.map(adapt);

/* ---------- estatísticas do painel ---------- */
const moneyVals = DEPS.filter(t => t.valor >= 1000).map(t => t.valor);
const somaValor = moneyVals.reduce((a, b) => a + b, 0);
const ticketMedio = moneyVals.length ? Math.round(somaValor / moneyVals.length) : 0;
const nichoCount = {};
DEPS.forEach(t => { if (t.mercado) nichoCount[t.mercado] = (nichoCount[t.mercado] || 0) + 1; });
const nichoTop = Object.entries(nichoCount).sort((a, b) => b[1] - a[1])[0];
const fortes = DEPS.filter(t => t.forte).length;

const DASH = {
  total: DEPS.length,
  somaLabel: somaValor >= 1e6 ? 'R$ ' + (somaValor / 1e6).toFixed(1).replace('.', ',') + ' mi' : moneyShort(somaValor),
  ticketLabel: ticketMedio ? moneyShort(ticketMedio) : '—',
  nichoTop: nichoTop ? nichoTop[0] : '—',
  fortesPct: DEPS.length ? Math.round((fortes / DEPS.length) * 100) + '%' : '—',
};

/* ---------- distribuição por tipo ---------- */
const tipoCount = {};
DEPS.forEach(t => {
  tipoCount[t.tipoLabel] = tipoCount[t.tipoLabel] || { name: t.tipoLabel, count: 0, color: t.tipoColor };
  tipoCount[t.tipoLabel].count++;
});
const TIPOS_DIST = Object.values(tipoCount).sort((a, b) => b.count - a.count);

/* ---------- NOVA classificação: nicho · objeção (11 fixas) · classe (4) ---------- */
const CLASS_COLOR = {
  'Faturamento': '#3ECF8E',
  'Salto de faturamento': '#5B9DF9',
  'Aumento de ticket': '#B98AFF',
  'Aumento de conversão': '#FBBF24',
};
const CLASSES_LIST = ['Faturamento', 'Salto de faturamento', 'Aumento de ticket', 'Aumento de conversão'];
const OBJ_CANON = [
  'Não confia no método',
  'Não acredita que traz retorno/ROI',
  'Não acredita que consegue ter resultado',
  'Não acredita que funciona',
  'Não entendeu o diferencial',
  'Não funciona para o meu nicho',
  'Não entendo nada de funis',
  'Não tenho dinheiro agora',
  'Não tenho tempo',
  'É muito complicado',
  'Não consigo fazer sozinho',
];
// nichos canônicos únicos (ordenados por volume, depois alfabético)
const nichoMap = {};
DEPS.forEach(t => { const n = (t.nichoCanon || '').trim(); if (n) nichoMap[n] = (nichoMap[n] || 0) + 1; });
const NAO_CLASS = 'Não classificado';
const NICHOS = Object.keys(nichoMap).sort((a, b) => {
  if (a === NAO_CLASS) return 1; if (b === NAO_CLASS) return -1; // "Não classificado" sempre por último
  return (nichoMap[b] - nichoMap[a]) || a.localeCompare(b, 'pt');
});
// contagem por objeção e por classe (para os rótulos dos filtros)
const objCanonCount = {}; OBJ_CANON.forEach(o => objCanonCount[o] = 0);
const classCount = {}; CLASSES_LIST.forEach(c => classCount[c] = 0);
DEPS.forEach(t => {
  (t.objecoesCanon || []).forEach(o => { if (o in objCanonCount) objCanonCount[o]++; });
  (t.classes || []).forEach(c => { if (c in classCount) classCount[c]++; });
});
const CLASSES_DIST = CLASSES_LIST.map(c => ({ name: c, count: classCount[c], color: CLASS_COLOR[c] })).sort((a, b) => b.count - a.count);
// opções dos filtros (com contagem GLOBAL) — fallback estático
const NICHO_OPTS = NICHOS.map(n => ({ value: n, label: n, count: nichoMap[n] }));
const OBJ_OPTS = OBJ_CANON.map(o => ({ value: o, label: o, count: objCanonCount[o] })).filter(o => o.count > 0);

// contagem REATIVA (faceted): cada eixo conta respeitando os OUTROS filtros ativos,
// menos ele mesmo. Assim o número ao lado da opção = quantos abrem se você escolher ela
// DADO o que já está selecionado. Some sozinho = contagem global.
function _matchExcept(t, f, except) {
  if (except !== 'nicho' && f.nicho && t.nichoCanon !== f.nicho) return false;
  if (except !== 'objecao' && f.objecao && !(t.objecoesCanon || []).includes(f.objecao)) return false;
  if (except !== 'classes' && f.classes && f.classes.length && !(t.classes || []).some(c => f.classes.includes(c))) return false;
  if (f.search) {
    const ql = norm(f.search);
    const blob = norm([t.headline, t.nome, t.mercado, t.resumo, t.kill, (t.objecoes || []).join(' '), (t.objecoesCanon || []).join(' '), (t.classes || []).join(' ')].join(' '));
    if (!blob.includes(ql)) return false;
  }
  return true;
}
function facetOptions(f) {
  f = f || { nicho: '', objecao: '', classes: [], search: '' };
  const nC = {}, oC = {};
  DEPS.forEach(t => {
    if (_matchExcept(t, f, 'nicho')) { const n = (t.nichoCanon || '').trim(); if (n) nC[n] = (nC[n] || 0) + 1; }
    if (_matchExcept(t, f, 'objecao')) (t.objecoesCanon || []).forEach(o => { if (OBJ_CANON.includes(o)) oC[o] = (oC[o] || 0) + 1; });
  });
  const nicho = NICHOS.map(n => ({ value: n, label: n, count: nC[n] || 0 })).filter(o => o.count > 0 || o.value === f.nicho);
  const obj = OBJ_CANON.map(o => ({ value: o, label: o, count: oC[o] || 0 })).filter(o => o.count > 0 || o.value === f.objecao);
  return { nicho, obj };
}

/* ---------- objeções mais resolvidas ---------- */
const objCount = {};
DEPS.forEach(t => t.objecoes.forEach(o => { const k = (o || '').trim(); if (k) objCount[k] = (objCount[k] || 0) + 1; }));
const OBJ_TOP = Object.entries(objCount).map(([label, count]) => ({ label, count })).sort((a, b) => b.count - a.count).slice(0, 8);

/* ---------- feed recente (dados.js já vem do mais recente ao mais antigo) ---------- */
const RECENTES = DEPS.slice(0, 8);

/* ---------- ranking de maiores resultados financeiros ---------- */
function rankFinanceiro() {
  return DEPS.filter(t => t.valor >= 1000).sort((a, b) => b.valor - a.valor);
}

/* ---------- matador de objeção (ranking semântico) ---------- */
function rankObjecao(query) {
  const terms = norm(query).split(/\W+/).filter(w => w.length > 2);
  const scored = DEPS.map(t => {
    const objBlob = norm(t.objecoes.concat(t.objecoesCanon).join(' '));
    const killBlob = norm(t.kill);
    const restBlob = norm([t.resumo, t.mercado, t.tipo, t.headline].join(' '));
    let s = 0;
    terms.forEach(term => {
      if (objBlob.includes(term)) s += 5;
      if (killBlob.includes(term)) s += 3;
      if (restBlob.includes(term)) s += 1;
    });
    if (t.forte) s += 2;
    s += Math.min(3, t.valor / 100000);
    return { t, s };
  });
  if (terms.length) {
    return scored.filter(x => x.s > 0).sort((a, b) => b.s - a.s || b.t.valor - a.t.valor).slice(0, 10).map(x => x.t);
  }
  return scored.sort((a, b) => (b.t.forte - a.t.forte) || (b.t.valor - a.t.valor)).slice(0, 10).map(x => x.t);
}

Object.assign(window, {
  DEPS, DASH, TIPOS_DIST, OBJ_TOP, RECENTES,
  CLASS_COLOR, CLASSES_LIST, CLASSES_DIST, OBJ_CANON, NICHOS, NICHO_OPTS, OBJ_OPTS, facetOptions,
  TIPO_BY_LABEL, MEDIA_LABEL, rankObjecao, rankFinanceiro, hexA, norm, moneyShort,
});
