// ═══════════════════════════════════════════════════════════════════════════
// AVD · Resultados do GC (Fase 4) — notas segmentadas
// Admin escolhe colaborador + ciclo e vê: nota final (pares+líder, sem auto),
// nota por fonte (auto/pares/líder/liderados), por categoria e por competência
// (pares × líder distintos, como o GC pediu). Fonte: agregarNotasAvd (data.jsx).
// ═══════════════════════════════════════════════════════════════════════════

const AVD_FONTES = [
  { id: 'auto',      label: 'Autoavaliação', cor: '#6B3FA0' },
  { id: 'par',       label: 'Pares',          cor: '#1F4A8A' },
  { id: 'lider',     label: 'Líder',          cor: '#00836B' },
  { id: 'liderado',  label: 'Liderados',      cor: '#B26A00' },
  // Avaliação cruzada da diretoria sobre a camada mais alta da liderança —
  // só a parte organizacional. Sem esta coluna as respostas do tipo
  // 'diretoria' eram gravadas e não apareciam em lugar nenhum. Fica FORA da
  // nota final de propósito: o G&C quer olhar pra ela em separado.
  { id: 'diretoria', label: 'Diretores',      cor: '#1F4A8A' },
];
const AVD_CAT_NOME = { organizacional: 'Organizacional', comportamental: 'Comportamental', performance: 'Performance' };

// Faixas do G&C (30/07), agora as mesmas em toda a AVD: AVD_FAIXAS em data.jsx.
// Antes disso esta tela tinha só duas (Destaque ≥ 4 / Crítico) e o painel usava
// um terceiro corte (4,25) — o mesmo 4,1 aparecia de duas cores conforme a tela.
function _notaCor(n)   { return avdFaixaCor(n); }
function _notaFaixa(n) { return avdFaixaRotulo(n); }
const NotaPill = ({ nota, forte }) => (
  <span style={{
    display: 'inline-block', minWidth: forte ? 44 : 34, textAlign: 'center',
    padding: forte ? '5px 12px' : '2px 8px', borderRadius: 8,
    fontSize: forte ? 18 : 13, fontWeight: 700,
    color: nota == null ? 'var(--escalab-mute)' : '#fff',
    background: nota == null ? 'var(--escalab-paper)' : _notaCor(nota),
  }}>{nota == null ? '–' : nota.toFixed(2)}</span>
);

