// Performance module — cycles · evaluation form · Nine Box matrix
// Datos derivados desde window.* (performance-data.jsx · Fase A)
const { useState: _pf_useState, useMemo: _pf_useMemo } = React;

// ─── Derivadores desde el store global ───────────────────

// Mapa de modelo de ciclo según las metodologías combinadas que tenga.
const _modelFromMetodologias = (m = []) => {
  if (m.includes('360')) return '360';
  if (m.includes('180')) return '180';
  if (m.includes('90'))  return '90';
  return '180';
};
const _stateFromCiclo = (estado) => {
  if (estado === 'configurando') return 'configurando';
  if (estado === 'publicado' || estado === 'archivado') return 'cerrado';
  return 'progreso';
};
const _closesInLabel = (c) => {
  if (c.estado === 'configurando') return `Inicia ${c.apertura}`;
  if (c.estado === 'publicado')    return `Cerrado el ${c.cierre}`;
  if (c.apertura === 'continuo')   return 'Continuo';
  return `Cierra el ${c.cierre}`;
};

const CYCLES = (window.CICLOS_EVALUACION || []).map(c => ({
  id: c.id,
  name: c.nombre,
  model: _modelFromMetodologias(c.metodologias),
  period: `${c.periodo.inicio} → ${c.periodo.fin}`,
  state: _stateFromCiclo(c.estado),
  completion: c.completitudPct,
  evaluators: c.evaluadores,
  evaluated: c.invitados,
  closesIn: _closesInLabel(c),
  owner: c.responsable,
  metodologias: c.metodologias,
  raw: c,
}));

const STATE_CYCLE = {
  configurando: { label: 'Configurando', pill: 'navy',       dot: 'var(--navy-800)' },
  progreso:     { label: 'En progreso',  pill: 'amber-soft', dot: '#854D0E' },
  cerrado:      { label: 'Cerrado',      pill: 'green',      dot: 'var(--green-600)' },
};

const MODEL_TONE = { '90': 'navy', '180': 'blue', '360': 'amber' };

// Nine-Box derivado del último snapshot
const _lastSnapshot = (window.NINE_BOX_SNAPSHOTS || [])[0];
const NINE_BOX = (_lastSnapshot?.personas || []).map(p => {
  const persona = (window.PERSONAS_DESEMPENO || {})[p.empId] || {};
  const cargo = (window.CARGOS || []).find(c => c.id === persona.cargoId) || {};
  return {
    id: p.empId,
    initials: persona.initials || '??',
    name: persona.nombre || p.empId,
    role: cargo.nombre || '—',
    area: cargo.area || '—',
    site: 'Cali',
    perf: p.perf, pot: p.pot, score: p.score,
  };
});

// Box layout: rows top-to-bottom = pot 3,2,1 ; cols left-to-right = perf 1,2,3
const NINE_BOX_LAYOUT = [
  // [perf, pot, label, tone]
  [{ p: 1, t: 3, name: 'Enigma',              tone: 'amber' }, { p: 2, t: 3, name: 'Alto potencial',     tone: 'blue'  }, { p: 3, t: 3, name: 'Estrella',         tone: 'green' }],
  [{ p: 1, t: 2, name: 'Dilema',              tone: 'rose'  }, { p: 2, t: 2, name: 'Core player',         tone: 'navy'  }, { p: 3, t: 2, name: 'Alto rendimiento', tone: 'green' }],
  [{ p: 1, t: 1, name: 'Bajo rendimiento',    tone: 'rose'  }, { p: 2, t: 1, name: 'Contribuidor sólido', tone: 'amber' }, { p: 3, t: 1, name: 'Efectivo',         tone: 'blue'  }],
];

// ─── Root ────────────────────────────────────────────────

