// ═══════════════════════════════════════════════════════════════════════════
// AVD · Evolução entre avaliações
// Pedido do G&C (05/08): "um local onde eu possa comparar numa tela só as notas
// de cada colaborador entre avaliações, pra notar a evolução avaliação após
// avaliação, e analisar a porcentagem que subiu ou decaiu".
//
// Uma linha por pessoa, uma coluna por ciclo, na ordem cronológica — e a
// variação do ciclo mais recente contra o anterior, em pontos e em %.
//
// A conta é a MESMA de todas as outras telas (agregarNotasAvd, data.jsx),
// ciclo a ciclo. Nada de régua nova aqui: a cor sai de AVD_FAIXAS, como no
// resultado individual e no painel. Régua duplicada é bug silencioso.
// ═══════════════════════════════════════════════════════════════════════════

// A métrica que a tela compara. 'final' é a nota que vale (par + líder +
// liderados, ponderada); as outras existem porque "subiu" e "subiu em quê" são
// perguntas diferentes — uma pessoa pode subir em performance e cair em
// comportamental com a final parada.
const EVO_METRICAS = [
  { id: 'final',          label: 'Nota final' },
  { id: 'organizacional', label: 'Organizacional' },
  { id: 'comportamental', label: 'Comportamental' },
  { id: 'performance',    label: 'Performance' },
  { id: 'auto',           label: 'Autoavaliação' },
];

// Tira de um agregado a métrica pedida. 'combinado' (par + líder + liderados) é
// a base das categorias pelo mesmo motivo da tela de resultados: não misturar
// duas médias com regras diferentes.
function _evoValor(agg, metrica) {
  if (!agg) return null;
  if (metrica === 'final') return agg.final;
  if (metrica === 'auto')  return agg.auto ? agg.auto.geral : null;
  return agg.combinado ? (agg.combinado.porCategoria[metrica] ?? null) : null;
}

// Variação entre dois pontos: em pontos da escala e em % relativo.
// De 0 não existe variação percentual (divisão por zero) — devolve só os
// pontos, e a tela mostra "—" no lugar do %.
function _evoDelta(antes, depois) {
  if (antes == null || depois == null) return null;
  const pontos = Math.round((depois - antes) * 100) / 100;
  const pct = antes === 0 ? null : Math.round((pontos / antes) * 1000) / 10;
  return { pontos, pct };
}

const EvoDelta = ({ delta, forte }) => {
  if (!delta) return <span style={{ color: 'var(--escalab-mute)', fontSize: 12 }}>–</span>;
  const sobe = delta.pontos > 0, desce = delta.pontos < 0;
  const cor = sobe ? '#00836B' : desce ? '#B3261E' : 'var(--escalab-mute)';
  const seta = sobe ? '▲' : desce ? '▼' : '=';
  const n = v => (v > 0 ? '+' : '') + String(v).replace('.', ',');
  return (
    <span style={{ color: cor, fontWeight: 700, fontSize: forte ? 13 : 12, whiteSpace: 'nowrap' }}>
      {seta} {n(delta.pontos)}
      {delta.pct != null && <span style={{ fontWeight: 600, opacity: .85 }}> ({n(delta.pct)}%)</span>}
    </span>
  );
};

// Faixa fina com o caminho da pessoa entre os ciclos — dá pra ler a tendência
// sem comparar número por número.
const EvoSparkline = ({ valores }) => {
  const pts = valores.filter(v => v != null);
  if (pts.length < 2) return null;
  const L = 92, A = 22;
  const passo = L / (valores.length - 1);
  const y = v => A - 2 - ((v / 5) * (A - 4));
  let d = '', primeiro = true;
  valores.forEach((v, i) => {
    if (v == null) return;
    d += `${primeiro ? 'M' : 'L'}${(i * passo).toFixed(1)},${y(v).toFixed(1)} `;
    primeiro = false;
  });
  const ultimo = pts[pts.length - 1], anterior = pts[pts.length - 2];
  const cor = ultimo > anterior ? '#00836B' : ultimo < anterior ? '#B3261E' : 'var(--escalab-mute)';
  return (
    <svg width={L} height={A} style={{ display: 'block', flexShrink: 0 }} aria-hidden="true">
      <path d={d.trim()} fill="none" stroke={cor} strokeWidth="1.8" strokeLinejoin="round" strokeLinecap="round" />
      {valores.map((v, i) => v == null ? null : (
        <circle key={i} cx={(i * passo).toFixed(1)} cy={y(v).toFixed(1)} r="2" fill={cor} />
      ))}
    </svg>
  );
};