// ── Resultado de UMA pessoa ───────────────────────────────────────────────────
// Esta era a segunda metade do ResultadosAvdView, e virou componente por um
// motivo concreto: a aba "Avaliações" (a primeira da AVD) mostrava, ao clicar
// numa pessoa, um painel que lia a tabela VELHA (`avaliacoes`, via getNotaColab)
// — pesos de 30/20/15/15/20 que não existem mais, "Ciclo 1º sem 2025" fixo,
// "Avaliação concluída" fixo, e nota nenhuma porque a tabela velha está vazia.
// Era o "clicando no nome de cada pessoa o dashboard está errado, não está
// sincronizado" de 03/08: as duas telas contavam a mesma coisa de dois jeitos.
// Agora existe uma conta só (agregarNotasAvd) e um componente só.
// `podeVerAbertas` (19/08): a parte qualitativa — o que as pessoas ESCREVERAM —
// é só do administrador, por decisão do Hiago. O padrão é FALSE de propósito:
// quem quiser mostrar texto tem que dizer isso em voz alta na chamada. Este
// mesmo componente serve a aba "Resultados do time" do gestor, e lá a resposta
// é não. (A pessoa avaliada não passa por aqui: a tela dela é a
// MinhaAvdResultado, que lê a RPC — e a 148 tirou o campo de lá.)
const ResultadoAvdPessoa = ({ colab, cicloId, respostas, podeVerAbertas = false }) => {
  // Competências abertas na tabela (mostram os indicadores por dentro).
  const [compsAbertas, setCompsAbertas] = React.useState([]);
  const abrirFecharComp = id => setCompsAbertas(a => a.includes(id) ? a.filter(x => x !== id) : [...a, id]);
  if (!colab) return null;

  const fonte = respostas || (typeof AVD_RESPOSTAS_TODAS !== 'undefined' ? AVD_RESPOSTAS_TODAS : []);
  const agg = agregarNotasAvd(colab.id, cicloId || null, fonte);
  const ficha = typeof montarFichaDoColaborador === 'function' ? montarFichaDoColaborador(colab) : null;
  // competenciasDoResultado (data.jsx) e não org+comportamental+performance: o
  // bloco de liderança universal (132) mora em `comportamental_lideranca`, e
  // concatenar as três categorias cruas deixava de fora as 10 competências que
  // os liderados respondem — a nota entrava no banco e a linha não existia.
  const compsOrdenadas = typeof competenciasDoResultado === 'function'
    ? competenciasDoResultado(ficha)
    : [...(ficha?.organizacional || []), ...(ficha?.comportamental || []), ...(ficha?.performance || [])];
  const temAlgo = agg && (agg.auto || agg.par || agg.lider || agg.liderado || agg.diretoria);
  const abertas = typeof getRespostasAbertasDoAvaliado === 'function'
    ? getRespostasAbertasDoAvaliado(colab.id, cicloId || null, fonte) : [];

  function mediaCompFonte(fonteResumo, compId) {
    if (!fonteResumo) return null;
    const f = fonteResumo.porCompetencia.find(x => x.id === compId);
    return f ? f.media : null;
  }
  function mediaCatFonte(fonteResumo, cat) {
    return fonteResumo ? (fonteResumo.porCategoria[cat] ?? null) : null;
  }
  // Nível INDICADOR: a frase afirmativa que recebe nota. Vem de
  // agregarNotasAvd().porIndicador (data.jsx), o mesmo agregado das outras
  // colunas — não é conta nova, é o mesmo número quebrado mais fino.
  function mediaIndFonte(fonteResumo, indId) {
    if (!fonteResumo || !fonteResumo.porIndicador) return null;
    const f = fonteResumo.porIndicador[indId];
    return f ? f.media : null;
  }
  function respostasInd(indId) {
    const f = agg && agg.combinado && agg.combinado.porIndicador ? agg.combinado.porIndicador[indId] : null;
    return f ? f.n : 0;
  }

  const prog = typeof getProgressoAvdDoAvaliado === 'function'
    ? getProgressoAvdDoAvaliado(colab.id, cicloId || null, fonte) : null;

  return (
    <div>
      {/* Andamento real: quantos dos avaliadores designados já fecharam a ficha.
          Substitui a tarja "Avaliação concluída" que a tela antiga mostrava
          sempre, para todo mundo. */}
      {prog && (
        <div style={{ display: 'flex', gap: 10, flexWrap: 'wrap', alignItems: 'center', marginBottom: 16, fontSize: 13, color: 'var(--escalab-slate)' }}>
          <span style={{
            fontSize: 11, fontWeight: 800, letterSpacing: '.05em', textTransform: 'uppercase',
            padding: '3px 10px', borderRadius: 999, color: '#fff',
            background: prog.status === 'concluida' ? '#00836B' : prog.status === 'em_andamento' ? '#C77700' : 'var(--escalab-mute)',
          }}>
            {prog.status === 'concluida' ? 'Concluída' : prog.status === 'em_andamento' ? 'Em andamento' : 'Pendente'}
          </span>
          <span>{prog.concluidos} de {prog.esperados} avaliador(es) fecharam a ficha{cicloId ? ' neste ciclo' : ''}.</span>
        </div>
      )}

      {/* Matriz da pessoa escolhida: é a "ficha de quem avalia quem, em qual
          categoria e peso" que o G&C pediu pra conferir se salvou certo. Antes
          só existia como SQL (scripts/checar_avd_matriz.sql). */}
      {typeof QuemMeAvalia !== 'undefined' && (
        <QuemMeAvalia avaliadoId={colab.id} cicloId={cicloId} titulo={`Quem avalia ${String(colab.nome || '').split(' ')[0]}`} />
      )}

      {!temAlgo && (
        <div style={{ background: 'var(--escalab-paper)', border: '1px dashed var(--escalab-line)', borderRadius: 10, padding: '20px', textAlign: 'center', color: 'var(--escalab-mute)', fontSize: 13.5 }}>
          Nenhuma resposta registrada para <strong>{String(colab.nome || '').split(' ')[0]}</strong> {cicloId ? 'neste ciclo' : ''} ainda.
        </div>
      )}

      {temAlgo && (
        <div>
          {/* Nota final + fontes */}
          <div style={{ display: 'flex', gap: 12, flexWrap: 'wrap', alignItems: 'stretch', marginBottom: 20 }}>
            <div style={{ flex: '1 1 200px', border: '2px solid var(--escalab-brand)', borderRadius: 12, padding: '14px 16px', background: 'var(--escalab-paper)' }}>
              <div style={{ fontSize: 11, fontWeight: 700, letterSpacing: '.08em', textTransform: 'uppercase', color: 'var(--escalab-brand)', marginBottom: 8 }}>Nota final</div>
              {/* Marcação inline de propósito: este arquivo não usa nenhum
                  componente do ui.jsx, e os <script type="text/babel"> não
                  compartilham os `const` de forma confiável — usar o componente
                  Tag aqui arriscaria um "Tag is not defined" em tela. */}
              <div style={{ display: 'flex', alignItems: 'center', gap: 8, flexWrap: 'wrap' }}>
                <NotaPill nota={agg.final} forte />
                {_notaFaixa(agg.final) && (
                  <span style={{
                    fontSize: 11, fontWeight: 700, letterSpacing: '.04em', textTransform: 'uppercase',
                    padding: '3px 9px', borderRadius: 999, color: '#fff', background: _notaCor(agg.final),
                  }}>{_notaFaixa(agg.final)}</span>
                )}
              </div>
              <div style={{ fontSize: 11.5, color: 'var(--escalab-mute)', marginTop: 8 }}>
                Média ponderada de pares + líder + liderados (exclui a autoavaliação). O líder pesa 2×.
                {' '}Faixas: {AVD_FAIXAS.map(f => f.rotulo + ' ≥ ' + String(f.min).replace('.', ',')).join(' · ')}.
              </div>
            </div>
            {AVD_FONTES.map(f => {
              const res = agg[f.id];
              return (
                <div key={f.id} style={{ flex: '1 1 140px', border: '1px solid var(--escalab-line)', borderRadius: 12, padding: '14px 16px' }}>
                  <div style={{ fontSize: 11, fontWeight: 700, letterSpacing: '.06em', textTransform: 'uppercase', color: f.cor, marginBottom: 8 }}>{f.label}</div>
                  <NotaPill nota={res ? res.geral : null} forte />
                  <div style={{ fontSize: 11.5, color: 'var(--escalab-mute)', marginTop: 8 }}>{res ? `${res.avaliadores} avaliador(es)` : 'sem resposta'}</div>
                </div>
              );
            })}
          </div>

          {/* Por categoria × fonte */}
          <div style={{ fontSize: 14, fontWeight: 700, margin: '4px 0 10px' }}>Por categoria</div>
          <div style={{ overflowX: 'auto', marginBottom: 22 }}>
            <table style={{ width: '100%', borderCollapse: 'collapse', fontSize: 13, minWidth: 480 }}>
              <thead>
                <tr style={{ borderBottom: '1px solid var(--escalab-line)' }}>
                  <th style={{ textAlign: 'left', padding: '8px 10px', color: 'var(--escalab-mute)', fontWeight: 600 }}>Categoria</th>
                  {AVD_FONTES.map(f => <th key={f.id} style={{ textAlign: 'center', padding: '8px 10px', color: f.cor, fontWeight: 700 }}>{f.label}</th>)}
                  <th style={{ textAlign: 'center', padding: '8px 10px', color: 'var(--escalab-brand)', fontWeight: 700, borderLeft: '1px solid var(--escalab-line)' }} title="Média de pares + líder + liderados (sem a autoavaliação)">Nota média</th>
                </tr>
              </thead>
              <tbody>
                {['organizacional', 'comportamental', 'performance'].map(cat => (
                  <tr key={cat} style={{ borderBottom: '1px solid var(--escalab-line)' }}>
                    <td style={{ padding: '8px 10px', fontWeight: 600 }}>{AVD_CAT_NOME[cat]}</td>
                    {AVD_FONTES.map(f => <td key={f.id} style={{ textAlign: 'center', padding: '8px 10px' }}><NotaPill nota={mediaCatFonte(agg[f.id], cat)} /></td>)}
                    <td style={{ textAlign: 'center', padding: '8px 10px', borderLeft: '1px solid var(--escalab-line)' }}><NotaPill nota={mediaCatFonte(agg.combinado, cat)} forte /></td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>

          {/* Por competência × fonte — cada linha abre nos indicadores dela */}
          <div style={{ display: 'flex', alignItems: 'baseline', gap: 10, flexWrap: 'wrap', margin: '4px 0 10px' }}>
            <div style={{ fontSize: 14, fontWeight: 700 }}>Por competência e indicador</div>
            <button
              onClick={() => setCompsAbertas(a => a.length ? [] : compsOrdenadas.map(c => c.id))}
              style={{ border: '1px solid var(--escalab-line)', background: '#fff', borderRadius: 7, padding: '3px 10px', fontSize: 11.5, fontWeight: 600, color: 'var(--escalab-slate)', cursor: 'pointer', fontFamily: 'var(--font-sans)' }}>
              {compsAbertas.length ? 'Recolher todos' : 'Abrir todos os indicadores'}
            </button>
            <span style={{ fontSize: 11.5, color: 'var(--escalab-mute)' }}>
              Clique numa competência para ver a nota de cada indicador — a frase afirmativa que recebeu a avaliação.
            </span>
          </div>
          <div style={{ overflowX: 'auto' }}>
            <table style={{ width: '100%', borderCollapse: 'collapse', fontSize: 12.5, minWidth: 560 }}>
              <thead>
                <tr style={{ borderBottom: '1px solid var(--escalab-line)' }}>
                  <th style={{ textAlign: 'left', padding: '8px 10px', color: 'var(--escalab-mute)', fontWeight: 600 }}>Competência</th>
                  {AVD_FONTES.map(f => <th key={f.id} style={{ textAlign: 'center', padding: '8px 8px', color: f.cor, fontWeight: 700 }}>{f.label}</th>)}
                  <th style={{ textAlign: 'center', padding: '8px 8px', color: 'var(--escalab-brand)', fontWeight: 700, borderLeft: '1px solid var(--escalab-line)' }} title="Média de pares + líder + liderados (sem a autoavaliação)">Nota média</th>
                </tr>
              </thead>
              <tbody>
                {compsOrdenadas.map((comp, i) => {
                  const catAnt = i > 0 ? compsOrdenadas[i - 1].categoria : null;
                  const novaCat = comp.categoria !== catAnt;
                  const aberta = compsAbertas.includes(comp.id);
                  return (
                    <React.Fragment key={comp.id}>
                      {novaCat && (
                        <tr style={{ background: 'var(--escalab-paper)' }}>
                          {/* +2: a coluna da competência e a de "Nota média" */}
                          <td colSpan={AVD_FONTES.length + 2} style={{ padding: '5px 10px', fontSize: 10.5, fontWeight: 700, letterSpacing: '.06em', textTransform: 'uppercase', color: 'var(--escalab-brand)' }}>
                            {AVD_CAT_NOME[comp.categoria]}
                          </td>
                        </tr>
                      )}
                      <tr onClick={() => abrirFecharComp(comp.id)}
                          style={{ borderBottom: '1px solid var(--escalab-line)', cursor: (comp.indicadores || []).length ? 'pointer' : 'default' }}>
                        <td style={{ padding: '7px 10px' }}>
                          <span style={{ display: 'inline-block', width: 14, color: 'var(--escalab-mute)', fontSize: 11 }}>
                            {(comp.indicadores || []).length ? (aberta ? '▾' : '▸') : ''}
                          </span>
                          {comp.nome}
                          {comp.lideranca && (
                            <span title="Bloco de liderança: quem responde é o liderado" style={{ fontSize: 9.5, fontWeight: 800, letterSpacing: '.05em', textTransform: 'uppercase', color: '#B26A00', background: '#B26A0018', padding: '1px 6px', borderRadius: 999, marginLeft: 6 }}>liderança</span>
                          )}
                          {(comp.indicadores || []).length > 0 && (
                            <span style={{ fontSize: 10.5, color: 'var(--escalab-mute)', marginLeft: 6 }}>
                              {comp.indicadores.length} indicador(es)
                            </span>
                          )}
                        </td>
                        {AVD_FONTES.map(f => <td key={f.id} style={{ textAlign: 'center', padding: '7px 8px' }}><NotaPill nota={mediaCompFonte(agg[f.id], comp.id)} /></td>)}
                        <td style={{ textAlign: 'center', padding: '7px 8px', borderLeft: '1px solid var(--escalab-line)' }}><NotaPill nota={mediaCompFonte(agg.combinado, comp.id)} forte /></td>
                      </tr>

                      {aberta && (comp.indicadores || []).map(ind => (
                        <tr key={ind.id} style={{ borderBottom: '1px solid var(--escalab-line)', background: 'var(--escalab-paper)' }}>
                          <td style={{ padding: '6px 10px 6px 34px', fontSize: 12, color: 'var(--escalab-slate)', lineHeight: 1.35 }}>
                            {ind.texto}
                            <span style={{ fontSize: 10.5, color: 'var(--escalab-mute)', marginLeft: 6, whiteSpace: 'nowrap' }}>
                              · {respostasInd(ind.id)} resp.
                            </span>
                          </td>
                          {AVD_FONTES.map(f => <td key={f.id} style={{ textAlign: 'center', padding: '6px 8px' }}><NotaPill nota={mediaIndFonte(agg[f.id], ind.id)} /></td>)}
                          <td style={{ textAlign: 'center', padding: '6px 8px', borderLeft: '1px solid var(--escalab-line)' }}><NotaPill nota={mediaIndFonte(agg.combinado, ind.id)} /></td>
                        </tr>
                      ))}
                    </React.Fragment>
                  );
                })}
              </tbody>
            </table>
          </div>
        </div>
      )}

      {/* Respostas qualitativas — o que as pessoas ESCREVERAM. Só o admin. */}
      {podeVerAbertas && <RespostasAbertasAvd abertas={abertas} nome={String(colab.nome || '').split(' ')[0]} />}
    </div>
  );
};

window.ResultadoAvdPessoa = ResultadoAvdPessoa;

// ── Respostas abertas (perguntas de texto) ────────────────────────────────────
// Cada categoria do formulário termina numa pergunta aberta ("quer explicar as
// notas?"). Elas eram salvas em avd_respostas com nota nula e indicador
// ABERTA_<categoria> — e nenhuma tela lia esse campo: o G&C só via números.
//
// Sem nome de quem escreveu, pelo mesmo motivo de a nota sair agregada. O tipo
// (par, líder, liderado, autoavaliação) fica, porque é o que dá sentido ao
// texto: "meu líder acha X" e "meu liderado acha X" não são a mesma frase.
const RespostasAbertasAvd = ({ abertas, nome }) => {
  const lista = abertas || [];
  const cats = ['organizacional', 'comportamental', 'performance'];
  const rotuloTipo = t => (AVD_TIPO_ROTULO[t] || { label: t }).label;
  const corTipo = t => (AVD_TIPO_ROTULO[t] || { cor: 'var(--escalab-mute)' }).cor;

  return (
    <div style={{ border: '1px solid var(--escalab-line)', borderRadius: 12, padding: 16, marginTop: 22 }}>
      <div style={{ fontSize: 14, fontWeight: 700, marginBottom: 4 }}>Respostas abertas</div>
      <div style={{ fontSize: 11.5, color: 'var(--escalab-mute)', marginBottom: 12 }}>
        O que os avaliadores escreveram ao justificar as notas. Sem identificação de quem escreveu — só o papel de quem respondeu.
      </div>
      {!lista.length && (
        <div style={{ fontSize: 13, color: 'var(--escalab-mute)', fontStyle: 'italic' }}>
          Ninguém escreveu nada sobre {nome || 'esta pessoa'} ainda. A justificativa é obrigatória no formulário, então isto quer dizer que ninguém fechou a ficha ainda.
        </div>
      )}
      {cats.map(cat => {
        const doCat = lista.filter(a => a.categoria === cat);
        if (!doCat.length) return null;
        return (
          <div key={cat} style={{ marginBottom: 16 }}>
            <div style={{ fontSize: 10.5, fontWeight: 700, letterSpacing: '.06em', textTransform: 'uppercase', color: 'var(--escalab-brand)', marginBottom: 8 }}>
              {AVD_CAT_NOME[cat] || cat}
            </div>
            <div style={{ display: 'flex', flexDirection: 'column', gap: 9 }}>
              {doCat.map((a, i) => (
                <div key={cat + '_' + i} style={{ border: '1px solid var(--escalab-line)', borderLeft: `3px solid ${corTipo(a.tipo)}`, borderRadius: 9, padding: '11px 13px', background: 'var(--escalab-paper)' }}>
                  <span style={{ display: 'inline-block', fontSize: 10, fontWeight: 800, letterSpacing: '.05em', textTransform: 'uppercase', color: '#fff', background: corTipo(a.tipo), padding: '2px 8px', borderRadius: 999, marginBottom: 6 }}>
                    {rotuloTipo(a.tipo)}
                  </span>
                  <div style={{ fontSize: 13.5, lineHeight: 1.55, color: 'var(--escalab-ink)', whiteSpace: 'pre-wrap' }}>{a.texto}</div>
                </div>
              ))}
            </div>
          </div>
        );
      })}
    </div>
  );
};

window.RespostasAbertasAvd = RespostasAbertasAvd;

const ResultadosAvdView = ({ user }) => {
  const [carregando, setCarregando] = React.useState(true);
  const [erro, setErro] = React.useState(null);
  const [colabId, setColabId] = React.useState(null);
  const cicloAberto = typeof getCicloAvdAberto === 'function' ? getCicloAvdAberto() : null;
  const [cicloId, setCicloId] = React.useState(cicloAberto ? cicloAberto.cicloId : '');

  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; };
  }, []);

  // Quem o seletor pode listar.
  //
  // Esta tela é a mesma pro admin e pro gestor ("Resultados do time"), e até
  // 31/07 listava COLABORADORES inteiro pros dois — o gestor escolhia qualquer
  // pessoa da empresa no dropdown. O comentário dizia "a RLS filtra", mas a RLS
  // protege a leitura das respostas, não a montagem da lista: o nome de todo
  // mundo aparecia, com a nota vindo vazia. Admin continua vendo a empresa toda.
  //
  // O recorte do gestor era só `gestorNome`, o mesmo de Colaboradores, Férias e
  // PDI — e na AVD isso está errado. Quem lidera quem, PARA A AVALIAÇÃO, mora em
  // avd_avaliadores.tipo = 'lider' (097), não no organograma: a Carol e o Felipe
  // lideram os associados de projetos pela matriz, e o gestor_id deles aponta pra
  // outro lugar. Resultado: a Carol via duas pessoas e avaliava dez. Agora é a
  // união dos dois — organograma OU matriz —, porque as duas coisas são
  // verdadeiras e nenhuma sozinha cobre o time inteiro.
  const _todos = [...(typeof COLABORADORES !== 'undefined' ? COLABORADORES : [])];
  const _ehAdmin = user && user.perfil === 'admin';
  const _lideroNaMatriz = new Set(
    (typeof AVD_AVALIADORES !== 'undefined' ? AVD_AVALIADORES : [])
      .filter(x => x.tipo === 'lider' && String(x.avaliadorId) === String(user?.id))
      .map(x => String(x.avaliadoId))
  );
  const colabs = (_ehAdmin ? _todos : _todos.filter(c =>
      (c.gestorNome && c.gestorNome === user?.nome) || _lideroNaMatriz.has(String(c.id))))
    .sort((a, b) => String(a.nome).localeCompare(String(b.nome)));
  const ciclos = [...(typeof CICLOS !== 'undefined' ? CICLOS : [])];
  const colab = colabs.find(c => c.id === colabId);

  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>;

  return (
    <div>
      <div style={{ display: 'flex', gap: 10, flexWrap: 'wrap', marginBottom: 18 }}>
        <select value={colabId || ''} onChange={e => setColabId(Number(e.target.value) || e.target.value)}
          style={{ border: '1px solid var(--escalab-line)', borderRadius: 8, padding: '9px 12px', fontSize: 13.5, fontFamily: 'var(--font-sans)', background: '#fff', outline: 'none', minWidth: 240 }}>
          <option value="">{_ehAdmin ? 'Selecione um colaborador…' : 'Selecione um liderado…'}</option>
          {colabs.map(c => <option key={c.id} value={c.id}>{c.nome}</option>)}
        </select>
        <select value={cicloId} onChange={e => setCicloId(e.target.value)}
          style={{ border: '1px solid var(--escalab-line)', borderRadius: 8, padding: '9px 12px', fontSize: 13.5, fontFamily: 'var(--font-sans)', background: '#fff', outline: 'none' }}>
          <option value="">Todos os ciclos</option>
          {ciclos.map(c => <option key={c.id} value={c.id}>{c.nome}</option>)}
        </select>
      </div>

      {!colab && colabs.length > 0 && <div style={{ fontSize: 13, color: 'var(--escalab-mute)', fontStyle: 'italic' }}>Escolha um colaborador para ver as notas segmentadas.</div>}
      {!colabs.length && (
        <div style={{ fontSize: 13, color: 'var(--escalab-mute)', fontStyle: 'italic' }}>
          Você não tem liderados cadastrados — não há resultados de time pra mostrar.
        </div>
      )}

      {colab && (
        // A qualitativa só pro admin: aqui dentro esta mesma tela é
        // "Resultados do time" pro gestor, que vê a nota agregada e não o texto.
        <ResultadoAvdPessoa colab={colab} cicloId={cicloId} podeVerAbertas={_ehAdmin} />
      )}
    </div>
  );
};