const Performance = () => {
  const [tab, setTab] = _pf_useState('cycles');
  const [newCycleOpen, setNewCycleOpen] = _pf_useState(false);
  const [cyclesTick, setCyclesTick] = _pf_useState(0);
  const [selectedCycleId, setSelectedCycleId] = _pf_useState(null);

  // Si hay un ciclo seleccionado · pantalla completa de detalle
  if (selectedCycleId && window.CycleDetailScreen) {
    return <CycleDetailScreen cicloId={selectedCycleId} onBack={() => setSelectedCycleId(null)} />;
  }

  // KPIs derivados del store global
  const ciclos = window.CICLOS_EVALUACION || [];
  const ciclosActivos = ciclos.filter(c => c.estado !== 'publicado' && c.estado !== 'archivado').length;
  const todasInst = window.EVALUACIONES_INSTANCIA || [];
  const enviadas = todasInst.filter(e => e.estado === 'enviado-firmado').length;
  const pendientes = todasInst.filter(e => e.estado === 'pendiente' || e.estado === 'borrador').length;
  const tasa = todasInst.length > 0 ? Math.round((enviadas / todasInst.length) * 100) : 0;

  return (
    <div className="main" data-screen-label="Desempeño">
      <div className="page-head">
        <div>
          <h1 className="page-title">Evaluación de Desempeño</h1>
          <div className="page-subtitle">
            <b>{ciclosActivos} ciclos activos</b> · {tasa}% tasa de respuesta global · {pendientes} pendientes en gestión
          </div>
        </div>
        <div style={{ display: 'flex', gap: 8 }}>
          <button className="btn"><IconBarChart size={14} /> Reporte general</button>
          <button className="btn primary" onClick={() => setNewCycleOpen(true)}><IconPlus size={14} /> Nuevo ciclo</button>
        </div>
      </div>

      {/* KPIs · vista organizacional */}
      <div className="tr-kpis">
        <div className="tr-kpi">
          <div className="tr-kpi-icon navy"><IconCalendar size={18} /></div>
          <div>
            <div className="tr-kpi-num">{ciclosActivos}</div>
            <div className="tr-kpi-lbl">Ciclos activos</div>
            <div className="tr-kpi-foot muted">Configurando, en progreso o calibrando</div>
          </div>
        </div>
        <div className="tr-kpi">
          <div className="tr-kpi-icon green"><IconCheck size={18} /></div>
          <div>
            <div className="tr-kpi-num">{tasa}<small>%</small></div>
            <div className="tr-kpi-lbl">Tasa de respuesta global</div>
            <div className="tr-kpi-foot up">{enviadas} de {todasInst.length} firmadas Ley 527</div>
          </div>
        </div>
        <div className="tr-kpi">
          <div className="tr-kpi-icon rose"><IconClock size={18} /></div>
          <div>
            <div className="tr-kpi-num">{pendientes}</div>
            <div className="tr-kpi-lbl">Pendientes en gestión</div>
            <div className="tr-kpi-foot down">Requieren acción de RRHH o jefes</div>
          </div>
        </div>
        <div className="tr-kpi">
          <div className="tr-kpi-icon amber"><IconStar size={18} /></div>
          <div>
            <div className="tr-kpi-num">{(window.INCIDENTES_CRITICOS || []).length}</div>
            <div className="tr-kpi-lbl">Incidentes registrados</div>
            <div className="tr-kpi-foot">Bitácora inmutable · CST Art. 62</div>
          </div>
        </div>
      </div>

      {/* Tabs · admin organizacional · NO vista de evaluador */}
      <div className="doc-tabs">
        <button className={`doc-tab ${tab === 'cycles' ? 'active' : ''}`} onClick={() => setTab('cycles')}>
          <IconCalendar size={14} /> Ciclos
        </button>
        <button className={`doc-tab ${tab === 'pendientes' ? 'active' : ''}`} onClick={() => setTab('pendientes')}>
          <IconClock size={14} /> Pendientes & seguimiento
          {pendientes > 0 && <span className="epp-tab-pill rose">{pendientes}</span>}
        </button>
        <button className={`doc-tab ${tab === 'analisis' ? 'active' : ''}`} onClick={() => setTab('analisis')}>
          <IconBarChart size={14} /> Análisis
        </button>
        <button className={`doc-tab ${tab === 'incidentes' ? 'active' : ''}`} onClick={() => setTab('incidentes')}>
          <IconShield size={14} /> Incidentes
          <span className="epp-tab-pill">{(window.INCIDENTES_CRITICOS || []).length}</span>
        </button>
        <button className={`doc-tab ${tab === '1on1' ? 'active' : ''}`} onClick={() => setTab('1on1')}>
          <IconUsers size={14} /> 1-on-1
        </button>
        <button className={`doc-tab ${tab === 'kudos' ? 'active' : ''}`} onClick={() => setTab('kudos')}>
          <IconStar size={14} /> Reconocimientos
        </button>
        <button className={`doc-tab ${tab === 'calibracion' ? 'active' : ''}`} onClick={() => setTab('calibracion')}>
          <IconShield size={14} /> Calibración
        </button>
        <button className={`doc-tab ${tab === 'ninebox' ? 'active' : ''}`} onClick={() => setTab('ninebox')}>
          <IconBarChart size={14} /> Nine Box
        </button>
        <button className={`doc-tab ${tab === 'config' ? 'active' : ''}`} onClick={() => setTab('config')}>
          <IconExternal size={14} /> Configuración
        </button>
      </div>

      {tab === 'cycles'      && <CyclesSection key={cyclesTick} onPickCycle={(id) => setSelectedCycleId(id)} />}
      {tab === 'pendientes'  && window.PendientesSeguimientoTab && <PendientesSeguimientoTab />}
      {tab === 'analisis'    && window.AnalisisTab && <AnalisisTab />}
      {tab === 'incidentes'  && window.IncidentesTab && <IncidentesTab />}
      {tab === '1on1'        && window.OneOnOneTab && <OneOnOneTab />}
      {tab === 'kudos'       && window.KudosTab && <KudosTab />}
      {tab === 'calibracion' && window.CalibracionGlobalTab && <CalibracionGlobalTab />}
      {tab === 'ninebox'     && <NineBoxSection />}
      {tab === 'config'      && window.ConfiguracionTab && <ConfiguracionTab />}

      {newCycleOpen && (
        <NewCycleModal
          onClose={() => setNewCycleOpen(false)}
          onSave={() => setCyclesTick(t => t + 1)}
        />
      )}
    </div>
  );
};

