// ═══════════════════════════════════════════════════════════════════════════
// AVD · Dashboard do GC (Fase 5) — ao lado de Feedback
// Comparações: média por setor · notas dadas pelos diretores (camada alta) ·
// notas dos próprios diretores · distribuição pelas faixas do G&C (AVD_FAIXAS).
// Client-side sobre AVD_RESPOSTAS_TODAS + agregarNotasAvd (data.jsx). Sem SQL novo.
// Reaproveita NotaPill / _notaCor de screen-avd-resultados.jsx.
// ═══════════════════════════════════════════════════════════════════════════

function _dashMedia(arr) { return (arr && arr.length) ? Math.round((arr.reduce((s, v) => s + v, 0) / arr.length) * 100) / 100 : null; }

const DashBarra = ({ nota }) => (
  <div style={{ height: 8, borderRadius: 4, background: 'var(--escalab-line)', overflow: 'hidden', flex: 1, minWidth: 60 }}>
    <div style={{ height: '100%', width: `${nota != null ? (nota / 5) * 100 : 0}%`, background: nota != null ? _notaCor(nota) : 'transparent', transition: 'width .2s' }} />
  </div>
);

const DashPessoaLinha = ({ colab, nota, sub }) => (
  <div style={{ display: 'flex', alignItems: 'center', gap: 10, padding: '7px 0' }}>
    <div style={{ width: 30, height: 30, borderRadius: '50%', background: colab.cor, color: '#fff', fontWeight: 700, fontSize: 11, display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }}>{colab.iniciais}</div>
    <div style={{ flex: 1, minWidth: 0 }}>
      <div style={{ fontSize: 13, fontWeight: 600, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{(colab.nome || '').split(' ').slice(0, 2).join(' ')}</div>
      {sub && <div style={{ fontSize: 11, color: 'var(--escalab-mute)' }}>{sub}</div>}
    </div>
    <NotaPill nota={nota} />
  </div>
);

// Faixas do G&C (30/07) prontas pra exibição: rótulo, %, teto e cor.
// Fonte única é AVD_FAIXAS (data.jsx) — vem em ordem decrescente, então o teto
// de cada faixa é o piso da faixa de cima, menos 0,01.
function _dashFaixas() {
  const fs = (typeof AVD_FAIXAS !== 'undefined' ? AVD_FAIXAS : []);
  const n = v => String(Math.round(v * 100) / 100).replace('.', ',');
  return fs.map((f, i) => ({
    rotulo: f.rotulo,
    pct: f.pct,
    cor: f.cor,
    intervalo: `${n(f.min)} a ${i === 0 ? '5,0' : n(fs[i - 1].min - 0.01)}`,
  }));
}

// Uma faixa recolhida: quantos, quantos % do quadro avaliado, e quem, ao abrir.
const DashBlocoFaixa = ({ faixa, pessoas, totalAvaliado }) => {
  const [aberto, setAberto] = React.useState(false);
  const pct = totalAvaliado ? Math.round((pessoas.length / totalAvaliado) * 1000) / 10 : 0;
  const tem = pessoas.length > 0;
  return (
    <div style={{ border: `1px solid ${faixa.cor}30`, background: faixa.cor + '10', borderRadius: 12, padding: '12px 14px' }}>
      <div onClick={() => tem && setAberto(v => !v)} style={{ display: 'flex', alignItems: 'center', gap: 10, cursor: tem ? 'pointer' : 'default' }}>
        <div style={{ width: 12, color: faixa.cor, fontSize: 11, flexShrink: 0 }}>{tem ? (aberto ? '▾' : '▸') : ''}</div>
        <div style={{ flex: 1, minWidth: 0 }}>
          <div style={{ fontSize: 13, fontWeight: 700, color: faixa.cor }}>{faixa.rotulo}</div>
          <div style={{ fontSize: 11, color: 'var(--escalab-mute)' }}>{faixa.intervalo} · {faixa.pct}</div>
        </div>
        <div style={{ textAlign: 'right', flexShrink: 0 }}>
          <div style={{ fontSize: 24, fontWeight: 900, color: faixa.cor, lineHeight: 1 }}>{pessoas.length}</div>
          <div style={{ fontSize: 11, color: 'var(--escalab-mute)' }}>{String(pct).replace('.', ',')}%</div>
        </div>
      </div>
      {aberto && (
        <div style={{ marginTop: 6, paddingLeft: 22 }}>
          {pessoas.map(x => <DashPessoaLinha key={x.colab.id} colab={x.colab} nota={x.final} sub={x.colab.setor} />)}
        </div>
      )}
    </div>
  );
};

// Uma competência recolhida: média da competência + indicadores ao abrir.
const DashBlocoIndicador = ({ bloco }) => {
  const [aberto, setAberto] = React.useState(false);
  return (
    <div style={{ borderTop: '1px solid var(--escalab-line)', padding: '8px 0' }}>
      <div onClick={() => setAberto(v => !v)} style={{ display: 'flex', alignItems: 'center', gap: 10, cursor: 'pointer' }}>
        <div style={{ width: 14, color: 'var(--escalab-mute)', fontSize: 11 }}>{aberto ? '▾' : '▸'}</div>
        <div style={{ flex: '1 1 200px', minWidth: 0 }}>
          <div style={{ fontSize: 13, fontWeight: 600, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{bloco.nome}</div>
          <div style={{ fontSize: 11, color: 'var(--escalab-mute)' }}>{bloco.categoria} · {bloco.indicadores.length} indicador(es)</div>
        </div>
        <DashBarra nota={bloco.media} />
        <NotaPill nota={bloco.media} />
      </div>
      {aberto && (
        <div style={{ paddingLeft: 24, marginTop: 6 }}>
          {bloco.indicadores.map(i => (
            <div key={i.id} style={{ display: 'flex', alignItems: 'center', gap: 10, padding: '5px 0' }}>
              <div style={{ flex: '1 1 240px', fontSize: 12, color: 'var(--escalab-slate)', lineHeight: 1.35 }}>{i.texto}</div>
              <div style={{ fontSize: 10.5, color: 'var(--escalab-mute)', whiteSpace: 'nowrap' }}>{i.n} resp.</div>
              <DashBarra nota={i.media} />
              <NotaPill nota={i.media} />
            </div>
          ))}
        </div>
      )}
    </div>
  );
};

// Uma pessoa avaliada pela diretoria: média recolhida, e ao abrir a nota que
// CADA diretor deu a ela (pedido do G&C em 27/07 — a média sozinha escondia
// divergência entre diretores sobre a mesma pessoa).
const DashPessoaPorDiretor = ({ colab, media, porDiretor }) => {
  const [aberto, setAberto] = React.useState(false);
  const temDetalhe = (porDiretor || []).length > 0;
  return (
    <div style={{ borderTop: '1px solid var(--escalab-line)' }}>
      <div onClick={() => temDetalhe && setAberto(v => !v)}
           style={{ display: 'flex', alignItems: 'center', gap: 10, padding: '7px 0', cursor: temDetalhe ? 'pointer' : 'default' }}>
        <div style={{ width: 12, color: 'var(--escalab-mute)', fontSize: 11, flexShrink: 0 }}>{temDetalhe ? (aberto ? '▾' : '▸') : ''}</div>
        <div style={{ width: 30, height: 30, borderRadius: '50%', background: colab.cor, color: '#fff', fontWeight: 700, fontSize: 11, display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }}>{colab.iniciais}</div>
        <div style={{ flex: 1, minWidth: 0 }}>
          <div style={{ fontSize: 13, fontWeight: 600, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{(colab.nome || '').split(' ').slice(0, 2).join(' ')}</div>
          <div style={{ fontSize: 11, color: 'var(--escalab-mute)' }}>{colab.setor} · {porDiretor.length} diretor(es)</div>
        </div>
        <NotaPill nota={media} />
      </div>
      {aberto && (
        <div style={{ paddingLeft: 52, paddingBottom: 6 }}>
          {porDiretor.map(d => (
            <div key={d.id} style={{ display: 'flex', alignItems: 'center', gap: 10, padding: '4px 0' }}>
              <div style={{ flex: '1 1 120px', fontSize: 12, color: 'var(--escalab-slate)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
                {(d.nome || '').split(' ').slice(0, 2).join(' ')}
                {d.papel && d.papel !== 'diretoria' && (
                  <span style={{ fontSize: 9.5, fontWeight: 800, letterSpacing: '.04em', textTransform: 'uppercase', color: '#00836B', background: '#00836B18', padding: '1px 6px', borderRadius: 999, marginLeft: 6 }}>{d.papel}</span>
                )}
              </div>
              <div style={{ fontSize: 10.5, color: 'var(--escalab-mute)', whiteSpace: 'nowrap' }}>{d.n} nota(s)</div>
              <DashBarra nota={d.media} />
              <NotaPill nota={d.media} />
            </div>
          ))}
        </div>
      )}
    </div>
  );
};

const DashCard = ({ titulo, children, hint }) => (
  <div style={{ border: '1px solid var(--escalab-line)', borderRadius: 12, padding: 16, background: '#fff' }}>
    <div style={{ fontSize: 14.5, fontWeight: 700, marginBottom: hint ? 2 : 12 }}>{titulo}</div>
    {hint && <div style={{ fontSize: 11.5, color: 'var(--escalab-mute)', marginBottom: 12 }}>{hint}</div>}
    {children}
  </div>
);

const DashboardAvdView = ({ user }) => {
  const [carregando, setCarregando] = React.useState(true);
  const [erro, setErro] = 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; };
  }, []);

  const colabs = (typeof COLABORADORES !== 'undefined' ? COLABORADORES : []);
  const ciclos = [...(typeof CICLOS !== 'undefined' ? CICLOS : [])];
  const respostas = (typeof AVD_RESPOSTAS_TODAS !== 'undefined' ? AVD_RESPOSTAS_TODAS : []);
  const cById = id => colabs.find(c => String(c.id) === String(id));

  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 cid = cicloId || null;
  const diretorIds = colabs.filter(c => c.nivel === 'diretor' || c.setor === 'Diretoria').map(c => c.id);

  // Nota final por colaborador (quem tem resposta).
  const finais = colabs.map(c => ({ colab: c, final: typeof agregarNotasAvd === 'function' ? agregarNotasAvd(c.id, cid, respostas).final : null }))
    .filter(x => x.final != null);

  // Distribuição pelas faixas do G&C (AVD_FAIXAS, data.jsx) — a mesma
  // régua da tela de resultados e do painel geral.
  //
  // Este painel era o último lugar com régua própria: partia o quadro em dois
  // no 4,0 ("Destaques" × "Críticos"), então 3,8 e 1,2 caíam na mesma caixa e a
  // pessoa aparecia como "crítica" no painel e "bom desempenho" no resultado
  // dela. Antes disso era top5/bottom5, pior ainda: numa turma boa alguém com
  // 4,5 aparecia como crítico só por ser o menor da lista.
  const faixasDash = _dashFaixas();
  const porFaixa = faixasDash.map(f => ({
    faixa: f,
    pessoas: finais.filter(x => (typeof avdFaixaRotulo === 'function' ? avdFaixaRotulo(x.final) : null) === f.rotulo)
      .sort((a, b) => b.final - a.final),
  }));

  // Média de CADA indicador (empresa toda), agrupada pela competência a que
  // pertence. Fica recolhido por competência pra não virar uma lista de 40
  // linhas soltas; abre a que interessa.
  const indPorId = {}; (typeof AVD_INDICADORES !== 'undefined' ? AVD_INDICADORES : []).forEach(i => { indPorId[i.id] = i; });
  const compPorId = {}; (typeof AVD_COMPETENCIAS !== 'undefined' ? AVD_COMPETENCIAS : []).forEach(c => { compPorId[c.id] = c; });
  // Mesma base da nota final (par + líder + liderado): a autoavaliação fica de
  // fora, senão o indicador subiria por causa de quem se avalia bem.
  const TIPOS_MEDIA_IND = ['par', 'lider', 'liderado'];
  const accInd = {};
  respostas.filter(r => r.nota != null && TIPOS_MEDIA_IND.includes(r.tipo) && (cid ? (r.cicloId || null) === cid : true))
    .forEach(r => { (accInd[r.indicadorId] = accInd[r.indicadorId] || []).push(r.nota); });
  const porCompetencia = {};
  Object.keys(accInd).forEach(indId => {
    const ind = indPorId[indId];
    const comp = ind ? compPorId[ind.competencia_id] : null;
    const chave = comp ? comp.id : '—';
    const bloco = porCompetencia[chave] = porCompetencia[chave] || {
      nome: comp ? comp.nome : 'Sem competência', categoria: comp ? comp.categoria : '', notas: [], indicadores: [],
    };
    const m = _dashMedia(accInd[indId]);
    bloco.indicadores.push({ id: indId, texto: ind ? ind.texto : indId, media: m, n: accInd[indId].length });
    bloco.notas.push(...accInd[indId]);
  });
  const blocosIndicador = Object.values(porCompetencia)
    .map(b => ({ ...b, media: _dashMedia(b.notas), indicadores: b.indicadores.sort((a, b2) => (a.media ?? 9) - (b2.media ?? 9)) }))
    .sort((a, b) => (a.media ?? 9) - (b.media ?? 9));

  // Por setor.
  const setorAcc = {};
  finais.forEach(x => { (setorAcc[x.colab.setor || '—'] = setorAcc[x.colab.setor || '—'] || []).push(x.final); });
  const porSetor = Object.keys(setorAcc).map(s => ({ setor: s, media: _dashMedia(setorAcc[s]), n: setorAcc[s].length })).sort((a, b) => (b.media || 0) - (a.media || 0));

  // Notas DADAS pelos diretores — SÓ sobre a camada mais alta da liderança
  // (os líderes de setor), que é a regra do G&C.
  //
  // Antes entrava toda nota que qualquer diretor deu a qualquer pessoa. Como o
  // diretor também avalia a ficha completa dos liderados diretos dele, o card
  // se enchia de gente que não é camada alta e o número deixava de significar
  // o que o título diz.
  //
  // Dois filtros, de propósito:
  //   tipo 'diretoria' → é a avaliação cruzada (só a parte organizacional),
  //                      não a avaliação normal que o diretor faz como líder;
  //   ehCamadaAlta     → trava por quem é avaliado, então um vínculo criado por
  //                      engano na matriz não contamina este card.
  //
  // Guarda a nota QUEBRADA POR DIRETOR além da média: o G&C pediu (27/07) pra
  // ver quanto cada diretor deu a cada pessoa. A média sozinha escondia o caso
  // em que dois diretores discordam fortemente sobre a mesma pessoa.
  //
  // 05/08 · o card ignorava o líder. Quando o líder da pessoa É um diretor, ele
  // não responde como 'diretoria' — responde a ficha inteira como 'lider', e a
  // parte organizacional dela ficava de fora deste card. A Amanda aparecia com a
  // nota dos outros diretores e sem a da Maria, que é a diretora que a lidera.
  // Aqui entra a MESMA competência organizacional, vinda da linha de 'lider',
  // e só quando quem respondeu é diretor — a régua do card continua sendo
  // "organizacional, dado por diretor".
  const _ehAlta = c => (typeof ehCamadaAlta === 'function') ? ehCamadaAlta(c?.nome) : true;
  const _catBase = c => (typeof avdCategoriaBase === 'function' ? avdCategoriaBase(c) : c);
  const dadasDir = {};      // avaliadoId -> [nota]
  const dadasDirPorAv = {}; // avaliadoId -> { avaliadorId: [nota] }
  respostas.filter(r => r.nota != null
                     && diretorIds.includes(r.avaliadorId)
                     && (r.tipo === 'diretoria'
                         || (r.tipo === 'lider' && _catBase(r.categoria) === 'organizacional'))
                     && (cid ? (r.cicloId || null) === cid : true))
    .forEach(r => {
      (dadasDir[r.avaliadoId] = dadasDir[r.avaliadoId] || []).push(r.nota);
      const porAv = dadasDirPorAv[r.avaliadoId] = dadasDirPorAv[r.avaliadoId] || {};
      const cel = porAv[r.avaliadorId] = porAv[r.avaliadorId] || { notas: [], papeis: {} };
      cel.notas.push(r.nota);
      cel.papeis[r.tipo] = true;
    });
  const notasDadasDiretores = Object.keys(dadasDir).map(id => {
    const porAv = dadasDirPorAv[id] || {};
    const porDiretor = Object.keys(porAv).map(avId => {
      const dir = cById(avId);
      const cel = porAv[avId];
      // Distingue as duas origens: a avaliação cruzada da diretoria e a nota que
      // o diretor deu como LÍDER da pessoa. É a mesma competência, mas não é o
      // mesmo olhar — e o G&C quer saber qual é qual.
      return {
        id: avId, nome: dir ? dir.nome : 'Diretor(a)',
        media: _dashMedia(cel.notas), n: cel.notas.length,
        papel: cel.papeis.lider ? (cel.papeis.diretoria ? 'diretoria + líder' : 'como líder') : 'diretoria',
      };
    }).sort((a, b) => (b.media || 0) - (a.media || 0));
    return { colab: cById(id), media: _dashMedia(dadasDir[id]), porDiretor };
  })
    .filter(x => x.colab && !diretorIds.includes(x.colab.id) && _ehAlta(x.colab))
    .sort((a, b) => (b.media || 0) - (a.media || 0));

  // Notas dos DIRETORES (eles como avaliados), pela nota final.
  const notasDiretores = finais.filter(x => diretorIds.includes(x.colab.id)).sort((a, b) => b.final - a.final);

  const semDados = !finais.length;

  return (
    <div>
      <div style={{ display: 'flex', gap: 10, alignItems: 'center', flexWrap: 'wrap', marginBottom: 18 }}>
        <div style={{ fontSize: 13, color: 'var(--escalab-slate)' }}>Painel do ciclo</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>

      {semDados && (
        <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 }}>
          Ainda não há notas suficientes {cicloId ? 'neste ciclo' : ''} para o dashboard. Assim que houver respostas (Fase 3), os painéis se preenchem.
        </div>
      )}

      {!semDados && (
        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(300px, 1fr))', gap: 14 }}>
          <div style={{ gridColumn: '1 / -1' }}>
            <DashCard titulo={`Distribuição por faixa de desempenho · ${finais.length} pessoa(s)`}
              hint="As faixas do G&C, iguais às do resultado individual e do painel geral. Clique numa faixa para ver quem está nela.">
              <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(230px, 1fr))', gap: 12, alignItems: 'start' }}>
                {porFaixa.map(b => <DashBlocoFaixa key={b.faixa.rotulo} faixa={b.faixa} pessoas={b.pessoas} totalAvaliado={finais.length} />)}
              </div>
            </DashCard>
          </div>

          <DashCard titulo="Média por setor">
            {porSetor.map(s => (
              <div key={s.setor} style={{ display: 'flex', alignItems: 'center', gap: 10, padding: '6px 0' }}>
                <div style={{ width: 130, fontSize: 12.5, fontWeight: 600, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }} title={s.setor}>{s.setor}</div>
                <DashBarra nota={s.media} />
                <NotaPill nota={s.media} />
              </div>
            ))}
          </DashCard>

          <DashCard titulo="Notas dadas pelos diretores" hint="Média de cada colaborador — clique para ver quanto cada diretor deu a ele. Só sobre a camada mais alta da liderança (os líderes de setor), e só na competência organizacional. Quando o líder da pessoa é um diretor, a nota organizacional que ele deu como líder entra aqui também, marcada como tal.">
            {diretorIds.length === 0 && <div style={{ fontSize: 12.5, color: 'var(--escalab-mute)', fontStyle: 'italic' }}>Nenhum diretor identificado (marque nível "diretor" ou setor "Diretoria" nos colaboradores).</div>}
            {notasDadasDiretores.map(x => <DashPessoaPorDiretor key={x.colab.id} colab={x.colab} media={x.media} porDiretor={x.porDiretor} />)}
            {diretorIds.length > 0 && !notasDadasDiretores.length && <div style={{ fontSize: 12.5, color: 'var(--escalab-mute)', fontStyle: 'italic' }}>A diretoria ainda não avaliou a camada mais alta neste ciclo.</div>}
          </DashCard>

          <DashCard titulo="Notas dos diretores" hint="Nota final de cada diretor.">
            {notasDiretores.map(x => <DashPessoaLinha key={x.colab.id} colab={x.colab} nota={x.final} sub={x.colab.setor} />)}
            {!notasDiretores.length && <div style={{ fontSize: 12.5, color: 'var(--escalab-mute)', fontStyle: 'italic' }}>Sem notas finais de diretores ainda.</div>}
          </DashCard>

          <div style={{ gridColumn: '1 / -1' }}>
            <DashCard titulo="Média por indicador" hint="Empresa toda, da competência mais fraca para a mais forte. Clique numa competência para abrir indicador por indicador. Mesma base da nota final (pares, líder e liderados — sem autoavaliação).">
              {!blocosIndicador.length && <div style={{ fontSize: 12.5, color: 'var(--escalab-mute)', fontStyle: 'italic' }}>Sem respostas com nota neste recorte.</div>}
              {blocosIndicador.map(b => <DashBlocoIndicador key={b.nome} bloco={b} />)}
            </DashCard>
          </div>
        </div>
      )}
    </div>
  );
};

window.DashboardAvdView = DashboardAvdView;