window.ResultadosAvdView = ResultadosAvdView;

// ── Quem avalia uma pessoa: nome, categoria e peso ────────────────────────────
// O G&C pediu (31/07) "um local onde a pessoa possa saber quem a avaliou e em
// qual das categorias e pesos". A matriz (avd_avaliadores) já chega no boot pra
// todo autenticado — a policy de SELECT da 072 é `USING (true)` —, então dá pra
// montar isto no cliente, sem RPC nova.
//
// O que NÃO mostra: a nota que cada avaliador deu. Isso continua agregado, como
// sempre foi; a lista diz quem responde e com que peso, não o que cada um achou.
// O "respondeu" só aparece pra quem lê AVD_RESPOSTAS_TODAS (admin) — pro próprio
// colaborador a coluna some, porque a RLS da 073 não devolve resposta alheia.
const AVD_TIPO_ROTULO = {
  auto:      { label: 'Autoavaliação', cor: '#6B3FA0' },
  lider:     { label: 'Líder',         cor: '#00836B' },
  par:       { label: 'Par',           cor: '#1F4A8A' },
  liderado:  { label: 'Liderado',      cor: '#B26A00' },
  diretoria: { label: 'Diretoria',     cor: '#1F4A8A' },
};

const QuemMeAvalia = ({ avaliadoId, cicloId, titulo }) => {
  const matriz = typeof AVD_AVALIADORES !== 'undefined' ? AVD_AVALIADORES : [];
  const colabs = typeof COLABORADORES !== 'undefined' ? COLABORADORES : [];
  const nomeDe = id => (colabs.find(c => c.id === id) || {}).nome || String(id);

  // Progresso por avaliador: só se a tela conseguiu ler as respostas DESTA
  // pessoa. O teste era "o array não está vazio", e isso passou a mentir depois
  // da 135: o gestor carrega as respostas do time, então o array enche — mas
  // sobre ELE mesmo continua sem nada, porque ninguém lê resposta alheia sobre
  // si. Na aba "Minha avaliação" a coluna sairia com todo mundo em "pendente",
  // e a leitura óbvia seria "ninguém me avaliou" — justamente quando avaliaram.
  //
  // Sem linha nenhuma sobre a pessoa, não dá pra distinguir "ninguém respondeu"
  // de "não posso ver" — e nesse caso a coluna não aparece, em vez de chutar.
  const _fonteResp = typeof AVD_RESPOSTAS_TODAS !== 'undefined' ? AVD_RESPOSTAS_TODAS : [];
  const temRespostas = _fonteResp.some(r => r.avaliadoId === avaliadoId);
  const prog = (temRespostas && typeof getProgressoAvdDoAvaliado === 'function')
    ? getProgressoAvdDoAvaliado(avaliadoId, cicloId || null) : null;
  // Situação com MOTIVO. "Em andamento" sozinho junta duas coisas muito
  // diferentes: quem deu todas as notas e só não escreveu a justificativa (um
  // lembrete de um minuto — e é o caso mais comum, porque a justificativa virou
  // obrigatória em 05/08, com metade da empresa já tendo respondido) e quem
  // parou na metade da ficha. Sem separar, o G&C cobra os dois igual.
  const statusDe = (avaliadorId, tipo) => {
    if (!prog) return null;
    if ((prog.ignorados || []).some(x => x.avaliadorId === avaliadorId && x.tipo === tipo))
      return { txt: 'desconsiderado (saiu da empresa)', cor: 'var(--escalab-mute)' };
    const d = (prog.detalhe || []).find(x => x.avaliadorId === avaliadorId && x.tipo === tipo);
    if (!d) return null;
    if (d.concluida) return { txt: 'respondida', cor: '#00836B' };
    if (!d.feitos) return { txt: 'não começou', cor: 'var(--escalab-mute)' };
    if (!d.faltamNotas && d.faltamAbertas)
      return { txt: `falta só a justificativa (${d.faltamAbertas})`, cor: '#C77700' };
    return { txt: `faltam ${d.faltamNotas} de ${d.total}`, cor: '#C77700' };
  };

  const linhas = [
    { avaliadorId: avaliadoId, tipo: 'auto', peso: null },
    ...matriz.filter(x => x.avaliadoId === avaliadoId).map(x => ({ avaliadorId: x.avaliadorId, tipo: x.tipo, peso: x.peso })),
  ].sort((a, b) => String(a.tipo).localeCompare(String(b.tipo)) || String(nomeDe(a.avaliadorId)).localeCompare(String(nomeDe(b.avaliadorId))));

  return (
    <div style={{ border: '1px solid var(--escalab-line)', borderRadius: 12, padding: 16, marginBottom: 22 }}>
      <div style={{ fontSize: 14, fontWeight: 700, marginBottom: 4 }}>{titulo || 'Quem me avalia'}</div>
      <div style={{ fontSize: 11.5, color: 'var(--escalab-mute)', marginBottom: 12 }}>
        Categoria e peso de cada avaliador designado neste ciclo. As notas individuais não são exibidas — o resultado sai sempre agregado.
      </div>
      {!linhas.length && <div style={{ fontSize: 13, color: 'var(--escalab-mute)', fontStyle: 'italic' }}>Nenhum avaliador designado ainda.</div>}
      {!!linhas.length && (
        <div style={{ overflowX: 'auto' }}>
          <table style={{ width: '100%', borderCollapse: 'collapse', fontSize: 13, minWidth: 380 }}>
            <thead><tr style={{ borderBottom: '1px solid var(--escalab-line)' }}>
              <th style={{ textAlign: 'left', padding: '8px 10px', color: 'var(--escalab-mute)', fontWeight: 600 }}>Avaliador</th>
              <th style={{ textAlign: 'left', padding: '8px 10px', color: 'var(--escalab-mute)', fontWeight: 600 }}>Categoria</th>
              <th style={{ textAlign: 'center', padding: '8px 10px', color: 'var(--escalab-mute)', fontWeight: 600 }}>Peso</th>
              {prog && <th style={{ textAlign: 'center', padding: '8px 10px', color: 'var(--escalab-mute)', fontWeight: 600 }}>Situação</th>}
            </tr></thead>
            <tbody>
              {linhas.map((l, i) => {
                const t = AVD_TIPO_ROTULO[l.tipo] || { label: l.tipo, cor: 'var(--escalab-mute)' };
                const st = statusDe(l.avaliadorId, l.tipo);
                return (
                  <tr key={l.avaliadorId + '_' + l.tipo + '_' + i} style={{ borderBottom: '1px solid var(--escalab-line)' }}>
                    <td style={{ padding: '8px 10px', fontWeight: 600 }}>{l.tipo === 'auto' ? 'Você mesmo(a)' : nomeDe(l.avaliadorId)}</td>
                    <td style={{ padding: '8px 10px' }}>
                      <span style={{ fontSize: 11, fontWeight: 700, letterSpacing: '.04em', textTransform: 'uppercase', padding: '3px 9px', borderRadius: 999, color: '#fff', background: t.cor }}>{t.label}</span>
                    </td>
                    <td style={{ textAlign: 'center', padding: '8px 10px' }}>{l.peso != null ? String(l.peso).replace('.', ',') : '—'}</td>
                    {prog && <td style={{ textAlign: 'center', padding: '8px 10px', color: st ? st.cor : 'var(--escalab-mute)', fontWeight: 600 }}>{st ? st.txt : '—'}</td>}
                  </tr>
                );
              })}
            </tbody>
          </table>
        </div>
      )}

      {/* Respondeu, está gravado, e a matriz não pede. Some de toda contagem —
          quem respondeu jura que respondeu e o painel não mostra nada. Quase
          sempre é vínculo tirado da matriz DEPOIS de a pessoa ter respondido.
          As notas continuam entrando na média, então ignorar em silêncio é o
          pior dos mundos: conta pro resultado e não aparece pra ninguém. */}
      {prog && !!(prog.extras || []).length && (
        <div style={{ marginTop: 14, background: '#FFF8E1', border: '1px solid #F5C518', borderRadius: 10, padding: '11px 14px', fontSize: 12.5, color: '#5A4500', lineHeight: 1.5 }}>
          <strong>Respondeu sem estar na matriz.</strong> Estas respostas existem no banco e entram na média, mas ninguém as cobra — confira se o vínculo foi removido por engano:
          <ul style={{ margin: '7px 0 0', paddingLeft: 18 }}>
            {prog.extras.map((x, i) => (
              <li key={i}>{nomeDe(x.avaliadorId)} · {(AVD_TIPO_ROTULO[x.tipo] || { label: x.tipo }).label} — {x.respostas} resposta(s)</li>
            ))}
          </ul>
        </div>
      )}
    </div>
  );
};