// ─── Section: Ciclos ────────────────────────────────────

const CyclesSection = ({ onPickCycle }) => {
  // Re-leer en cada render por si NewCycleModal agregó uno nuevo
  const cycles = (window.CICLOS_EVALUACION || []).map(c => ({
    id: c.id, name: c.nombre,
    model: c.metodologias.includes('360') ? '360' : c.metodologias.includes('180') ? '180' : '90',
    period: `${c.periodo.inicio} → ${c.periodo.fin}`,
    state: c.estado === 'configurando' ? 'configurando' : (c.estado === 'publicado' || c.estado === 'archivado') ? 'cerrado' : 'progreso',
    completion: c.completitudPct, evaluators: c.evaluadores, evaluated: c.invitados,
    estadoFase: c.estado,
    closesIn: c.estado === 'configurando' ? `Inicia ${c.apertura}` :
              c.estado === 'publicado'    ? `Cerrado el ${c.cierre}` :
              c.apertura === 'continuo'   ? 'Continuo' : `Cierra el ${c.cierre}`,
    owner: c.responsable, metodologias: c.metodologias,
  }));
  return (
    <div className="pf-cycles">
      {cycles.map(c => {
        const s = STATE_CYCLE[c.state];
        const tone = MODEL_TONE[c.model];
        const is360 = c.model === '360';
        return (
          <div key={c.id} className={`pf-cycle-card ${is360 ? 'is-360' : ''} pf-cycle-clickable`}
               onClick={() => onPickCycle(c.id)}
               role="button" tabIndex={0}>
            <div className="pf-cycle-head">
              <div style={{ minWidth: 0, flex: 1 }}>
                <div className="muted mono" style={{ fontSize: 11 }}>{c.id}</div>
                <h3 className="pf-cycle-name">{c.name}</h3>
                <div className="muted" style={{ fontSize: 12, marginTop: 4 }}>
                  Período: <span className="mono">{c.period}</span> · responsable {c.owner}
                </div>
              </div>
              <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'flex-end', gap: 6 }}>
                <span className={`pf-model-badge ${tone}`}>{c.model}°</span>
                <span className={`pill ${s.pill}`}>
                  <span className="status-dot" style={{ background: s.dot }} /> {c.estadoFase}
                </span>
              </div>
            </div>

            {c.metodologias && c.metodologias.length > 0 && (
              <div className="pf-cycle-meto-row">
                {c.metodologias.map(m => <MetodologiaChip key={m} id={m} size="sm" />)}
              </div>
            )}

            <div className="pf-cycle-stats">
              <div>
                <div className="muted-xs">Evaluadores</div>
                <div className="pf-cycle-stat">{c.evaluators}</div>
              </div>
              <div>
                <div className="muted-xs">Evaluados</div>
                <div className="pf-cycle-stat">{c.evaluated.toLocaleString()}</div>
              </div>
              <div>
                <div className="muted-xs">Completitud</div>
                <div className="pf-cycle-prog">
                  <div className="tr-prog-track" style={{ flex: 1 }}>
                    <div className={`tr-prog-fill ${c.completion >= 80 ? 'green' : c.completion >= 40 ? 'amber' : 'rose'}`}
                         style={{ width: `${c.completion}%` }} />
                  </div>
                  <span className="pf-cycle-pct">{c.completion}%</span>
                </div>
              </div>
              <div>
                <div className="muted-xs">Calendario</div>
                <div className="pf-cycle-stat-soft mono">{c.closesIn}</div>
              </div>
            </div>

            <div className="pf-cycle-foot">
              <button className="btn primary" style={{ flex: 1 }}>
                <IconExternal size={13} /> Abrir gestión del ciclo →
              </button>
            </div>
          </div>
        );
      })}
    </div>
  );
};

// ─── Section: Nine Box (interactivo · Fase B+) ───────────