// Linha de uma pessoa; abre nas categorias, ciclo a ciclo.
const EvoLinha = ({ item, ciclos, respostas }) => {
  const [aberta, setAberta] = React.useState(false);
  const cats = ['organizacional', 'comportamental', 'performance'];
  return (
    <React.Fragment>
      <tr onClick={() => setAberta(v => !v)} style={{ borderBottom: '1px solid var(--escalab-line)', cursor: 'pointer' }}>
        <td style={{ padding: '8px 10px' }}>
          <div style={{ display: 'flex', alignItems: 'center', gap: 9 }}>
            <span style={{ width: 12, color: 'var(--escalab-mute)', fontSize: 11 }}>{aberta ? '▾' : '▸'}</span>
            <div style={{ width: 28, height: 28, borderRadius: '50%', background: item.colab.cor, color: '#fff', fontWeight: 700, fontSize: 10.5, display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }}>{item.colab.iniciais}</div>
            <div style={{ minWidth: 0 }}>
              <div style={{ fontSize: 13, fontWeight: 600, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{(item.colab.nome || '').split(' ').slice(0, 2).join(' ')}</div>
              <div style={{ fontSize: 10.5, color: 'var(--escalab-mute)' }}>{item.colab.setor}</div>
            </div>
          </div>
        </td>
        {item.valores.map((v, i) => (
          <td key={ciclos[i].id} style={{ textAlign: 'center', padding: '8px 8px' }}><NotaPill nota={v} /></td>
        ))}
        <td style={{ textAlign: 'center', padding: '8px 8px' }}><EvoSparkline valores={item.valores} /></td>
        <td style={{ textAlign: 'right', padding: '8px 12px', borderLeft: '1px solid var(--escalab-line)' }}>
          <EvoDelta delta={item.delta} forte />
        </td>
      </tr>
      {aberta && cats.map(cat => {
        const vals = ciclos.map(c => {
          const agg = agregarNotasAvd(item.colab.id, c.id, respostas);
          return _evoValor(agg, cat);
        });
        const ult = vals.filter(v => v != null);
        const d = ult.length >= 2 ? _evoDelta(ult[ult.length - 2], ult[ult.length - 1]) : null;
        return (
          <tr key={cat} style={{ borderBottom: '1px solid var(--escalab-line)', background: 'var(--escalab-paper)' }}>
            <td style={{ padding: '5px 10px 5px 60px', fontSize: 12, color: 'var(--escalab-slate)' }}>{AVD_CAT_NOME[cat]}</td>
            {vals.map((v, i) => <td key={ciclos[i].id} style={{ textAlign: 'center', padding: '5px 8px' }}><NotaPill nota={v} /></td>)}
            <td />
            <td style={{ textAlign: 'right', padding: '5px 12px', borderLeft: '1px solid var(--escalab-line)' }}><EvoDelta delta={d} /></td>
          </tr>
        );
      })}
    </React.Fragment>
  );
};

const EvolucaoAvdView = ({ user }) => {
  const [carregando, setCarregando] = React.useState(true);
  const [erro, setErro] = React.useState(null);
  const [metrica, setMetrica] = React.useState('final');
  const [setor, setSetor] = React.useState('');
  const [ordem, setOrdem] = React.useState('variacao'); // variacao | nota | nome

  React.useEffect(() => {
    let vivo = true;
    (async () => {
      setCarregando(true);
      const r = typeof fetchAvdRespostasTodasSupabase === 'function' ? await fetchAvdRespostasTodasSupabase() : null;
      if (!vivo) return;
      if (r == null) setErro('Não consegui ler as respostas (precisa ser admin e ter rodado o 073).');
      setCarregando(false);
    })();
    return () => { vivo = false; };
  }, []);

  const colabs = (typeof COLABORADORES !== 'undefined' ? COLABORADORES : []);
  const respostas = (typeof AVD_RESPOSTAS_TODAS !== 'undefined' ? AVD_RESPOSTAS_TODAS : []);

  // Só entram ciclos que TÊM nota. Um ciclo vazio viraria uma coluna de traços
  // e, pior, um "caiu 100%" falso na comparação com o seguinte. A ordem é a de
  // `inicio` (fetchCiclos já traz ascendente) — é o eixo do tempo da tela.
  const ciclos = React.useMemo(() => {
    const comNota = new Set(respostas.filter(r => r.nota != null).map(r => r.cicloId || ''));
    return (typeof CICLOS !== 'undefined' ? CICLOS : [])
      .filter(c => comNota.has(c.id))
      .sort((a, b) => String(a.inicio || '').localeCompare(String(b.inicio || '')));
  }, [respostas, carregando]);

  const linhas = React.useMemo(() => {
    if (!ciclos.length) return [];
    return colabs.map(c => {
      const valores = ciclos.map(ci => _evoValor(agregarNotasAvd(c.id, ci.id, respostas), metrica));
      const preenchidos = valores.filter(v => v != null);
      const delta = preenchidos.length >= 2
        ? _evoDelta(preenchidos[preenchidos.length - 2], preenchidos[preenchidos.length - 1]) : null;
      return { colab: c, valores, delta, ultima: preenchidos.length ? preenchidos[preenchidos.length - 1] : null };
    }).filter(x => x.valores.some(v => v != null));
  }, [ciclos, colabs, respostas, metrica]);

  if (carregando) return <div style={{ padding: 30, textAlign: 'center', color: 'var(--escalab-mute)', fontSize: 14 }}>Carregando respostas…</div>;
  if (erro) return <div style={{ background: '#FDECEC', border: '1px solid #f5b5b0', borderRadius: 10, padding: '12px 15px', fontSize: 13, color: '#B3261E' }}>{erro}</div>;

  const setores = [...new Set(linhas.map(x => x.colab.setor).filter(Boolean))].sort((a, b) => a.localeCompare(b));
  const filtradas = linhas
    .filter(x => !setor || x.colab.setor === setor)
    .sort((a, b) => {
      if (ordem === 'nome') return String(a.colab.nome).localeCompare(String(b.colab.nome));
      if (ordem === 'nota') return (b.ultima ?? -1) - (a.ultima ?? -1);
      // Por variação: quem mais caiu primeiro — é o que exige ação. Quem não
      // tem dois ciclos não tem variação e vai pro fim, não pro topo.
      const va = a.delta ? a.delta.pontos : null, vb = b.delta ? b.delta.pontos : null;
      if (va == null && vb == null) return String(a.colab.nome).localeCompare(String(b.colab.nome));
      if (va == null) return 1;
      if (vb == null) return -1;
      return va - vb;
    });

  const comDelta = filtradas.filter(x => x.delta);
  const subiram = comDelta.filter(x => x.delta.pontos > 0).length;
  const cairam  = comDelta.filter(x => x.delta.pontos < 0).length;
  const mediaVar = comDelta.length
    ? Math.round((comDelta.reduce((s, x) => s + x.delta.pontos, 0) / comDelta.length) * 100) / 100 : null;

  const selEstilo = { border: '1px solid var(--escalab-line)', borderRadius: 8, padding: '8px 11px', fontSize: 13, fontFamily: 'var(--font-sans)', background: '#fff', outline: 'none' };

  return (
    <div>
      <div style={{ display: 'flex', gap: 10, alignItems: 'center', flexWrap: 'wrap', marginBottom: 16 }}>
        <select value={metrica} onChange={e => setMetrica(e.target.value)} style={selEstilo}>
          {EVO_METRICAS.map(m => <option key={m.id} value={m.id}>{m.label}</option>)}
        </select>
        <select value={setor} onChange={e => setSetor(e.target.value)} style={selEstilo}>
          <option value="">Todos os setores</option>
          {setores.map(s => <option key={s} value={s}>{s}</option>)}
        </select>
        <select value={ordem} onChange={e => setOrdem(e.target.value)} style={selEstilo}>
          <option value="variacao">Ordenar: quem mais caiu</option>
          <option value="nota">Ordenar: maior nota atual</option>
          <option value="nome">Ordenar: nome</option>
        </select>
      </div>

      {ciclos.length === 0 && (
        <div style={{ background: 'var(--escalab-paper)', border: '1px dashed var(--escalab-line)', borderRadius: 10, padding: 20, textAlign: 'center', color: 'var(--escalab-mute)', fontSize: 13.5 }}>
          Nenhum ciclo com nota lançada ainda. Esta tela se preenche sozinha conforme os ciclos vão fechando.
        </div>
      )}

      {ciclos.length === 1 && (
        <div style={{ background: '#fff8e1', border: '1px solid #f5c518', borderRadius: 10, padding: '11px 14px', marginBottom: 14, fontSize: 13, color: '#5a4500', lineHeight: 1.5 }}>
          <strong>Só há um ciclo com notas ({ciclos[0].nome}).</strong> A comparação aparece a partir do segundo — as colunas de variação ficam vazias até lá.
        </div>
      )}

      {ciclos.length > 0 && (
        <div>
          {comDelta.length > 0 && (
            <div style={{ display: 'flex', gap: 12, flexWrap: 'wrap', marginBottom: 16 }}>
              {[
                { rot: 'Subiram',        val: subiram,       cor: '#00836B' },
                { rot: 'Caíram',         val: cairam,        cor: '#B3261E' },
                { rot: 'Sem mudança',    val: comDelta.length - subiram - cairam, cor: 'var(--escalab-mute)' },
                { rot: 'Variação média', val: mediaVar == null ? '–' : (mediaVar > 0 ? '+' : '') + String(mediaVar).replace('.', ','), cor: mediaVar > 0 ? '#00836B' : mediaVar < 0 ? '#B3261E' : 'var(--escalab-mute)' },
              ].map(k => (
                <div key={k.rot} style={{ flex: '1 1 130px', border: '1px solid var(--escalab-line)', borderRadius: 12, padding: '12px 15px' }}>
                  <div style={{ fontSize: 10.5, fontWeight: 700, letterSpacing: '.07em', textTransform: 'uppercase', color: 'var(--escalab-mute)' }}>{k.rot}</div>
                  <div style={{ fontSize: 25, fontWeight: 900, color: k.cor, lineHeight: 1.15 }}>{k.val}</div>
                </div>
              ))}
            </div>
          )}

          <div style={{ fontSize: 11.5, color: 'var(--escalab-mute)', marginBottom: 10, lineHeight: 1.5 }}>
            A variação compara os <strong>dois ciclos mais recentes em que a pessoa tem nota</strong> — não necessariamente as duas últimas colunas, porque nem todo mundo é avaliado em todo ciclo.
            {' '}Clique numa linha para abrir a evolução por categoria.
          </div>

          <div style={{ overflowX: 'auto' }}>
            <table style={{ width: '100%', borderCollapse: 'collapse', fontSize: 13, minWidth: 620 }}>
              <thead>
                <tr style={{ borderBottom: '1px solid var(--escalab-line)' }}>
                  <th style={{ textAlign: 'left', padding: '8px 10px', color: 'var(--escalab-mute)', fontWeight: 600 }}>Colaborador</th>
                  {ciclos.map(c => (
                    <th key={c.id} title={c.nome} style={{ textAlign: 'center', padding: '8px 8px', color: 'var(--escalab-brand)', fontWeight: 700, minWidth: 78 }}>
                      {c.nome}
                      <div style={{ fontSize: 10, fontWeight: 500, color: 'var(--escalab-mute)' }}>{c.inicio ? String(c.inicio).slice(0, 7).split('-').reverse().join('/') : ''}</div>
                    </th>
                  ))}
                  <th style={{ textAlign: 'center', padding: '8px 8px', color: 'var(--escalab-mute)', fontWeight: 600 }}>Trajetória</th>
                  <th style={{ textAlign: 'right', padding: '8px 12px', color: 'var(--escalab-brand)', fontWeight: 700, borderLeft: '1px solid var(--escalab-line)' }}>Variação</th>
                </tr>
              </thead>
              <tbody>
                {filtradas.map(item => (
                  <EvoLinha key={item.colab.id} item={item} ciclos={ciclos} respostas={respostas} />
                ))}
                {!filtradas.length && (
                  <tr><td colSpan={ciclos.length + 3} style={{ padding: 14, color: 'var(--escalab-mute)', fontStyle: 'italic' }}>Ninguém com nota neste recorte.</td></tr>
                )}
              </tbody>
            </table>
          </div>
        </div>
      )}
    </div>
  );
};

window.EvolucaoAvdView = EvolucaoAvdView;