window.QuemMeAvalia = QuemMeAvalia;

// ── Relatório imprimível: quem avalia quem, com que peso e respondendo o quê ──
// Pedido do G&C (03/08): "um PDF de como está quem avalia quem e os pesos pra eu
// verificar se está de fato correto".
//
// Sai da tela, e não de um SQL, porque é o que a plataforma REALMENTE usa: a
// mesma AVD_AVALIADORES que o formulário lê, a mesma AVD_CATEGORIA_POR_TIPO que
// decide as perguntas e o mesmo AVD_PESO_POR_TIPO que entra na nota final. Um
// relatório escrito à parte poderia conferir e a tela continuar errada.
//
// Abre numa janela nova já no diálogo de impressão — "Salvar como PDF" ali
// mesmo. Sem biblioteca: é HTML com @page.
function _relEscapar(s) {
  return String(s == null ? '' : s)
    .replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;');
}

function gerarRelatorioMatrizAvdHTML() {
  const colabs = (typeof getColaboradoresAtivos === 'function' ? getColaboradoresAtivos() : (typeof COLABORADORES !== 'undefined' ? COLABORADORES : []))
    .slice().sort((a, b) => String(a.nome).localeCompare(String(b.nome)));
  const matriz = typeof AVD_AVALIADORES !== 'undefined' ? AVD_AVALIADORES : [];
  const ciclo = typeof getCicloAvdAberto === 'function' ? getCicloAvdAberto() : null;
  const todos = typeof COLABORADORES !== 'undefined' ? COLABORADORES : [];
  const nomeDe = id => (todos.find(c => c.id === id) || {}).nome || ('#' + id);
  const cargoDe = id => (todos.find(c => c.id === id) || {}).cargo || '';
  const rotulo = t => (AVD_TIPO_ROTULO[t] || { label: t }).label;
  const pesoTipo = t => (typeof AVD_PESO_POR_TIPO !== 'undefined' ? (AVD_PESO_POR_TIPO[t] || 1) : 1);
  const cats = t => (typeof AVD_CATEGORIA_POR_TIPO !== 'undefined' ? (AVD_CATEGORIA_POR_TIPO[t] || []) : []);
  const NOME_CAT = {
    organizacional: 'Organizacional', comportamental: 'Comportamental', performance: 'Performance',
    comportamental_par: 'Comportamental (bloco do par)', comportamental_lideranca: 'Comportamental (bloco de liderança)',
  };

  // Quantas perguntas cada tipo responde sobre esta pessoa — é o número que
  // fecha (ou não) a ficha, o mesmo de getProgressoAvdDoAvaliado.
  function perguntasDe(colab, tipo) {
    const ficha = typeof montarFichaDoColaborador === 'function' ? montarFichaDoColaborador(colab) : null;
    if (!ficha) return 0;
    let n = 0;
    cats(tipo).forEach(cat => {
      const comps = ficha[cat] || [];
      comps.forEach(comp => { n += (comp.indicadores || []).length; });
      // A justificativa de cada bloco entra na conta desde 05/08 — é o mesmo
      // número que o formulário cobra pra dar a ficha como concluída.
      if (comps.length) n += 1;
    });
    return n;
  }

  const semFicha = [], semAvaliador = [], comDiretoria = [], recebemLideranca = [];
  const blocos = colabs.map(c => {
    const fichaId = typeof getFichaIdDoColaborador === 'function' ? getFichaIdDoColaborador(c) : null;
    const ficha = (typeof AVD_FICHAS !== 'undefined' ? AVD_FICHAS : []).find(f => f.id === fichaId);
    if (!fichaId) semFicha.push(c.nome);
    const linhas = [
      { avaliadorId: c.id, tipo: 'auto', peso: 1, origem: '—' },
      ...matriz.filter(x => x.avaliadoId === c.id),
    ].sort((a, b) => String(a.tipo).localeCompare(String(b.tipo)) || String(nomeDe(a.avaliadorId)).localeCompare(String(nomeDe(b.avaliadorId))));
    if (linhas.length <= 1) semAvaliador.push(c.nome);
    if (linhas.some(l => l.tipo === 'diretoria')) comDiretoria.push(c.nome);
    if (linhas.some(l => l.tipo === 'liderado')) recebemLideranca.push(c.nome);

    const tr = linhas.map(l => {
      const pt = l.tipo === 'auto' ? 0 : pesoTipo(l.tipo);
      const pi = l.peso != null ? Number(l.peso) : 1;
      const naFinal = ['par', 'lider', 'liderado'].includes(l.tipo);
      return `<tr class="${l.tipo === 'diretoria' ? 'alerta' : ''}">
        <td>${_relEscapar(l.tipo === 'auto' ? c.nome + ' (ela mesma)' : nomeDe(l.avaliadorId))}<div class="sub">${_relEscapar(l.tipo === 'auto' ? '' : cargoDe(l.avaliadorId))}</div></td>
        <td><span class="tag">${_relEscapar(rotulo(l.tipo))}</span></td>
        <td class="num">${naFinal ? String(pt).replace('.', ',') + '×' : '—'}</td>
        <td class="num">${String(pi).replace('.', ',')}</td>
        <td class="num"><b>${naFinal ? String(pt * pi).replace('.', ',') : '0'}</b></td>
        <td>${cats(l.tipo).map(x => _relEscapar(NOME_CAT[x] || x)).join(' + ') || '—'}</td>
        <td class="num">${perguntasDe(c, l.tipo)}</td>
      </tr>`;
    }).join('');

    return `<section class="pessoa">
      <h2>${_relEscapar(c.nome)}</h2>
      <div class="meta">${_relEscapar(c.cargo || '—')} · ${_relEscapar(c.setor || '—')} · Ficha: <b>${_relEscapar(ficha ? ficha.nome : 'SEM FICHA')}</b></div>
      <table>
        <thead><tr>
          <th>Quem avalia</th><th>Papel</th><th>Peso do papel</th><th>Peso individual</th>
          <th>Peso na nota</th><th>Responde</th><th>Perguntas</th>
        </tr></thead>
        <tbody>${tr || '<tr><td colspan="7" class="vazio">Ninguém designado.</td></tr>'}</tbody>
      </table>
    </section>`;
  }).join('');

  const porTipo = {};
  matriz.forEach(x => { porTipo[x.tipo] = (porTipo[x.tipo] || 0) + 1; });
  const pesosNaoUm = matriz.filter(x => Number(x.peso) !== 1);

  const hoje = new Date().toLocaleDateString('pt-BR');
  return `<!doctype html><html lang="pt-BR"><head><meta charset="utf-8">
<title>AVD · Quem avalia quem e pesos</title>
<style>
  @page { size: A4; margin: 14mm; }
  * { box-sizing: border-box; }
  body { font-family: -apple-system, "Segoe UI", Roboto, Arial, sans-serif; color: #1B2A33; font-size: 11px; margin: 0; }
  h1 { font-size: 20px; margin: 0 0 4px; }
  h2 { font-size: 13px; margin: 0 0 2px; }
  .cap { color: #5B6B77; font-size: 11px; margin-bottom: 16px; }
  .pessoa { page-break-inside: avoid; margin-bottom: 14px; padding-bottom: 10px; border-bottom: 1px solid #E3E8EB; }
  .meta { color: #5B6B77; font-size: 10.5px; margin-bottom: 6px; }
  table { width: 100%; border-collapse: collapse; }
  th { text-align: left; font-size: 9.5px; text-transform: uppercase; letter-spacing: .05em; color: #5B6B77; border-bottom: 1px solid #C9D2D8; padding: 3px 5px; }
  td { padding: 4px 5px; border-bottom: 1px solid #EEF2F4; vertical-align: top; }
  td.num { text-align: center; }
  .sub { color: #8A98A2; font-size: 9.5px; }
  .tag { background: #EEF2F4; border-radius: 20px; padding: 1px 7px; font-size: 9.5px; font-weight: 700; text-transform: uppercase; }
  tr.alerta td { background: #FFF7EB; }
  .vazio { color: #B3261E; font-style: italic; }
  .resumo { border: 1px solid #C9D2D8; border-radius: 8px; padding: 12px 14px; margin-bottom: 18px; page-break-after: always; }
  .resumo ul { margin: 4px 0 12px; padding-left: 18px; }
  .resumo li { margin-bottom: 2px; }
  .aviso { background: #FFF7EB; border-left: 3px solid #C77700; padding: 8px 10px; margin: 8px 0; }
</style></head><body>
<h1>AVD · Quem avalia quem, e com que peso</h1>
<div class="cap">Ciclo: <b>${_relEscapar(ciclo ? ciclo.nome : 'nenhum ciclo aberto')}</b> · gerado em ${hoje} · ${colabs.length} pessoas ativas · ${matriz.length} vínculos na matriz</div>

<div class="resumo">
  <h2>Como a plataforma calcula</h2>
  <ul>
    ${Object.keys(AVD_CATEGORIA_POR_TIPO).map(t => `<li><b>${_relEscapar(rotulo(t))}</b> — responde ${cats(t).map(x => _relEscapar(NOME_CAT[x] || x)).join(' + ')}. Peso do papel na nota final: ${['par', 'lider', 'liderado'].includes(t) ? String(pesoTipo(t)).replace('.', ',') + '×' : 'fora da nota final'}.</li>`).join('')}
  </ul>
  <div>A nota final é a média ponderada de <b>par + líder + liderado</b>. Autoavaliação e diretoria ficam de fora dela e aparecem em separado. O peso de cada linha é <i>peso do papel × peso individual</i> — o peso individual nasce 1 e só muda se alguém editar na tela.</div>

  <h2 style="margin-top:12px">Vínculos por papel</h2>
  <ul>${Object.keys(porTipo).sort().map(t => `<li>${_relEscapar(rotulo(t))}: <b>${porTipo[t]}</b></li>`).join('')}</ul>

  ${semFicha.length ? `<div class="aviso"><b>Sem ficha (${semFicha.length})</b> — ninguém consegue avaliar estas pessoas: ${_relEscapar(semFicha.join(', '))}</div>` : ''}
  ${semAvaliador.length ? `<div class="aviso"><b>Só com autoavaliação (${semAvaliador.length})</b> — ninguém foi designado: ${_relEscapar(semAvaliador.join(', '))}</div>` : ''}
  ${comDiretoria.length ? `<div class="aviso"><b>Recebem avaliação do tipo "Diretoria" (${comDiretoria.length})</b> — camada cruzada da 096/097, pendente de decisão do G&amp;C: ${_relEscapar(comDiretoria.join(', '))}</div>` : ''}
  ${recebemLideranca.length ? `<div class="aviso"><b>Recebem o bloco de liderança (${recebemLideranca.length})</b> — tem liderado designado, então responde-se sobre a liderança dessa pessoa. Se alguém aqui não é liderança, o vínculo "liderado" é que está errado: ${_relEscapar(recebemLideranca.join(', '))}</div>` : ''}
  ${pesosNaoUm.length ? `<div class="aviso"><b>Pesos individuais diferentes de 1 (${pesosNaoUm.length})</b>: ${_relEscapar(pesosNaoUm.map(x => nomeDe(x.avaliadorId) + ' → ' + nomeDe(x.avaliadoId) + ' (' + x.peso + ')').join('; '))}</div>` : '<div>Todos os pesos individuais estão em 1 — só o peso do papel diferencia.</div>'}
</div>

${blocos}
</body></html>`;
}