const NineBoxSection = () => {
  const snapshots = window.NINE_BOX_SNAPSHOTS || [];
  const [snapId, setSnapId] = _pf_useState(snapshots[0]?.id || null);
  const [filterArea, setFilterArea] = _pf_useState('todas');
  const [filterSite, setFilterSite] = _pf_useState('todas');
  const [selected, setSelected] = _pf_useState(null);   // persona en panel lateral
  const [cellMenu, setCellMenu] = _pf_useState(null);   // cuadrante con menú abierto
  const [exportOpen, setExportOpen] = _pf_useState(false);
  const [sucesion, setSucesion] = _pf_useState(false);
  const [howToOpen, setHowToOpen] = _pf_useState(false);

  const snap = snapshots.find(s => s.id === snapId) || snapshots[0];

  if (snapshots.length === 0) {
    return (
      <div className="empty-state" style={{ padding: 60 }}>
        <IconBarChart size={36} style={{ color: 'var(--text-subtle)' }} />
        <div style={{ fontWeight: 700, fontSize: 15, marginTop: 10 }}>Sin snapshots disponibles</div>
        <div className="muted" style={{ fontSize: 13, maxWidth: 480, textAlign: 'center', lineHeight: 1.55 }}>
          El Nine Box se genera automáticamente cuando un ciclo de evaluación se publica.
          Crea un ciclo, complétalo y publícalo para ver el primer snapshot aquí.
        </div>
      </div>
    );
  }

  // Reconstruir lista de personas con metadata desde el snapshot + PERSONAS_DESEMPENO + CARGOS
  const people = _pf_useMemo(() => {
    if (!snap) return [];
    return snap.personas.map(p => {
      const persona = (window.PERSONAS_DESEMPENO || {})[p.empId] || {};
      const cargo = (window.CARGOS || []).find(c => c.id === persona.cargoId) || {};
      return {
        id: p.empId,
        initials: persona.initials || '??',
        name: persona.nombre || p.empId,
        role: cargo.nombre || '—',
        area: cargo.area || '—',
        site: 'Cali',
        cargoId: persona.cargoId,
        nivel: cargo.nivel,
        perf: p.perf, pot: p.pot, score: p.score,
        // mock: cargo crítico = liderazgo o directivo
        esCritico: cargo.nivel === 'liderazgo' || cargo.nivel === 'directivo',
      };
    });
  }, [snap]);

  const areas = _pf_useMemo(() => Array.from(new Set(people.map(p => p.area))), [people]);
  const filtered = people.filter(p =>
    (filterArea === 'todas' || p.area === filterArea) &&
    (filterSite === 'todas' || p.site === filterSite)
  );

  const inCell = (perf, pot) => filtered.filter(p => p.perf === perf && p.pot === pot);

  return (
    <>
      <div className="sst-quickfilter">
        <select value={snapId || ''} onChange={(e) => setSnapId(e.target.value)}>
          {snapshots.map(s => {
            const ciclo = (window.CICLOS_EVALUACION || []).find(c => c.id === s.cicloId);
            return <option key={s.id} value={s.id}>{ciclo?.nombre || s.id} · {s.fecha}</option>;
          })}
        </select>
        <select value={filterArea} onChange={(e) => setFilterArea(e.target.value)}>
          <option value="todas">Todas las áreas</option>
          {areas.map(a => <option key={a}>{a}</option>)}
        </select>
        <select value={filterSite} onChange={(e) => setFilterSite(e.target.value)}>
          <option value="todas">Todas las sedes</option>
          <option>Cali</option>
          <option>Barranquilla</option>
          <option>Bogotá</option>
        </select>
        <button
          className={`btn ${sucesion ? 'primary' : ''}`}
          onClick={() => setSucesion(s => !s)}
          title="Resalta cargos críticos con anillo dorado"
        >
          <IconShield size={13} /> Vista sucesión
        </button>
        <span className="muted" style={{ fontSize: 12, marginLeft: 'auto' }}>
          {filtered.length} de {people.length} colaboradores
        </span>
        <button className="btn" onClick={() => setExportOpen(true)}>
          <IconExternal size={14} /> Exportar PDF
        </button>
      </div>

      {snap && (
        <div className="pf-ninebox-meta">
          <span className="muted-xs">Snapshot</span>
          <span className="mono" style={{ fontSize: 11.5 }}>{snap.id}</span>
          <span className="muted">·</span>
          <span style={{ fontSize: 11.5 }}>aprobado por <b>{snap.aprobadoPor}</b></span>
          <span className="muted">·</span>
          <span className="pill green" style={{ fontSize: 10 }}>inmutable · ICONTEC</span>
          <button className="link-btn" style={{ marginLeft: 'auto' }} onClick={() => setHowToOpen(true)}>
            ¿Cómo aparecen las personas?
          </button>
        </div>
      )}

      {howToOpen && <NineBoxHowToModal onClose={() => setHowToOpen(false)} />}

      <div className={`pf-ninebox-layout ${selected ? 'with-panel' : ''}`}>
        <div className="pf-ninebox-main">
          <div className="pf-ninebox-wrap">
            <div className="pf-ninebox-yaxis">
              <div className="pf-ninebox-axis-title">Potencial</div>
              <div className="pf-ninebox-axis-labels">
                <span>Alto</span><span>Medio</span><span>Bajo</span>
              </div>
            </div>

            <div className="pf-ninebox-grid">
              {NINE_BOX_LAYOUT.map((row, ri) =>
                row.map((cell, ci) => {
                  const peopleInCell = inCell(cell.p, cell.t);
                  return (
                    <div key={`${ri}-${ci}`} className={`pf-cell pf-cell-${cell.tone}`}>
                      <div className="pf-cell-head">
                        <span className="pf-cell-name">{cell.name}</span>
                        <span className="pf-cell-count">{peopleInCell.length}</span>
                        <button
                          className="pf-cell-menu-btn"
                          title="Acciones masivas"
                          onClick={(e) => { e.stopPropagation(); setCellMenu(cellMenu?.key === `${ri}-${ci}` ? null : { key: `${ri}-${ci}`, cell, peopleInCell }); }}
                        >⋯</button>
                        {cellMenu?.key === `${ri}-${ci}` && (
                          <NineBoxCellMenu
                            cell={cellMenu.cell}
                            people={cellMenu.peopleInCell}
                            onClose={() => setCellMenu(null)}
                          />
                        )}
                      </div>
                      <div className="pf-cell-avatars">
                        {peopleInCell.slice(0, 6).map(p => (
                          <button
                            key={p.id}
                            className={`pf-cell-avatar ${selected?.id === p.id ? 'active' : ''} ${sucesion && p.esCritico ? 'critico' : ''}`}
                            onClick={() => setSelected(p)}
                            title={p.name}
                          >
                            {p.initials}
                          </button>
                        ))}
                        {peopleInCell.length > 6 && <div className="pf-cell-avatar more">+{peopleInCell.length - 6}</div>}
                        {peopleInCell.length === 0 && <div className="muted" style={{ fontSize: 10.5, padding: '4px 0' }}>—</div>}
                      </div>
                    </div>
                  );
                })
              )}
            </div>

            <div className="pf-ninebox-spacer" />
            <div className="pf-ninebox-xaxis">
              <div className="pf-ninebox-axis-labels">
                <span>Bajo</span><span>Medio</span><span>Alto</span>
              </div>
              <div className="pf-ninebox-axis-title">Desempeño</div>
            </div>
          </div>

          {sucesion && (
            <div className="pf-ninebox-legend">
              <span className="pf-suc-marker" /> Cargo crítico (liderazgo o directivo)
            </div>
          )}
        </div>

        {selected && (
          <NineBoxPersonPanel
            persona={selected}
            onClose={() => setSelected(null)}
            cell={NINE_BOX_LAYOUT.flat().find(c => c.p === selected.perf && c.t === selected.pot)}
          />
        )}
      </div>

      {exportOpen && <NineBoxExportModal snapshot={snap} people={filtered} onClose={() => setExportOpen(false)} />}
    </>
  );
};

// ─── Panel lateral con detalle de la persona ─────────────

const NineBoxPersonPanel = ({ persona, cell, onClose }) => {
  const [actionTaken, setActionTaken] = _pf_useState(null);
  const objetivos  = (window.objetivosVigentesPara && window.objetivosVigentesPara(persona.id)) || [];
  const incidentes = (window.incidentesVisiblesPara && window.incidentesVisiblesPara(persona.id)) || [];
  const kudos      = (window.kudosRecibidos && window.kudosRecibidos(persona.id)) || [];
  const ultimo1o1  = ((window.ultimos1on1 && window.ultimos1on1(persona.id, 1)) || [])[0];
  const pip        = (window.pipActivoPara && window.pipActivoPara(persona.id)) || null;

  const interpretaciones = {
    'Estrella':            { tone: 'green', accion: 'Plan de sucesión · expandir scope · retención prioritaria.' },
    'Alto potencial':      { tone: 'blue',  accion: 'Inversión en formación · mentoring · rotación a otra área.' },
    'Alto rendimiento':    { tone: 'green', accion: 'Reconocer · involucrar en proyectos críticos.' },
    'Enigma':              { tone: 'amber', accion: 'Investigar bloqueos · feedback honesto · plan de mejora.' },
    'Core player':         { tone: 'navy',  accion: 'Mantener · feedback regular · oportunidades de crecimiento.' },
    'Efectivo':            { tone: 'blue',  accion: 'Especialista en su rol · reconocer aporte estable.' },
    'Dilema':              { tone: 'rose',  accion: 'Conversación de claridad · evaluar si el cargo es el adecuado.' },
    'Contribuidor sólido': { tone: 'amber', accion: 'Acompañamiento cercano · objetivos a corto plazo.' },
    'Bajo rendimiento':    { tone: 'rose',  accion: 'PIP formal · evaluar continuidad con debido proceso.' },
  };
  const interp = interpretaciones[cell?.name] || { tone: 'navy', accion: '—' };

  // Score breakdown mock
  const compScore = (persona.score * 0.6 + 1).toFixed(1);
  const objScore  = Math.round(objetivos.reduce((s, o) => s + o.logroPct, 0) / Math.max(1, objetivos.length));

  const toast = (msg) => { setActionTaken(msg); setTimeout(() => setActionTaken(null), 2400); };

  return (
    <aside className="pf-nb-panel">
      <div className="pf-nb-panel-head">
        <button className="icon-btn" onClick={onClose} title="Cerrar">
          <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round"><path d="M18 6 6 18M6 6l12 12"/></svg>
        </button>
        <div className="ats-card-avatar lg" style={{ width: 48, height: 48, fontSize: 16, borderRadius: 12 }}>{persona.initials}</div>
        <div style={{ flex: 1, minWidth: 0 }}>
          <div style={{ fontWeight: 800, fontSize: 15, letterSpacing: '-0.01em' }}>{persona.name}</div>
          <div className="muted" style={{ fontSize: 12 }}>{persona.role}</div>
          <div className="muted mono" style={{ fontSize: 10.5, marginTop: 2 }}>{persona.id} · {persona.area} · {persona.site}</div>
        </div>
      </div>

      {/* Score breakdown */}
      <div className="pf-nb-scores">
        <div>
          <div className="muted-xs">Score consolidado</div>
          <div className="pf-nb-score-num">{persona.score.toFixed(1)}<small>/5</small></div>
        </div>
        <div>
          <div className="muted-xs">Competencias</div>
          <div className="pf-nb-score-num">{compScore}<small>/5</small></div>
        </div>
        <div>
          <div className="muted-xs">Objetivos</div>
          <div className="pf-nb-score-num">{objScore || '—'}<small>%</small></div>
        </div>
      </div>

      {/* Cuadrante + interpretación */}
      <div className={`pf-nb-quad pf-nb-quad-${interp.tone}`}>
        <div className="pf-nb-quad-head">
          <span className="muted-xs">Cuadrante</span>
          <span className="pf-nb-quad-name">{cell?.name || '—'}</span>
        </div>
        <div className="pf-nb-quad-coords mono">desempeño {persona.perf}/3 · potencial {persona.pot}/3</div>
        <div className="pf-nb-quad-accion">
          <IconShield size={12} /> {interp.accion}
        </div>
      </div>

      {/* Último 1-on-1 */}
      <div className="pf-nb-block">
        <div className="muted-xs">Último 1-on-1</div>
        {ultimo1o1 ? (
          <div className="pf-nb-1o1">
            <div className="mono" style={{ fontSize: 11 }}>{ultimo1o1.fecha}</div>
            <div className="muted" style={{ fontSize: 11.5, lineHeight: 1.5, marginTop: 4 }}>
              {ultimo1o1.acuerdos.length} acuerdo{ultimo1o1.acuerdos.length === 1 ? '' : 's'} · firmado
            </div>
          </div>
        ) : (
          <div className="muted" style={{ fontSize: 11.5 }}>Sin 1-on-1 recientes.</div>
        )}
      </div>

      {/* Reconocimientos + Incidentes resumen */}
      <div className="pf-nb-stats-row">
        <div>
          <div className="muted-xs">Reconocimientos</div>
          <div style={{ fontSize: 18, fontWeight: 800 }}>{kudos.length}</div>
          <div className="muted" style={{ fontSize: 10.5 }}>{kudos.filter(k => k.impacto === 'alto').length} de alto impacto</div>
        </div>
        <div>
          <div className="muted-xs">Incidentes</div>
          <div style={{ fontSize: 18, fontWeight: 800, color: incidentes.length > 0 ? 'var(--aguila-600)' : 'var(--text)' }}>{incidentes.length}</div>
          <div className="muted" style={{ fontSize: 10.5 }}>último período</div>
        </div>
        <div>
          <div className="muted-xs">PIP</div>
          <div style={{ fontSize: 18, fontWeight: 800, color: pip ? 'var(--green-600)' : 'var(--text-muted)' }}>{pip ? '✓' : '—'}</div>
          <div className="muted" style={{ fontSize: 10.5 }}>{pip ? 'activo' : 'sin plan'}</div>
        </div>
      </div>

      {/* Acciones rápidas */}
      <div className="pf-nb-actions">
        <button className="btn primary" onClick={() => {
          if (window.__navigateToEmployee) {
            window.__navigateToEmployee(persona.id);
          } else {
            toast('No se pudo navegar · recarga la app');
          }
        }}>
          <IconExternal size={13} /> Ver ficha completa
        </button>
        <button className="btn" onClick={() => toast('1-on-1 programado para la próxima semana')}>
          <IconCalendar size={13} /> Programar 1-on-1
        </button>
        {!pip && persona.perf <= 2 && (
          <button className="btn" onClick={() => toast('Borrador de PIP creado · pendiente de firma')}>
            <IconShield size={13} /> Crear PIP
          </button>
        )}
        {persona.pot >= 3 && (
          <button className="btn" onClick={() => toast(`${persona.name} marcado/a para sucesión · notificado al Comité de Talento`)}>
            <IconStar size={13} /> Marcar para sucesión
          </button>
        )}
        {persona.pot >= 2 && (
          <button className="btn" onClick={() => toast('Solicitud de evaluación 360° enviada a RRHH')}>
            <IconUsers size={13} /> Solicitar 360°
          </button>
        )}
      </div>

      {actionTaken && (
        <div className="pf-nb-toast">
          <IconCheck size={12} /> {actionTaken}
        </div>
      )}
    </aside>
  );
};