function abrirRelatorioMatrizAvd() {
  const html = gerarRelatorioMatrizAvdHTML();
  const w = window.open('', '_blank');
  if (!w) {
    alert('O navegador bloqueou a janela do relatório. Libere pop-ups para este site e tente de novo.');
    return;
  }
  w.document.open();
  w.document.write(html);
  w.document.close();
  // Espera o layout antes de chamar o diálogo, senão o Chrome imprime em branco.
  w.onload = () => setTimeout(() => { try { w.focus(); w.print(); } catch {} }, 250);
}

window.abrirRelatorioMatrizAvd = abrirRelatorioMatrizAvd;
window.gerarRelatorioMatrizAvdHTML = gerarRelatorioMatrizAvdHTML;

// ── Visão da PRÓPRIA pessoa (Fase 4b, via RPC avd_meus_resultados / SQL 074) ──
const MinhaAvdResultado = ({ user }) => {
  const cicloAberto = typeof getCicloAvdAberto === 'function' ? getCicloAvdAberto() : null;
  const [cicloId, setCicloId] = React.useState(cicloAberto ? cicloAberto.cicloId : '');
  const [dados, setDados] = React.useState(undefined); // undefined=carregando, null=erro
  const ciclos = [...(typeof CICLOS !== 'undefined' ? CICLOS : [])];

  React.useEffect(() => {
    let vivo = true;
    setDados(undefined);
    (async () => {
      const r = typeof fetchMeusResultadosAvd === 'function' ? await fetchMeusResultadosAvd(cicloId || null) : null;
      if (vivo) setDados(r);
    })();
    return () => { vivo = false; };
  }, [cicloId]);

  const catNome = { organizacional: 'Organizacional', comportamental: 'Comportamental', performance: 'Performance' };

  return (
    <div style={{ border: '1px solid var(--escalab-line)', borderRadius: 12, padding: 16, marginBottom: 22 }}>
      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 10, flexWrap: 'wrap', marginBottom: 14 }}>
        <div style={{ fontSize: 16, fontWeight: 700 }}>Meu resultado da AVD</div>
        <select value={cicloId} onChange={e => setCicloId(e.target.value)}
          style={{ border: '1px solid var(--escalab-line)', borderRadius: 8, padding: '8px 11px', fontSize: 13, fontFamily: 'var(--font-sans)', background: '#fff', outline: 'none' }}>
          <option value="">Todos os ciclos</option>
          {ciclos.map(c => <option key={c.id} value={c.id}>{c.nome}</option>)}
        </select>
      </div>

      {dados === undefined && <div style={{ padding: 16, color: 'var(--escalab-mute)', fontSize: 13.5 }}>Carregando…</div>}
      {dados === null && <div style={{ padding: 16, color: 'var(--escalab-mute)', fontSize: 13.5 }}>Não consegui carregar agora (a RPC 074 precisa estar rodada).</div>}

      {/* Fica FORA do gate de `liberado`: saber quem responde por você não
          depende da nota estar liberada — é justamente o que a pessoa quer ver
          enquanto o ciclo corre. */}
      {typeof QuemMeAvalia !== 'undefined' && user && (
        <QuemMeAvalia avaliadoId={user.id} cicloId={cicloId} titulo="Quem me avalia neste ciclo" />
      )}

      {dados && dados.liberado === false && (
        <div style={{ background: 'var(--escalab-paper)', border: '1px dashed var(--escalab-line)', borderRadius: 10, padding: '18px', textAlign: 'center', color: 'var(--escalab-mute)', fontSize: 13.5 }}>
          Suas notas ainda <strong>não foram liberadas</strong> pelo RH. Assim que forem, seu resultado aparece aqui.
        </div>
      )}

      {dados && dados.liberado === true && (
        <div>
          <div style={{ display: 'flex', gap: 12, flexWrap: 'wrap', marginBottom: 20 }}>
            <div style={{ flex: '1 1 180px', border: '2px solid var(--escalab-brand)', borderRadius: 12, padding: '14px 16px', background: 'var(--escalab-paper)' }}>
              <div style={{ fontSize: 11, fontWeight: 700, letterSpacing: '.08em', textTransform: 'uppercase', color: 'var(--escalab-brand)', marginBottom: 8 }}>Minha nota geral</div>
              <NotaPill nota={dados.geral} forte />
              <div style={{ fontSize: 11.5, color: 'var(--escalab-mute)', marginTop: 8 }}>Média de pares + líder (sem a autoavaliação).</div>
            </div>
            <div style={{ flex: '1 1 180px', border: '1px solid var(--escalab-line)', borderRadius: 12, padding: '14px 16px' }}>
              <div style={{ fontSize: 11, fontWeight: 700, letterSpacing: '.08em', textTransform: 'uppercase', color: '#6B3FA0', marginBottom: 8 }}>Minha autoavaliação</div>
              <NotaPill nota={dados.autoGeral} forte />
              <div style={{ fontSize: 11.5, color: 'var(--escalab-mute)', marginTop: 8 }}>O que você deu pra si.</div>
            </div>
          </div>

          <div style={{ fontSize: 14, fontWeight: 700, margin: '4px 0 10px' }}>Por categoria</div>
          <div style={{ overflowX: 'auto', marginBottom: 20 }}>
            <table style={{ width: '100%', borderCollapse: 'collapse', fontSize: 13, minWidth: 360 }}>
              <thead><tr style={{ borderBottom: '1px solid var(--escalab-line)' }}>
                <th style={{ textAlign: 'left', padding: '8px 10px', color: 'var(--escalab-mute)', fontWeight: 600 }}>Categoria</th>
                <th style={{ textAlign: 'center', padding: '8px 10px', color: 'var(--escalab-brand)', fontWeight: 700 }}>Recebida</th>
                <th style={{ textAlign: 'center', padding: '8px 10px', color: '#6B3FA0', fontWeight: 700 }}>Autoavaliação</th>
              </tr></thead>
              <tbody>
                {(dados.porCategoria || []).map(c => (
                  <tr key={c.categoria} style={{ borderBottom: '1px solid var(--escalab-line)' }}>
                    <td style={{ padding: '8px 10px', fontWeight: 600 }}>{catNome[c.categoria] || c.categoria}</td>
                    <td style={{ textAlign: 'center', padding: '8px 10px' }}><NotaPill nota={c.recebida != null ? Number(c.recebida) : null} /></td>
                    <td style={{ textAlign: 'center', padding: '8px 10px' }}><NotaPill nota={c.auto != null ? Number(c.auto) : null} /></td>
                  </tr>
                ))}
                {!(dados.porCategoria || []).length && <tr><td colSpan={3} style={{ padding: '10px', color: 'var(--escalab-mute)', fontStyle: 'italic' }}>Sem notas ainda.</td></tr>}
              </tbody>
            </table>
          </div>

          <div style={{ fontSize: 14, fontWeight: 700, margin: '4px 0 10px' }}>Por competência</div>
          <div style={{ overflowX: 'auto' }}>
            <table style={{ width: '100%', borderCollapse: 'collapse', fontSize: 12.5, minWidth: 420 }}>
              <thead><tr style={{ borderBottom: '1px solid var(--escalab-line)' }}>
                <th style={{ textAlign: 'left', padding: '8px 10px', color: 'var(--escalab-mute)', fontWeight: 600 }}>Competência</th>
                <th style={{ textAlign: 'center', padding: '8px 8px', color: 'var(--escalab-brand)', fontWeight: 700 }}>Recebida</th>
                <th style={{ textAlign: 'center', padding: '8px 8px', color: '#6B3FA0', fontWeight: 700 }}>Auto</th>
              </tr></thead>
              <tbody>
                {(dados.porCompetencia || []).map((c, i) => {
                  const catAnt = i > 0 ? dados.porCompetencia[i - 1].categoria : null;
                  const nova = c.categoria !== catAnt;
                  return (
                    <React.Fragment key={c.id}>
                      {nova && <tr style={{ background: 'var(--escalab-paper)' }}><td colSpan={3} style={{ padding: '5px 10px', fontSize: 10.5, fontWeight: 700, letterSpacing: '.06em', textTransform: 'uppercase', color: 'var(--escalab-brand)' }}>{catNome[c.categoria] || c.categoria}{c.grupo ? ` · ${c.grupo}` : ''}</td></tr>}
                      <tr style={{ borderBottom: '1px solid var(--escalab-line)' }}>
                        <td style={{ padding: '7px 10px' }}>{c.nome}</td>
                        <td style={{ textAlign: 'center', padding: '7px 8px' }}><NotaPill nota={c.recebida != null ? Number(c.recebida) : null} /></td>
                        <td style={{ textAlign: 'center', padding: '7px 8px' }}><NotaPill nota={c.auto != null ? Number(c.auto) : null} /></td>
                      </tr>
                    </React.Fragment>
                  );
                })}
                {!(dados.porCompetencia || []).length && <tr><td colSpan={3} style={{ padding: '10px', color: 'var(--escalab-mute)', fontStyle: 'italic' }}>Sem notas ainda.</td></tr>}
              </tbody>
            </table>
          </div>

          {/* 19/08 · a parte qualitativa saiu daqui. Pedido do Hiago: quando a
              nota é liberada, a pessoa vê a NOTA; o que escreveram sobre ela
              fica só com o administrador. Não é só esconder — a 148 tirou o
              campo 'abertas' do avd_meus_resultados, então o texto nem sai do
              banco pra ela (é a única porta que ela tinha: as policies da 073
              não a alcançam como avaliada). */}
        </div>
      )}
    </div>
  );
};

window.MinhaAvdResultado = MinhaAvdResultado;