// ─── Menú de acciones masivas por cuadrante ───────────────

const NineBoxCellMenu = ({ cell, people, onClose }) => {
  const [actionTaken, setActionTaken] = _pf_useState(null);
  React.useEffect(() => {
    const handler = (e) => { if (!e.target.closest('.pf-cell-menu')) onClose(); };
    setTimeout(() => document.addEventListener('click', handler), 0);
    return () => document.removeEventListener('click', handler);
  }, []);

  const trigger = (msg) => { setActionTaken(msg); setTimeout(onClose, 1500); };
  const esBajo = cell.p === 1;
  const esAlto = cell.t === 3 || (cell.p === 3 && cell.t === 2);

  if (people.length === 0) {
    return (
      <div className="pf-cell-menu" onClick={(e) => e.stopPropagation()}>
        <div className="pf-cell-menu-empty">Sin colaboradores en este cuadrante</div>
      </div>
    );
  }

  if (actionTaken) {
    return <div className="pf-cell-menu" onClick={(e) => e.stopPropagation()}><div className="pf-cell-menu-toast"><IconCheck size={11} /> {actionTaken}</div></div>;
  }

  return (
    <div className="pf-cell-menu" onClick={(e) => e.stopPropagation()}>
      <div className="pf-cell-menu-head">
        <b>{cell.name}</b>
        <span className="muted" style={{ fontSize: 11 }}>· {people.length} persona{people.length === 1 ? '' : 's'}</span>
      </div>
      <button className="pf-cell-menu-item" onClick={() => trigger(`1-on-1 programado para ${people.length} personas`)}>
        <IconCalendar size={12} /> Programar 1-on-1 con todos
      </button>
      {esBajo && (
        <button className="pf-cell-menu-item" onClick={() => trigger(`PIP creado para ${people.length} personas · pendiente firma`)}>
          <IconShield size={12} /> Crear PIP para todos
        </button>
      )}
      {esAlto && (
        <button className="pf-cell-menu-item" onClick={() => trigger(`${people.length} marcados/as para sucesión`)}>
          <IconStar size={12} /> Marcar para sucesión
        </button>
      )}
      <button className="pf-cell-menu-item" onClick={() => trigger('Lista exportada en CSV')}>
        <IconExternal size={12} /> Exportar lista del cuadrante
      </button>
    </div>
  );
};

// ─── Modal de exportación PDF ─────────────────────────────

const NineBoxExportModal = ({ snapshot, people, onClose }) => {
  React.useEffect(() => {
    document.body.style.overflow = 'hidden';
    return () => { document.body.style.overflow = ''; };
  }, []);

  const ciclo = snapshot && (window.CICLOS_EVALUACION || []).find(c => c.id === snapshot.cicloId);
  const counts = NINE_BOX_LAYOUT.flat().map(cell => ({
    name: cell.name,
    n: people.filter(p => p.perf === cell.p && p.pot === cell.t).length,
  }));

  return (
    <div className="modal-overlay" onMouseDown={(e) => { if (e.target === e.currentTarget) onClose(); }}>
      <div className="modal" style={{ maxWidth: 600 }}>
        <div className="modal-head">
          <div>
            <div className="muted mono" style={{ fontSize: 11 }}>{snapshot?.id || '—'}</div>
            <div className="modal-title">Exportar Nine Box · Comité de Talento</div>
            <div className="modal-sub">Genera un PDF con el snapshot, distribución, movimientos y acciones recomendadas.</div>
          </div>
          <button className="icon-btn" onClick={onClose}>
            <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round"><path d="M18 6 6 18M6 6l12 12"/></svg>
          </button>
        </div>
        <div className="modal-body" style={{ padding: '20px 24px' }}>
          <div className="pd-card" style={{ marginBottom: 12 }}>
            <div className="muted-xs">Contenido del reporte</div>
            <div className="pf-nb-export-list">
              <div><IconCheck size={11} /> Identidad del ciclo · <span className="mono">{ciclo?.nombre || '—'}</span></div>
              <div><IconCheck size={11} /> Snapshot completo · {people.length} colaboradores</div>
              <div><IconCheck size={11} /> Recolección por cuadrante (9 celdas)</div>
              <div><IconCheck size={11} /> Acciones recomendadas por cuadrante</div>
              <div><IconCheck size={11} /> Aprobación: <b>{snapshot?.aprobadoPor}</b></div>
              <div><IconCheck size={11} /> Fecha snapshot: <span className="mono">{snapshot?.fecha}</span></div>
              <div className="muted"><IconClock size={11} /> Movimientos vs. snapshot anterior <i>(disponible en Fase 2)</i></div>
            </div>
          </div>
          <div className="pd-card">
            <div className="muted-xs" style={{ marginBottom: 6 }}>Recolección</div>
            <div className="pf-nb-export-grid">
              {counts.map((c, i) => (
                <div key={i} className="pf-nb-export-cell">
                  <div className="muted" style={{ fontSize: 10.5 }}>{c.name}</div>
                  <div style={{ fontWeight: 800, fontSize: 18 }}>{c.n}</div>
                </div>
              ))}
            </div>
          </div>
        </div>
        <div className="modal-foot">
          <button className="btn" onClick={onClose}>Cancelar</button>
          <button className="btn primary" onClick={() => { alert('PDF generado · descarga simulada en demo'); onClose(); }}>
            <IconExternal size={13} /> Descargar PDF
          </button>
        </div>
      </div>
    </div>
  );
};

// ─── Modal: ¿Cómo aparecen las personas en Nine Box? ─────

const NineBoxHowToModal = ({ onClose }) => {
  React.useEffect(() => {
    document.body.style.overflow = 'hidden';
    const onEsc = (e) => { if (e.key === 'Escape') onClose(); };
    window.addEventListener('keydown', onEsc);
    return () => { document.body.style.overflow = ''; window.removeEventListener('keydown', onEsc); };
  }, []);

  return (
    <div className="modal-overlay" onMouseDown={(e) => { if (e.target === e.currentTarget) onClose(); }}>
      <div className="modal" style={{ maxWidth: 640 }}>
        <div className="modal-head">
          <div>
            <div className="muted mono" style={{ fontSize: 11 }}>Nine Box · gobernanza</div>
            <div className="modal-title">¿Cómo aparecen las personas aquí?</div>
          </div>
          <button className="icon-btn" onClick={onClose}>
            <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round"><path d="M18 6 6 18M6 6l12 12"/></svg>
          </button>
        </div>

        <div className="modal-body" style={{ padding: '20px 24px', fontSize: 13, lineHeight: 1.6 }}>
          <div className="ic-warn-box" style={{ background: 'rgba(27,47,94,0.05)', border: '1px solid rgba(27,47,94,0.20)', color: 'var(--text)' }}>
            <IconShield size={14} />
            <div>
              <b>El Nine Box NO se llena manualmente.</b> Es un <b>output</b> automático del ciclo de evaluación.
              Esto preserva la integridad probatoria del snapshot ante auditoría ICONTEC, MinTrabajo o tutela.
            </div>
          </div>

          <h4 style={{ fontSize: 13.5, marginTop: 18, marginBottom: 6 }}>Flujo de generación</h4>
          <ol style={{ paddingLeft: 18, margin: 0 }}>
            <li>El ciclo se crea, configura y se lanza (<i>fase configurando → invitaciones</i>).</li>
            <li>Los evaluadores responden en su portal y firman (<i>en-progreso</i>).</li>
            <li>El sistema agrega scores con la regla anonimato N≥3 (<i>cerrando</i>).</li>
            <li>El comité de talento ajusta sesgos por área/jefe (<i>calibrando</i>).</li>
            <li>Al publicar, se calcula:
              <ul style={{ paddingLeft: 18, margin: '4px 0' }}>
                <li><b>Eje X · Desempeño</b> · score ponderado (60% competencias + 40% objetivos)</li>
                <li><b>Eje Y · Potencial</b> · evaluación de potencial del comité o 360°</li>
              </ul>
            </li>
            <li>Se crea un <b>snapshot inmutable</b> (ej. <code>NB-CY-2026-S1</code>).</li>
          </ol>

          <h4 style={{ fontSize: 13.5, marginTop: 18, marginBottom: 6 }}>¿No ves a alguien que esperabas?</h4>
          <table className="cd-matriz-table" style={{ marginTop: 4 }}>
            <thead><tr><th>Causa</th><th>Solución</th></tr></thead>
            <tbody>
              <tr>
                <td>No estaba en el ciclo cuando se cerró</td>
                <td>Agregarla al próximo ciclo desde <b>Pendientes & seguimiento</b></td>
              </tr>
              <tr>
                <td>El ciclo aún no se ha publicado</td>
                <td>Avanzar el ciclo en <b>Ciclos → click → Publicación</b></td>
              </tr>
              <tr>
                <td>Quieres recolocarla manualmente</td>
                <td>Solo en <b>fase calibración</b> · drag & drop con firma (Fase 2)</td>
              </tr>
              <tr>
                <td>Es nuevo/a · sin ciclo aún</td>
                <td>Aparecerá en su primer ciclo cerrado · período de prueba o semestral</td>
              </tr>
            </tbody>
          </table>

          <div style={{ background: 'var(--surface)', padding: 12, borderRadius: 8, marginTop: 14, fontSize: 12 }}>
            <b>Marco normativo:</b> ISO 9001:2015 cap. 9.1.3 (revisión por la dirección) ·
            Ley 2466/2025 (motivación de decisiones de talento) · ICONTEC NTC 6001.
          </div>
        </div>

        <div className="modal-foot">
          <button className="btn primary" onClick={onClose}>Entendido</button>
        </div>
      </div>
    </div>
  );
};

window.Performance = Performance;
