// Fundación de datos · Desempeño (Fase A)
// Fuente única para Competencias Conductuales, Ciclos, Evaluaciones, Objetivos,
// Incidentes Críticos, 1-on-1, Kudos, Pulse, PIP y Nine-Box.
//
// Convención: todos los mocks se cuelgan de window al final del archivo.
// Se carga DESPUÉS de data-providers.jsx (depende de CARGOS) y ANTES de
// performance.jsx / eval-360.jsx / employee-detail.jsx / portal.jsx.
//
// Marco normativo cubierto:
//   CST Art. 62 (causal justa por bajo rendimiento) — debido proceso documentado.
//   Sentencia C-593/2014 — debido proceso laboral, descargos, plazos.
//   Ley 1581/2012 + Dec. 1377 (Habeas Data) — anonimato N≥3, derecho a copia.
//   Ley 2466/2025 (Reforma Laboral) — motivación de decisiones de talento.
//   Ley 527/1999 + Dec. 2364/2012 — firma electrónica de evaluaciones y PIP.
//   Ley 1010/2006 — detección de patrones de acoso.
//   ISO 9001:2015 cap. 7.2 + 9.1.3 — competencia y revisión por la dirección.
//   ISO 30414 — indicadores de capital humano.

// ─── Marco normativo (referencia para Modo Auditoría) ─────

const MARCO_NORMATIVO_DESEMPENO = [
  { norma: 'CST Art. 62 num. 9-10', tema: 'Despido por bajo rendimiento — exige documentación y debido proceso',
    aplicaA: ['evaluacion-cerrada-bajo', 'PIP', 'incidente-critico-negativo'] },
  { norma: 'Sentencia C-593/2014',  tema: 'Debido proceso laboral — descargos y plazos en sanciones',
    aplicaA: ['PIP', 'incidente-critico-negativo'] },
  { norma: 'Ley 1581/2012 + Dec. 1377/2013', tema: 'Habeas Data — anonimato y derecho a copia',
    aplicaA: ['360', 'pulse', 'kudos'] },
  { norma: 'Ley 2466/2025 (Reforma Laboral)', tema: 'Motivación de decisiones de talento',
    aplicaA: ['9-box', 'calibracion', 'promocion'] },
  { norma: 'Ley 527/1999 + Dec. 2364/2012', tema: 'Firma electrónica — validez probatoria',
    aplicaA: ['evaluacion-cerrada', 'PIP', 'objetivo-aceptado'] },
  { norma: 'Ley 1010/2006',         tema: 'Acoso laboral — detección de patrones de calificación',
    aplicaA: ['evaluacion-cerrada'] },
  { norma: 'ISO 9001:2015 cap. 7.2 + 9.1.3', tema: 'Gestión de competencia + revisión por la dirección',
    aplicaA: ['ciclo', '9-box'] },
  { norma: 'ISO 30414',             tema: 'Indicadores de capital humano',
    aplicaA: ['reportes-talento'] },
];

// ─── Diccionario único de Competencias Conductuales ────────
// Tres familias:
//   cardinal   → toda la organización
//   funcional  → por área
//   de-nivel   → por nivel jerárquico (operativo / liderazgo / directivo)
//
// Cada competencia tiene:
//   - indicadoresConductuales[] : conductas observables que el evaluador califica
//   - diccionarioPorNivel{1..5} : descriptor textual de cada nivel
//
// Las competencias técnicas/normativas (CMP-01..12) viven en data-providers.jsx
// y NO se duplican aquí. La conexión bidireccional se modela en CRUCE_TECNICO_CONDUCTUAL.

const COMPETENCIAS_CONDUCTUALES = [
  // ─── Cardinales (toda la org) ──────
  {
    id: 'CDC-01', nombre: 'Compromiso con la calidad y la marca',
    familia: 'cardinal', categoria: 'cultura',
    descripcion: 'Trabaja con el estándar Atica como referencia · cuida el detalle del producto y la marca como propios.',
    indicadoresConductuales: [
      'Reporta no-conformidades aún cuando no es su responsabilidad directa',
      'Cumple los protocolos HACCP y BPM en cada lote sin necesidad de supervisión',
      'Sugiere mejoras concretas al producto o al proceso',
      'Asume con orgullo la representación de la marca dentro y fuera de la planta',
    ],
    diccionarioPorNivel: {
      1: 'No cumple los estándares mínimos de calidad. Requiere supervisión constante.',
      2: 'Cumple cuando se lo recuerdan o supervisan. Calidad inconsistente entre lotes/turnos.',
      3: 'Cumple los estándares de manera autónoma y consistente.',
      4: 'Supera el estándar · detecta y reporta no-conformidades de otros · cuida la marca.',
      5: 'Es referente de calidad en el área · forma a otros · propone mejoras adoptadas.',
    },
  },
  {
    id: 'CDC-02', nombre: 'Seguridad y autocuidado (conducta)',
    familia: 'cardinal', categoria: 'sst',
    descripcion: 'Cumple protocolos SST por convicción, no por obligación · cuida a sí mismo y a sus compañeros.',
    indicadoresConductuales: [
      'Usa EPP correctamente sin necesidad de recordatorio',
      'Reporta condiciones inseguras antes de que generen un evento',
      'Sigue procedimientos LOTO, alturas y espacios confinados sin atajos',
      'Apoya a compañeros nuevos en el cuidado SST',
    ],
    diccionarioPorNivel: {
      1: 'Salta procedimientos · ha tenido cuasi-accidentes · resiste el uso de EPP.',
      2: 'Cumple cuando es observado. Tendencia a "atajos" cuando hay presión de tiempo.',
      3: 'Cumple SST de forma sistemática y autónoma.',
      4: 'Modela la cultura SST · escala riesgos a tiempo · apoya brigada o COPASST.',
      5: 'Referente SST de la planta · activamente forma a otros · propone mejoras al programa.',
    },
  },
  {
    id: 'CDC-03', nombre: 'Trabajo en equipo',
    familia: 'cardinal', categoria: 'cultura',
    descripcion: 'Colabora activamente, comparte conocimiento y apoya a compañeros sin que se lo pidan.',
    indicadoresConductuales: [
      'Apoya el cambio de turno con entrega ordenada de información',
      'Comparte tips o conocimiento ganado con compañeros',
      'Resuelve discrepancias con respeto y enfoque en el problema, no en la persona',
      'Asume tareas adicionales cuando el equipo lo necesita',
    ],
    diccionarioPorNivel: {
      1: 'Trabaja aislado · entrega de turno deficiente · genera fricciones.',
      2: 'Colabora cuando se lo piden · poca iniciativa para apoyar.',
      3: 'Colabora bien · entrega información clara · convive sin fricciones.',
      4: 'Es solicitado por sus pares · apoya proactivamente · forma a nuevos.',
      5: 'Genera cohesión en el equipo · es elegido para liderar grupos / brigadas.',
    },
  },
  {
    id: 'CDC-04', nombre: 'Adaptabilidad y mejora continua',
    familia: 'cardinal', categoria: 'cultura',
    descripcion: 'Acepta cambios · aplica retroalimentación · propone mejoras al proceso.',
    indicadoresConductuales: [
      'Acepta cambios de turno, máquina o proceso sin resistencia',
      'Aplica retroalimentación recibida en evaluaciones previas',
      'Propone al menos una mejora documentada al año',
      'Aprende nuevas herramientas o sistemas en plazos razonables',
    ],
    diccionarioPorNivel: {
      1: 'Resiste cambios · ignora la retroalimentación · curva de aprendizaje muy lenta.',
      2: 'Se adapta con esfuerzo · necesita acompañamiento prolongado.',
      3: 'Se adapta a los cambios y aplica feedback recibido.',
      4: 'Propone mejoras · aprende rápido · referente de adaptabilidad.',
      5: 'Conduce iniciativas de cambio · forma a otros · sus mejoras escalan a la organización.',
    },
  },

  // ─── Funcionales (por área) ──────
  {
    id: 'CDF-01', nombre: 'Orientación al cliente interno',
    familia: 'funcional', categoria: 'servicio',
    aplicaAreas: ['Aprovechamiento', 'Recolección', 'Mantenimiento', 'Calidad', 'RRHH', 'Compras'],
    descripcion: 'Entrega lo que el siguiente eslabón necesita en tiempo, forma y calidad.',
    indicadoresConductuales: [
      'Entiende quién es su "cliente interno" y qué necesita',
      'Cumple plazos pactados con áreas vecinas',
      'Comunica con antelación cuando hay un retraso o desvío',
      'Recibe retroalimentación del cliente interno y ajusta',
    ],
    diccionarioPorNivel: {
      1: 'Entrega trabajo incompleto, tarde o sin avisar.', 2: 'Cumple si se lo recuerdan.',
      3: 'Cumple plazos y calidad esperados.',
      4: 'Anticipa necesidades · ajusta proactivamente al cliente interno.',
      5: 'Es buscado por otras áreas · genera relaciones de confianza estables.',
    },
  },
  {
    id: 'CDF-02', nombre: 'Conocimiento técnico de la operación',
    familia: 'funcional', categoria: 'tecnico',
    aplicaAreas: ['Operaciones', 'Mantenimiento', 'Calidad', 'Logística'],
    descripcion: 'Domina los procedimientos, equipos, parámetros y estándares de su área técnica.',
    indicadoresConductuales: [
      'Conoce los rangos operativos críticos sin consultar manuales',
      'Identifica desviaciones del proceso antes de que escalen',
      'Resuelve incidencias técnicas de su nivel sin escalar',
      'Forma a otros en aspectos técnicos del cargo',
    ],
    diccionarioPorNivel: {
      1: 'Conoce solo lo básico · genera errores frecuentes.',
      2: 'Cumple lo rutinario · escala lo no-rutinario sin intentar resolver.',
      3: 'Domina su cargo · resuelve incidencias estándar.',
      4: 'Resuelve casos no estándar · es referente técnico del turno.',
      5: 'Referente técnico de planta · forma a otros · participa en mejora de procesos.',
    },
  },
  {
    id: 'CDF-03', nombre: 'Atención al detalle y cumplimiento normativo',
    familia: 'funcional', categoria: 'compliance',
    aplicaAreas: ['Calidad', 'RRHH', 'Administración', 'Compras', 'Operaciones'],
    descripcion: 'Trabaja con rigor documental · entiende y aplica la normativa pertinente al cargo.',
    indicadoresConductuales: [
      'Documenta sus acciones en los formatos requeridos sin omisiones',
      'Identifica brechas de cumplimiento antes de que las detecte una auditoría',
      'Mantiene actualizado su conocimiento normativo del área',
      'Es elegido para soportar auditorías ICONTEC, INVIMA o MinTrabajo',
    ],
    diccionarioPorNivel: {
      1: 'Errores frecuentes en documentación · brechas detectadas en auditoría.',
      2: 'Documenta cuando se le insiste · conocimiento normativo desactualizado.',
      3: 'Documenta correctamente y conoce la normativa de su rol.',
      4: 'Anticipa requisitos · es soporte de auditorías · forma a pares.',
      5: 'Referente de cumplimiento · su trabajo pasa auditoría sin observaciones.',
    },
  },
  {
    id: 'CDF-04', nombre: 'Negociación y abastecimiento',
    familia: 'funcional', categoria: 'comercial',
    aplicaAreas: ['Compras', 'Logística', 'Administración'],
    descripcion: 'Genera relaciones gana-gana con proveedores · obtiene mejores condiciones sin sacrificar calidad.',
    indicadoresConductuales: [
      'Logra términos comerciales mejores que el promedio del mercado',
      'Diversifica la base de proveedores para reducir riesgo de desabasto',
      'Construye relaciones de largo plazo con proveedores estratégicos',
      'Cumple los procesos de compras y SAGRILAFT',
    ],
    diccionarioPorNivel: {
      1: 'Compras tardías · términos peores que el mercado · proveedores únicos.',
      2: 'Cumple lo básico · poca capacidad de negociación.',
      3: 'Cumple con condiciones de mercado · gestión sin incidencias.',
      4: 'Logra mejoras significativas · diversifica proveedores · documenta negociaciones.',
      5: 'Genera ahorros estructurales · proveedores destacan la relación · referente del proceso.',
    },
  },

  // ─── De nivel (por jerarquía) ──────
  {
    id: 'CDN-01', nombre: 'Liderazgo situacional',
    familia: 'de-nivel', categoria: 'liderazgo',
    aplicaNiveles: ['liderazgo', 'directivo'],
    descripcion: 'Adapta su estilo de liderazgo a la madurez del colaborador y a la situación.',
    indicadoresConductuales: [
      'Identifica cuándo dar instrucción precisa vs. cuándo delegar',
      'Confía y delega gradualmente conforme su gente crece',
      'Sostiene conversaciones difíciles con respeto y firmeza',
      'Genera espacios para el desarrollo del equipo',
    ],
    diccionarioPorNivel: {
      1: 'Microgestiona o abandona · no diferencia situaciones.',
      2: 'Estilo único e inflexible · resultados desiguales en el equipo.',
      3: 'Adapta su estilo al colaborador · resultados consistentes.',
      4: 'Equipo crece bajo su liderazgo · personas reportan aprendizaje.',
      5: 'Forma futuros líderes · su gente asciende · referente de cultura.',
    },
  },
  {
    id: 'CDN-02', nombre: 'Comunicación efectiva',
    familia: 'de-nivel', categoria: 'liderazgo',
    aplicaNiveles: ['liderazgo', 'directivo'],
    descripcion: 'Transmite información de forma clara, oportuna y respetuosa · escucha activamente.',
    indicadoresConductuales: [
      'Las metas y prioridades del equipo son entendidas por todos',
      'Da retroalimentación al menos mensualmente',
      'Maneja conflictos con discreción y eficacia',
      'Comunica a tiempo las decisiones que afectan al equipo',
    ],
    diccionarioPorNivel: {
      1: 'Equipo no sabe qué se espera · conflictos crónicos.',
      2: 'Comunica solo lo urgente · feedback ausente o esporádico.',
      3: 'Comunicación clara y consistente.',
      4: 'Genera diálogo bidireccional · feedback recurrente y útil.',
      5: 'Referente de comunicación · forma a otros líderes.',
    },
  },
  {
    id: 'CDN-03', nombre: 'Toma de decisiones',
    familia: 'de-nivel', categoria: 'liderazgo',
    aplicaNiveles: ['liderazgo', 'directivo'],
    descripcion: 'Decide con información, oportunidad y claridad de criterios · asume responsabilidad.',
    indicadoresConductuales: [
      'Decide con información suficiente y en plazo razonable',
      'Documenta las decisiones operativas para no perder trazabilidad',
      'Asume las consecuencias de sus decisiones · no las traslada',
      'Distingue lo reversible de lo irreversible y ajusta su rigor',
    ],
    diccionarioPorNivel: {
      1: 'Posterga · evita decidir · escala todo arriba.',
      2: 'Decide pero sin trazabilidad · errores recurrentes.',
      3: 'Decide en plazo y con criterio · documenta lo importante.',
      4: 'Buenas decisiones bajo presión · equipo confía en su criterio.',
      5: 'Referente del juicio en la organización · sus decisiones son adoptadas.',
    },
  },
  {
    id: 'CDN-04', nombre: 'Visión estratégica',
    familia: 'de-nivel', categoria: 'liderazgo',
    aplicaNiveles: ['directivo'],
    descripcion: 'Conecta el día a día con los objetivos del negocio · anticipa cambios del entorno.',
    indicadoresConductuales: [
      'Cascadea los objetivos del negocio a su equipo de forma comprensible',
      'Anticipa cambios del entorno (regulación, mercado, tecnología) y prepara al equipo',
      'Prioriza con claridad · dice "no" a iniciativas no estratégicas',
      'Mide y comunica el progreso hacia los objetivos del negocio',
    ],
    diccionarioPorNivel: {
      1: 'Centrado en lo operativo · sin línea con objetivos del negocio.',
      2: 'Conoce los objetivos pero no los comunica · desconexión con equipo.',
      3: 'Cascadea objetivos · equipo entiende su contribución.',
      4: 'Anticipa cambios · prepara al equipo · prioriza con claridad.',
      5: 'Su visión orienta al negocio · referente del comité directivo.',
    },
  },
];

// ─── Cruce técnico ↔ conductual ────────────────────────────
// Cuando una competencia conductual baja, sugiere capacitaciones técnicas
// del catálogo de Capacitaciones (data-providers.jsx).

const CRUCE_TECNICO_CONDUCTUAL = [
  { conductualId: 'CDC-02', tecnicasIds: ['CMP-01', 'CMP-04', 'CMP-05', 'CMP-11'], razon: 'Refuerzo SST general y específico' },
  { conductualId: 'CDF-02', tecnicasIds: ['CMP-01', 'CMP-07'], razon: 'Refuerzo técnico operativo' },
  { conductualId: 'CDF-03', tecnicasIds: ['CMP-02', 'CMP-03', 'CMP-10'], razon: 'Refuerzo cumplimiento BPM/INVIMA/Habeas Data' },
  { conductualId: 'CDN-01', tecnicasIds: ['CMP-08'], razon: 'Diplomado Liderazgo EAFIT' },
  { conductualId: 'CDN-02', tecnicasIds: ['CMP-08'], razon: 'Diplomado Liderazgo EAFIT' },
];

// ─── Niveles esperados por cargo ─────────────────────────
// Por cada par (cargoId, competenciaConductualId), nivel esperado 1-5.
// Si una competencia no está listada para un cargo, no aplica.

const NIVELES_ESPERADOS_CARGO = [
  // CGO-001 Operario de Clasificación
  { cargoId: 'CGO-001', compId: 'CDC-01', nivelEsperado: 4, peso: 0.20 },
  { cargoId: 'CGO-001', compId: 'CDC-02', nivelEsperado: 4, peso: 0.25 },
  { cargoId: 'CGO-001', compId: 'CDC-03', nivelEsperado: 3, peso: 0.15 },
  { cargoId: 'CGO-001', compId: 'CDC-04', nivelEsperado: 3, peso: 0.10 },
  { cargoId: 'CGO-001', compId: 'CDF-02', nivelEsperado: 4, peso: 0.30 },
  // CGO-002 Operaria de Planta
  { cargoId: 'CGO-002', compId: 'CDC-01', nivelEsperado: 4, peso: 0.25 },
  { cargoId: 'CGO-002', compId: 'CDC-02', nivelEsperado: 4, peso: 0.25 },
  { cargoId: 'CGO-002', compId: 'CDC-03', nivelEsperado: 3, peso: 0.15 },
  { cargoId: 'CGO-002', compId: 'CDC-04', nivelEsperado: 3, peso: 0.10 },
  { cargoId: 'CGO-002', compId: 'CDF-02', nivelEsperado: 3, peso: 0.25 },
  // CGO-003 Op. Aprovechamiento
  { cargoId: 'CGO-003', compId: 'CDC-01', nivelEsperado: 4, peso: 0.25 },
  { cargoId: 'CGO-003', compId: 'CDC-02', nivelEsperado: 3, peso: 0.20 },
  { cargoId: 'CGO-003', compId: 'CDC-03', nivelEsperado: 4, peso: 0.20 },
  { cargoId: 'CGO-003', compId: 'CDC-04', nivelEsperado: 3, peso: 0.10 },
  { cargoId: 'CGO-003', compId: 'CDF-01', nivelEsperado: 3, peso: 0.25 },
  // CGO-004 Líder de Aprovechamiento
  { cargoId: 'CGO-004', compId: 'CDC-01', nivelEsperado: 4, peso: 0.10 },
  { cargoId: 'CGO-004', compId: 'CDC-02', nivelEsperado: 4, peso: 0.10 },
  { cargoId: 'CGO-004', compId: 'CDC-03', nivelEsperado: 4, peso: 0.10 },
  { cargoId: 'CGO-004', compId: 'CDC-04', nivelEsperado: 3, peso: 0.10 },
  { cargoId: 'CGO-004', compId: 'CDF-01', nivelEsperado: 4, peso: 0.10 },
  { cargoId: 'CGO-004', compId: 'CDN-01', nivelEsperado: 4, peso: 0.20 },
  { cargoId: 'CGO-004', compId: 'CDN-02', nivelEsperado: 4, peso: 0.15 },
  { cargoId: 'CGO-004', compId: 'CDN-03', nivelEsperado: 3, peso: 0.15 },
  // CGO-005 Aux Calidad
  { cargoId: 'CGO-005', compId: 'CDC-01', nivelEsperado: 5, peso: 0.20 },
  { cargoId: 'CGO-005', compId: 'CDC-02', nivelEsperado: 4, peso: 0.15 },
  { cargoId: 'CGO-005', compId: 'CDC-03', nivelEsperado: 3, peso: 0.10 },
  { cargoId: 'CGO-005', compId: 'CDC-04', nivelEsperado: 3, peso: 0.10 },
  { cargoId: 'CGO-005', compId: 'CDF-02', nivelEsperado: 4, peso: 0.15 },
  { cargoId: 'CGO-005', compId: 'CDF-03', nivelEsperado: 5, peso: 0.30 },
  // CGO-006 Téc Mantenimiento
  { cargoId: 'CGO-006', compId: 'CDC-01', nivelEsperado: 4, peso: 0.10 },
  { cargoId: 'CGO-006', compId: 'CDC-02', nivelEsperado: 5, peso: 0.30 },
  { cargoId: 'CGO-006', compId: 'CDC-03', nivelEsperado: 3, peso: 0.10 },
  { cargoId: 'CGO-006', compId: 'CDC-04', nivelEsperado: 4, peso: 0.10 },
  { cargoId: 'CGO-006', compId: 'CDF-01', nivelEsperado: 3, peso: 0.10 },
  { cargoId: 'CGO-006', compId: 'CDF-02', nivelEsperado: 5, peso: 0.30 },
  // CGO-007 Coord Compras
  { cargoId: 'CGO-007', compId: 'CDC-01', nivelEsperado: 4, peso: 0.10 },
  { cargoId: 'CGO-007', compId: 'CDC-03', nivelEsperado: 4, peso: 0.10 },
  { cargoId: 'CGO-007', compId: 'CDC-04', nivelEsperado: 4, peso: 0.10 },
  { cargoId: 'CGO-007', compId: 'CDF-03', nivelEsperado: 4, peso: 0.15 },
  { cargoId: 'CGO-007', compId: 'CDF-04', nivelEsperado: 4, peso: 0.20 },
  { cargoId: 'CGO-007', compId: 'CDN-01', nivelEsperado: 3, peso: 0.10 },
  { cargoId: 'CGO-007', compId: 'CDN-02', nivelEsperado: 4, peso: 0.10 },
  { cargoId: 'CGO-007', compId: 'CDN-03', nivelEsperado: 4, peso: 0.15 },
  // CGO-008 Jefe RRHH
  { cargoId: 'CGO-008', compId: 'CDC-01', nivelEsperado: 5, peso: 0.05 },
  { cargoId: 'CGO-008', compId: 'CDC-03', nivelEsperado: 5, peso: 0.10 },
  { cargoId: 'CGO-008', compId: 'CDC-04', nivelEsperado: 4, peso: 0.10 },
  { cargoId: 'CGO-008', compId: 'CDF-03', nivelEsperado: 5, peso: 0.15 },
  { cargoId: 'CGO-008', compId: 'CDN-01', nivelEsperado: 5, peso: 0.15 },
  { cargoId: 'CGO-008', compId: 'CDN-02', nivelEsperado: 5, peso: 0.15 },
  { cargoId: 'CGO-008', compId: 'CDN-03', nivelEsperado: 5, peso: 0.15 },
  { cargoId: 'CGO-008', compId: 'CDN-04', nivelEsperado: 4, peso: 0.15 },
  // CGO-009 Conductor
  { cargoId: 'CGO-009', compId: 'CDC-01', nivelEsperado: 4, peso: 0.20 },
  { cargoId: 'CGO-009', compId: 'CDC-02', nivelEsperado: 5, peso: 0.30 },
  { cargoId: 'CGO-009', compId: 'CDC-03', nivelEsperado: 3, peso: 0.10 },
  { cargoId: 'CGO-009', compId: 'CDC-04', nivelEsperado: 3, peso: 0.10 },
  { cargoId: 'CGO-009', compId: 'CDF-01', nivelEsperado: 4, peso: 0.30 },
];

// ─── Plantillas de escalas (gráficas) ────────────────────
// Conjuntos de factores reutilizables por familia de cargo.
// Cada plantilla aplica una escala 1-5 a una lista corta de factores (5-7).

const ESCALAS_PLANTILLAS = [
  {
    id: 'ESC-001', nombre: 'Operario de planta · escala simple',
    aplicaCargosIds: ['CGO-001', 'CGO-002', 'CGO-003'],
    factores: [
      { id: 'f1', nombre: 'Puntualidad y asistencia',     descriptor: 'Llega a tiempo, cumple turnos asignados, comunica con antelación las ausencias.' },
      { id: 'f2', nombre: 'Calidad del trabajo',           descriptor: 'Producto cumple estándares · errores dentro de la tolerancia.' },
      { id: 'f3', nombre: 'Volumen / productividad',       descriptor: 'Cumple las metas de operaciones del turno.' },
      { id: 'f4', nombre: 'Cuidado de equipos y EPP',      descriptor: 'Usa correctamente equipos, herramientas y EPP · reporta deterioro.' },
      { id: 'f5', nombre: 'Disposición y actitud',         descriptor: 'Acepta indicaciones · trato respetuoso con compañeros y superiores.' },
    ],
  },
  {
    id: 'ESC-002', nombre: 'Cargo técnico/auxiliar',
    aplicaCargosIds: ['CGO-005', 'CGO-006'],
    factores: [
      { id: 'f1', nombre: 'Dominio técnico del cargo',     descriptor: 'Conoce procedimientos, equipos y parámetros críticos.' },
      { id: 'f2', nombre: 'Resolución de problemas',       descriptor: 'Diagnostica e interviene incidencias de su nivel sin escalar.' },
      { id: 'f3', nombre: 'Documentación y registros',     descriptor: 'Documenta intervenciones y mantiene trazabilidad.' },
      { id: 'f4', nombre: 'Cumplimiento normativo',        descriptor: 'Aplica normativa SST/INVIMA/ICONTEC pertinente.' },
      { id: 'f5', nombre: 'Comunicación con áreas',        descriptor: 'Coordina con áreas vecinas y reporta desviaciones a tiempo.' },
    ],
  },
  {
    id: 'ESC-003', nombre: 'Cargo de liderazgo',
    aplicaCargosIds: ['CGO-004', 'CGO-007', 'CGO-008'],
    factores: [
      { id: 'f1', nombre: 'Resultados del equipo',         descriptor: 'El equipo cumple metas asignadas en cantidad, calidad y oportunidad.' },
      { id: 'f2', nombre: 'Desarrollo del equipo',         descriptor: 'Identifica brechas · facilita formación · genera planes de carrera.' },
      { id: 'f3', nombre: 'Comunicación y feedback',       descriptor: 'Da retroalimentación oportuna · maneja conversaciones difíciles.' },
      { id: 'f4', nombre: 'Toma de decisiones',            descriptor: 'Decide con criterio · asume consecuencias · documenta.' },
      { id: 'f5', nombre: 'Cultura y SST en el equipo',    descriptor: 'Modela los valores · cero tolerancia a desvíos críticos.' },
      { id: 'f6', nombre: 'Visión y prioridades',          descriptor: 'Conecta el día a día con la estrategia del área.' },
    ],
  },
];

// ─── Objetivos en cascada (MBO) ──────────────────────────
// Cascadeo: organizacionales → área → cargo → individuales.
// Cada nivel tiene parentId hacia el de arriba (excepto org).
// Los individuales pueden tener evidencias y check-ins.

const OBJETIVOS_CASCADE = [
  // ── Nivel organizacional ──
  { id: 'OBJ-ORG-2026-01', nivel: 'org',       parentId: null, owner: 'Dirección General',
    descripcion: 'Cerrar 2026 con 28% de crecimiento en ventas vs. 2025',
    metrica: 'Ventas anuales', target: 28, unidad: '%', peso: 0.40,
    periodo: '01/01/2026 → 31/12/2026' },
  { id: 'OBJ-ORG-2026-02', nivel: 'org',       parentId: null, owner: 'Dirección General',
    descripcion: 'Mantener cero accidentes laborales graves o fatales',
    metrica: 'AT graves/fatales', target: 0, unidad: 'eventos', peso: 0.30,
    periodo: '01/01/2026 → 31/12/2026' },
  { id: 'OBJ-ORG-2026-03', nivel: 'org',       parentId: null, owner: 'Dirección General',
    descripcion: 'Alcanzar certificación ICONTEC ISO 9001 sin no-conformidades mayores',
    metrica: 'NC mayores en auditoría externa', target: 0, unidad: 'NC', peso: 0.30,
    periodo: '01/01/2026 → 31/12/2026' },
  // ── Nivel área (Operaciones) ──
  { id: 'OBJ-PROD-2026-01', nivel: 'area',     parentId: 'OBJ-ORG-2026-01', area: 'Operaciones',
    owner: 'Jefe Operaciones',
    descripcion: 'Aumentar operaciones promedio mensual a 540 t (vs. 470 t en 2025)',
    metrica: 'Toneladas producidas/mes', target: 540, unidad: 't', peso: 0.40,
    periodo: '01/01/2026 → 31/12/2026' },
  { id: 'OBJ-PROD-2026-02', nivel: 'area',     parentId: 'OBJ-ORG-2026-01', area: 'Operaciones',
    owner: 'Jefe Operaciones',
    descripcion: 'Reducir merma de clasificación a < 2.3% (vs. 2.8% en 2025)',
    metrica: 'Merma de clasificación', target: 2.3, unidad: '%', peso: 0.35,
    periodo: '01/01/2026 → 31/12/2026' },
  { id: 'OBJ-PROD-2026-03', nivel: 'area',     parentId: 'OBJ-ORG-2026-02', area: 'Operaciones',
    owner: 'Jefe Operaciones',
    descripcion: 'Cero accidentes laborales en línea de clasificación',
    metrica: 'AT en clasificación', target: 0, unidad: 'eventos', peso: 0.25,
    periodo: '01/01/2026 → 31/12/2026' },
  // ── Nivel individual (Andrés Mejía · Op Clasificación) ──
  { id: 'OBJ-IND-E0247-01', nivel: 'individuo', parentId: 'OBJ-PROD-2026-01',
    empId: 'E0247', cargoId: 'CGO-001', owner: 'Andrés Felipe Mejía',
    descripcion: 'Cumplir lote diario · 240 kg/turno asignado',
    metrica: 'Ton clasificadas/turno', target: 240, unidad: 'kg', peso: 0.30,
    periodo: '01/01/2026 → 30/06/2026', logroPct: 96, evidencias: 1,
    estado: 'aceptado-firmado', firmaColaborador: { nombre: 'Andrés Felipe Mejía', fecha: '14/01/2026', hash: 'sha-firmaev-247-01' } },
  { id: 'OBJ-IND-E0247-02', nivel: 'individuo', parentId: 'OBJ-PROD-2026-02',
    empId: 'E0247', cargoId: 'CGO-001', owner: 'Andrés Felipe Mejía',
    descripcion: 'Reducir merma personal a < 2.5% (atribuible al operador)',
    metrica: 'Merma atribuible', target: 2.5, unidad: '%', peso: 0.25,
    periodo: '01/01/2026 → 30/06/2026', logroPct: 88, evidencias: 1,
    estado: 'aceptado-firmado', firmaColaborador: { nombre: 'Andrés Felipe Mejía', fecha: '14/01/2026', hash: 'sha-firmaev-247-02' } },
  { id: 'OBJ-IND-E0247-03', nivel: 'individuo', parentId: 'OBJ-PROD-2026-03',
    empId: 'E0247', cargoId: 'CGO-001', owner: 'Andrés Felipe Mejía',
    descripcion: 'Cero accidentes laborales o cuasi-accidentes reportados',
    metrica: 'AT/CA reportados', target: 0, unidad: 'eventos', peso: 0.25,
    periodo: '01/01/2026 → 30/06/2026', logroPct: 100, evidencias: 0,
    estado: 'aceptado-firmado', firmaColaborador: { nombre: 'Andrés Felipe Mejía', fecha: '14/01/2026', hash: 'sha-firmaev-247-03' } },
  { id: 'OBJ-IND-E0247-04', nivel: 'individuo', parentId: 'OBJ-ORG-2026-03',
    empId: 'E0247', cargoId: 'CGO-001', owner: 'Andrés Felipe Mejía',
    descripcion: 'Completar plan de capacitación obligatorio del cargo',
    metrica: 'Cursos cargo cumplidos', target: 6, unidad: 'cursos', peso: 0.20,
    periodo: '01/01/2026 → 30/06/2026', logroPct: 67, evidencias: 2,
    estado: 'aceptado-firmado', firmaColaborador: { nombre: 'Andrés Felipe Mejía', fecha: '14/01/2026', hash: 'sha-firmaev-247-04' } },
  // ── Nivel individual (Luis Miguel Marín · Líder Aprovechamiento) ──
  { id: 'OBJ-IND-E0067-01', nivel: 'individuo', parentId: 'OBJ-ORG-2026-01',
    empId: 'E0067', cargoId: 'CGO-004', owner: 'Luis Miguel Marín',
    descripcion: 'Aumentar throughput de aprovechamiento a 18.500 unid/turno (vs. 16.800 en 2025)',
    metrica: 'Unid empacadas/turno', target: 18500, unidad: 'unid', peso: 0.30,
    periodo: '01/01/2026 → 30/06/2026', logroPct: 78, evidencias: 2,
    estado: 'aceptado-firmado', firmaColaborador: { nombre: 'Luis Miguel Marín', fecha: '12/01/2026', hash: 'sha-firmaev-067-01' } },
  { id: 'OBJ-IND-E0067-02', nivel: 'individuo', parentId: 'OBJ-ORG-2026-02',
    empId: 'E0067', cargoId: 'CGO-004', owner: 'Luis Miguel Marín',
    descripcion: 'Cero accidentes laborales en su línea',
    metrica: 'AT en línea Aprovechamiento', target: 0, unidad: 'eventos', peso: 0.20,
    periodo: '01/01/2026 → 30/06/2026', logroPct: 100, evidencias: 0,
    estado: 'aceptado-firmado', firmaColaborador: { nombre: 'Luis Miguel Marín', fecha: '12/01/2026', hash: 'sha-firmaev-067-02' } },
  { id: 'OBJ-IND-E0067-03', nivel: 'individuo', parentId: null,
    empId: 'E0067', cargoId: 'CGO-004', owner: 'Luis Miguel Marín',
    descripcion: 'Formar a 2 operarios senior como respaldo del cargo de líder',
    metrica: 'Personas formadas', target: 2, unidad: 'personas', peso: 0.25,
    periodo: '01/01/2026 → 30/06/2026', logroPct: 50, evidencias: 1,
    estado: 'aceptado-firmado', firmaColaborador: { nombre: 'Luis Miguel Marín', fecha: '12/01/2026', hash: 'sha-firmaev-067-03' } },
  { id: 'OBJ-IND-E0067-04', nivel: 'individuo', parentId: 'OBJ-ORG-2026-03',
    empId: 'E0067', cargoId: 'CGO-004', owner: 'Luis Miguel Marín',
    descripcion: 'Mantener 100% de cumplimiento ICONTEC en su línea',
    metrica: 'Cumplimiento auditoría interna', target: 100, unidad: '%', peso: 0.25,
    periodo: '01/01/2026 → 30/06/2026', logroPct: 92, evidencias: 1,
    estado: 'aceptado-firmado', firmaColaborador: { nombre: 'Luis Miguel Marín', fecha: '12/01/2026', hash: 'sha-firmaev-067-04' } },
];

// ─── Check-ins de objetivos (histórico de avances) ─────────

const OBJETIVO_CHECKINS = [
  { objId: 'OBJ-IND-E0247-01', fecha: '15/02/2026', logroPct: 60, nota: 'Avance esperado · curva normal de aprendizaje en máquina nueva.', evidenciaUrl: '#mock-checkin-feb.pdf' },
  { objId: 'OBJ-IND-E0247-01', fecha: '15/03/2026', logroPct: 78, nota: 'Mejor manejo de la curva de clasificación · subió 18 pts.',                evidenciaUrl: '#mock-checkin-mar.pdf' },
  { objId: 'OBJ-IND-E0247-01', fecha: '15/04/2026', logroPct: 96, nota: 'Cumple meta de manera consistente · seguir así.',                  evidenciaUrl: '#mock-checkin-abr.pdf' },
  { objId: 'OBJ-IND-E0067-01', fecha: '20/02/2026', logroPct: 50, nota: 'Inicio · línea con paradas no programadas por mantenimiento.',     evidenciaUrl: null },
  { objId: 'OBJ-IND-E0067-01', fecha: '20/03/2026', logroPct: 65, nota: 'Recuperación parcial · operación más estable.',                    evidenciaUrl: null },
  { objId: 'OBJ-IND-E0067-01', fecha: '20/04/2026', logroPct: 78, nota: 'Cerca del target · ajustes finales en cambio de turno.',           evidenciaUrl: '#mock-checkin-067-abr.pdf' },
];

// ─── Incidentes Críticos (continuo · NO se borran · solo negativos) ─
// Bitácora inmutable de eventos problemáticos. Severidad: bajo | medio | alto.
// Sustento del debido proceso · CST Art. 62 · Ley 1010/2006 · descargos en 5 días hábiles.
// Los eventos positivos se modelan como Reconocimientos (window.KUDOS · ver abajo).

const INCIDENTES_CRITICOS = [
  { id: 'IC-2026-003', empId: 'E0247', autorId: 'E0067', autorNombre: 'Luis Miguel Marín',
    fecha: '21/03/2026', severidad: 'medio',
    competenciaRelacionadaId: 'CDC-04',
    descripcion: 'Entrega de turno incompleta · no informó parámetro modificado en curva de clasificación · turno siguiente generó merma adicional de 12 kg.',
    evidenciaUrl: '#mock-ic-003.pdf', visibleAlEvaluado: true, descargosNotificados: true,
    plazoDescargosVence: '26/03/2026', estadoDescargos: 'recibidos-aceptados',
    descargosTexto: 'Operador reconoce el descuido · acuerdo de capacitación adicional en protocolo de cambio de turno.' },
];

// ─── Ciclos de Evaluación (refactorizado) ──────────────────
// Cada ciclo combina N metodologías. Estados expandidos:
//   configurando | invitaciones-enviadas | en-progreso | cerrando | calibrando | publicado | archivado
// audiencia: { tipo: 'cargo'|'area'|'individual'|'liderazgos'|'todos', criterio }

const CICLOS_EVALUACION = [
  {
    id: 'CY-2026-S1', nombre: 'Evaluación Semestral S1 2026',
    metodologias: ['mbo', 'competencias', '180', 'incidentes'],
    audiencia: { tipo: 'todos' },
    periodo: { inicio: '01/01/2026', fin: '30/06/2026' },
    apertura: '03/01/2026', cierre: '15/07/2026',
    estado: 'en-progreso', completitudPct: 64,
    invitados: 824, completados: 528, evaluadores: 47,
    responsable: 'Carolina Restrepo Salazar',
    pondCompetencias: 0.60, pondObjetivos: 0.40,
    requireFirmaElectronica: true, anonimatoMinN: 3,
  },
  {
    id: 'CY-2025-Q4-360', nombre: 'Evaluación 360° Liderazgo · Q4 2025',
    metodologias: ['360', 'competencias'],
    audiencia: { tipo: 'liderazgos', criterio: { niveles: ['liderazgo', 'directivo'] } },
    periodo: { inicio: '01/10/2025', fin: '31/12/2025' },
    apertura: '01/12/2025', cierre: '15/01/2026',
    estado: 'publicado', completitudPct: 100,
    invitados: 18, completados: 18, evaluadores: 22,
    responsable: 'Carolina Restrepo Salazar',
    pondCompetencias: 1.0, pondObjetivos: 0.0,
    requireFirmaElectronica: true, anonimatoMinN: 3,
  },
  {
    id: 'CY-CONT-90', nombre: 'Auto-evaluación 90° · período de prueba',
    metodologias: ['90', 'escalas'],
    audiencia: { tipo: 'individual', criterio: { trigger: 'periodo-prueba-dia-60' } },
    periodo: { inicio: '01/01/2026', fin: '31/12/2026' },
    apertura: 'continuo', cierre: 'continuo',
    estado: 'en-progreso', completitudPct: 38,
    invitados: 12, completados: 5, evaluadores: 12,
    responsable: 'Patricia Gómez',
    pondCompetencias: 1.0, pondObjetivos: 0.0,
    requireFirmaElectronica: true, anonimatoMinN: 3,
  },
  {
    id: 'CY-2026-S2', nombre: 'Evaluación Semestral S2 2026',
    metodologias: ['mbo', 'competencias', '180', 'incidentes'],
    audiencia: { tipo: 'todos' },
    periodo: { inicio: '01/07/2026', fin: '31/12/2026' },
    apertura: '01/07/2026', cierre: '15/01/2027',
    estado: 'configurando', completitudPct: 0,
    invitados: 824, completados: 0, evaluadores: 0,
    responsable: 'Carolina Restrepo Salazar',
    pondCompetencias: 0.60, pondObjetivos: 0.40,
    requireFirmaElectronica: true, anonimatoMinN: 3,
  },
];

// ─── Pulse Surveys (opt-in del tenant · simulado activo) ───

const PULSE_SURVEYS = [
  { id: 'PS-2026-04', mes: 'Abril 2026', estado: 'cerrado',
    n: 612, total: 824, responsePct: 74,
    eNPS: 38, // -100 a +100
    preguntas: [
      { id: 'q1', texto: '¿Recomendarías Atica como un buen lugar para trabajar?', tipo: 'eNPS', resultado: 38 },
      { id: 'q2', texto: '¿Tienes claridad sobre lo que se espera de ti esta semana?', tipo: 'liker-5', resultado: 4.1 },
      { id: 'q3', texto: '¿Te sientes seguro/a (físicamente) en tu lugar de trabajo?', tipo: 'liker-5', resultado: 4.6 },
    ] },
  { id: 'PS-2026-05', mes: 'Mayo 2026', estado: 'abierto',
    n: 198, total: 824, responsePct: 24,
    eNPS: null,
    preguntas: [
      { id: 'q1', texto: '¿Recomendarías Atica como un buen lugar para trabajar?', tipo: 'eNPS', resultado: null },
      { id: 'q2', texto: '¿Recibiste retroalimentación útil de tu jefe en los últimos 30 días?', tipo: 'liker-5', resultado: null },
      { id: 'q3', texto: '¿Tienes los recursos que necesitas para hacer bien tu trabajo?', tipo: 'liker-5', resultado: null },
    ] },
];

// ─── 1-on-1 (check-ins jefe-colaborador) ───────────────────

const CHECKINS_1ON1 = [
  { id: '1o1-2026-04-E0247', empId: 'E0247', jefeId: 'E0067',
    fecha: '12/04/2026', duracionMin: 30, estado: 'realizado',
    agenda: ['Avance objetivos S1', 'Plan de formación pendiente', 'Bienestar / equipo'],
    notasCompartidas: 'Andrés cumple bien sus metas. Falta cerrar 2 cursos del plan. Pidió cambio a turno mañana — se evaluará en mayo.',
    acuerdos: ['Cerrar CMP-04 antes del 30/04', 'Revisión de turno · semana del 06/05'],
    proximaFecha: '14/05/2026', firmaColaborador: { fecha: '12/04/2026', hash: 'sha-1o1-247-04' } },
  { id: '1o1-2026-03-E0247', empId: 'E0247', jefeId: 'E0067',
    fecha: '15/03/2026', duracionMin: 30, estado: 'realizado',
    agenda: ['Cambio de turno · entrega', 'Ajuste de curva de clasificación', 'Carrera'],
    notasCompartidas: 'Conversación sobre el incidente del 21/03 (descargos aceptados). Acuerdo de refuerzo en protocolo.',
    acuerdos: ['Capacitación adicional en cambio de turno · semana del 25/03', 'Mentoría 1h con operador senior'],
    proximaFecha: '12/04/2026', firmaColaborador: { fecha: '15/03/2026', hash: 'sha-1o1-247-03' } },
  { id: '1o1-2026-05-E0247', empId: 'E0247', jefeId: 'E0067',
    fecha: '14/05/2026', duracionMin: 30, estado: 'programado',
    agenda: ['Cierre S1 · preparación evaluación', 'Plan de formación cumplido', 'Próximos pasos S2'],
    notasCompartidas: '', acuerdos: [], proximaFecha: null, firmaColaborador: null },
  { id: '1o1-2026-04-E0067', empId: 'E0067', jefeId: 'E0023',
    fecha: '20/04/2026', duracionMin: 45, estado: 'realizado',
    agenda: ['Resultados 360°', 'Plan desarrollo · trim 2', 'Sucesión (formar respaldo)'],
    notasCompartidas: 'Resultados muy buenos en general. Foco en visión a 6 meses (gap detectado por reportes).',
    acuerdos: ['Sesión de planificación trimestral con su equipo · semana del 28/04', 'Documentar decisiones operativas'],
    proximaFecha: '18/05/2026', firmaColaborador: { fecha: '20/04/2026', hash: 'sha-1o1-067-04' } },
];

// ─── Reconocimientos · peer-to-peer + de alto impacto ─────
// Reemplaza la idea de "incidente positivo". Tres niveles de impacto:
//   bajo   · kudo casual · sin evidencia
//   medio  · reconocimiento formal · puede tener evidencia
//   alto   · reconocimiento de alto impacto · evidencia + bitácora del colaborador
// El identificador interno se mantiene como KUDOS por consistencia técnica.

const KUDOS = [
  { id: 'K-001', deId: 'E0067', deNombre: 'Luis Miguel Marín', paraId: 'E0247', fecha: '14/02/2026',
    competenciaId: 'CDC-02', impacto: 'alto',
    mensaje: '¡Gracias Andrés! Detectar la fuga de GLP en el cabezal de la trituradora antes del turno evitó un AT mayor.',
    evidenciaUrl: '#mock-rc-001.pdf', publico: true },
  { id: 'K-002', deId: 'E0067', deNombre: 'Luis Miguel Marín', paraId: 'E0247', fecha: '03/03/2026',
    competenciaId: 'CDC-03', impacto: 'bajo',
    mensaje: 'Apoyo voluntario al cambio de turno extendido cuando faltó un compañero por incapacidad.',
    evidenciaUrl: null, publico: true },
  { id: 'K-003', deId: 'E0023', deNombre: 'Carolina Restrepo', paraId: 'E0067', fecha: '15/03/2026',
    competenciaId: 'CDN-01', impacto: 'medio',
    mensaje: 'Manejaste la salida del operador por bajo rendimiento con respeto y siguiendo el debido proceso. Sin tutela ni demanda. Estoy orgullosa.',
    evidenciaUrl: '#mock-rc-003.pdf', publico: true },
  { id: 'K-004', deId: 'E0156', deNombre: 'Paula Valencia',    paraId: 'E0205', fecha: '08/04/2026',
    competenciaId: 'CDF-02', impacto: 'alto',
    mensaje: 'Carlos resolvió por su cuenta la falla del PLC de la trituradora #2 · evitó parada de 6 horas · ahorro estimado $2.1M COP.',
    evidenciaUrl: '#mock-rc-004.pdf', publico: true },
  { id: 'K-005', deId: 'E0094', deNombre: 'María Trujillo',    paraId: 'E0023', fecha: '02/05/2026',
    competenciaId: 'CDN-02', impacto: 'bajo',
    mensaje: 'Tu retroalimentación quincenal me ha cambiado la forma de trabajar. Gracias.',
    evidenciaUrl: null, publico: false },
];

// ─── Matriz de Evaluadores ─────────────────────────────────
// Para cada evaluado, lista los evaluadores agrupados por perspectiva.
// Marcado de anonimato individual + estado de respuesta.
// Mock: Luis Miguel Marín (líder Aprovechamiento · 360°) con 9 evaluadores.

const MATRIZ_EVALUADORES = [
  { ciclo: 'CY-2025-Q4-360', evaluadoId: 'E0067', evaluadoNombre: 'Luis Miguel Marín',
    perspectivas: {
      self:    [{ id: 'E0067', anon: false }],
      manager: [{ id: 'E0023', anon: false }],
      peer:    [
        { id: 'E0244', anon: true }, { id: 'E0094', anon: true },
        { id: 'E0177', anon: true }, { id: 'E0156', anon: true },
      ],
      report:  [
        { id: 'E0142', anon: true }, { id: 'E0198', anon: true },
        { id: 'E0246', anon: true }, { id: 'E0205', anon: true },
        { id: 'E0247', anon: true },
      ],
      stake:   [],
    } },
  { ciclo: 'CY-2025-Q4-360', evaluadoId: 'E0023', evaluadoNombre: 'Carolina Restrepo',
    perspectivas: {
      self:    [{ id: 'E0023', anon: false }],
      manager: [],   // Es directiva · sin jefe directo en mock
      peer:    [{ id: 'E0067', anon: true }, { id: 'E0244', anon: true }, { id: 'E0177', anon: true }],
      report:  [{ id: 'E0094', anon: true }],   // ⚠️ N=1 · degrada a 180° por anonimato
      stake:   [],
    } },
];

// ─── Evaluaciones Instancia ────────────────────────────────
// Una por par {evaluado · evaluador · ciclo · perspectiva}.
// Estados: pendiente | borrador | enviado-firmado | rechazado.

const EVALUACIONES_INSTANCIA = [
  // ─ Ciclo S1 2026 (180° en progreso) · Andrés Mejía (autoevaluación pendiente) ─
  { id: 'EV-S1-247-self',    cicloId: 'CY-2026-S1', evaluadoId: 'E0247', evaluadorId: 'E0247',
    perspectiva: 'self', estado: 'pendiente', plazoVence: '20/05/2026',
    competencias: [], objetivos: [], firmaElectronica: null },
  { id: 'EV-S1-247-manager', cicloId: 'CY-2026-S1', evaluadoId: 'E0247', evaluadorId: 'E0067',
    perspectiva: 'manager', estado: 'pendiente', plazoVence: '20/05/2026',
    competencias: [], objetivos: [], firmaElectronica: null },
  // ─ Ciclo S1 2026 · Carlos Vélez (autoevaluación enviada) ─
  { id: 'EV-S1-205-self',    cicloId: 'CY-2026-S1', evaluadoId: 'E0205', evaluadorId: 'E0205',
    perspectiva: 'self', estado: 'enviado-firmado', plazoVence: '15/05/2026',
    fechaEnvio: '02/05/2026',
    competencias: [
      { compId: 'CDC-01', score: 4 }, { compId: 'CDC-02', score: 5 },
      { compId: 'CDC-03', score: 4 }, { compId: 'CDC-04', score: 3 },
      { compId: 'CDF-02', score: 4 },
    ],
    objetivos: [], firmaElectronica: { nombre: 'Carlos Andrés Vélez', fecha: '02/05/2026', hash: 'sha-ev-205-self', leyDerivado: 'Ley 527/1999' } },
  { id: 'EV-S1-205-manager', cicloId: 'CY-2026-S1', evaluadoId: 'E0205', evaluadorId: 'E0067',
    perspectiva: 'manager', estado: 'pendiente', plazoVence: '20/05/2026',
    competencias: [], objetivos: [], firmaElectronica: null },
  // ─ Ciclo Q4 2025 360° (cerrado) · Luis Miguel Marín ─
  { id: 'EV-Q4-067-self',    cicloId: 'CY-2025-Q4-360', evaluadoId: 'E0067', evaluadorId: 'E0067',
    perspectiva: 'self', estado: 'enviado-firmado', plazoVence: '22/12/2025', fechaEnvio: '08/12/2025',
    competencias: [
      { compId: 'CDN-02', score: 4 }, { compId: 'CDN-01', score: 4 },
      { compId: 'CDN-04', score: 5 }, { compId: 'CDC-04', score: 4 },
      { compId: 'CDN-03', score: 3 }, { compId: 'CDC-03', score: 3 },
    ],
    firmaElectronica: { nombre: 'Luis Miguel Marín', fecha: '08/12/2025', hash: 'sha-ev-067-self-q4', leyDerivado: 'Ley 527/1999' } },
];

// ─── Plan de Desarrollo Individual (PIP) ───────────────────
// Sólo se persiste cuando está firmado por colaborador y jefe.

const PLANES_DESARROLLO_PIP = [
  { id: 'PIP-2026-001', empId: 'E0247', cicloOrigenId: 'CY-CONT-90',
    motivo: 'plan-desarrollo-positivo', // vs. 'plan-de-mejora-bajo-rend'
    creadoPor: 'E0067', fechaCreacion: '15/04/2026',
    estado: 'activo-firmado', vigenciaHasta: '30/09/2026',
    objetivosMejora: [
      { id: 'pm1', descripcion: 'Cerrar 100% del plan de capacitación obligatorio del cargo', plazo: '30/06/2026' },
      { id: 'pm2', descripcion: 'Reforzar protocolo de cambio de turno (formación + práctica supervisada)', plazo: '15/05/2026' },
    ],
    capacitacionesSugeridas: [
      { cursoId: 'CMP-04', razon: 'Pendiente del plan obligatorio' },
      { cursoId: 'CMP-01', razon: 'Refuerzo SST específico' },
    ],
    firmaColaborador: { nombre: 'Andrés Felipe Mejía', fecha: '15/04/2026', hash: 'sha-pip-247-001', leyDerivado: 'Ley 527/1999' },
    firmaJefe:        { nombre: 'Luis Miguel Marín',   fecha: '15/04/2026', hash: 'sha-pip-067-001', leyDerivado: 'Ley 527/1999' },
    proximaRevision: '15/05/2026',
  },
];

// ─── Nine-Box Snapshots ────────────────────────────────────
// Una foto por ciclo cerrado. NO se sobreescribe (auditabilidad ICONTEC).

const NINE_BOX_SNAPSHOTS = [
  { id: 'NB-CY-2025-Q4', cicloId: 'CY-2025-Q4-360', fecha: '15/01/2026',
    aprobadoPor: 'Carolina Restrepo Salazar · Comité de Talento',
    personas: [
      { empId: 'E0023', perf: 3, pot: 3, score: 4.7 }, { empId: 'E0067', perf: 3, pot: 3, score: 4.5 },
      { empId: 'E0205', perf: 3, pot: 2, score: 4.4 }, { empId: 'E0177', perf: 3, pot: 1, score: 4.3 },
      { empId: 'E0247', perf: 2, pot: 3, score: 3.9 }, { empId: 'E0094', perf: 2, pot: 3, score: 3.8 },
      { empId: 'E0198', perf: 2, pot: 2, score: 3.5 }, { empId: 'E0156', perf: 2, pot: 2, score: 3.6 },
      { empId: 'E0142', perf: 2, pot: 1, score: 3.3 }, { empId: 'E0128', perf: 2, pot: 1, score: 3.2 },
      { empId: 'E0246', perf: 1, pot: 3, score: 3.0 }, { empId: 'E0245', perf: 1, pot: 2, score: 2.8 },
      { empId: 'E0011', perf: 1, pot: 1, score: 2.4 },
    ] },
];

// ─── Assessment Centers (FASE 2 · placeholder) ─────────────
const ASSESSMENT_CENTERS = []; // se construye en Fase 2

// ─── Helpers ───────────────────────────────────────────────

const getCompConductual = (id) => COMPETENCIAS_CONDUCTUALES.find(c => c.id === id);

// Devuelve las competencias conductuales que aplican a un cargo, con su nivel esperado y peso.
const cargoToCompetenciasConductuales = (cargoId) => {
  return NIVELES_ESPERADOS_CARGO
    .filter(n => n.cargoId === cargoId)
    .map(n => ({ ...getCompConductual(n.compId), nivelEsperado: n.nivelEsperado, peso: n.peso }))
    .filter(c => c && c.id);
};

const nivelEsperadoFor = (cargoId, compId) => {
  const row = NIVELES_ESPERADOS_CARGO.find(n => n.cargoId === cargoId && n.compId === compId);
  return row ? row.nivelEsperado : null;
};

// Recomienda metodologías aplicables para un cargo (auto-poblar matriz al crear ciclo).
// Reglas:
//   - Operativos sin reportes → 90° + escalas
//   - Cargos con jefe directo + sin reportes → 180° + competencias + MBO
//   - Cargos con reportes → 360° + competencias + MBO
//   - Cargos críticos (riesgo alto) → +incidentes
const aplicaMetodologiaParaCargo = (cargoId) => {
  const cargo = (window.CARGOS || []).find(c => c.id === cargoId);
  if (!cargo) return ['90', 'escalas'];
  const out = [];
  if (cargo.nivel === 'operativo' || cargo.nivel === 'voluntario') {
    out.push('escalas', '180', 'competencias', 'mbo', 'incidentes');
  } else if (cargo.nivel === 'liderazgo' || cargo.nivel === 'directivo') {
    out.push('360', 'competencias', 'mbo', 'incidentes');
  } else {
    out.push('180', 'competencias', 'mbo');
  }
  return out;
};

// Resuelve la plantilla de escala para un cargo.
const escalaParaCargo = (cargoId) => {
  return ESCALAS_PLANTILLAS.find(p => p.aplicaCargosIds.includes(cargoId)) || ESCALAS_PLANTILLAS[0];
};

// Aplica la regla de anonimato N≥minN.
// Si N < minN para una perspectiva: se OMITE la perspectiva (no se muestra).
// Si una perspectiva (peer/report) cae a 0 evaluadores · degrada de 360° → 180°.
const aplicarReglaAnonimato = (resultadosPorPerspectiva, minN = 3) => {
  const out = {};
  const omitidas = [];
  Object.entries(resultadosPorPerspectiva).forEach(([persp, data]) => {
    const esAnon = persp === 'peer' || persp === 'report' || persp === 'stake';
    if (esAnon && (data?.n || 0) < minN) {
      omitidas.push({ perspectiva: persp, n: data?.n || 0, motivo: `N=${data?.n || 0} < mínimo ${minN}` });
    } else {
      out[persp] = data;
    }
  });
  // Detectar degradación 360 → 180
  const degradacion = (omitidas.some(o => o.perspectiva === 'peer') && omitidas.some(o => o.perspectiva === 'report'))
    ? '360-a-180'
    : null;
  return { resultadosVisibles: out, omitidas, degradacion };
};

// Gap auto vs. otros (promedio jefe + pares + reportes).
const gapPercepcion = (resultadosPorPerspectiva, competenciasIds) => {
  return competenciasIds.map(compId => {
    const self = resultadosPorPerspectiva.self?.[compId] || null;
    const otros = ['manager', 'peer', 'report']
      .map(p => resultadosPorPerspectiva[p]?.[compId])
      .filter(v => typeof v === 'number');
    const promedioOtros = otros.length ? otros.reduce((s, v) => s + v, 0) / otros.length : null;
    return {
      compId,
      self,
      otros: promedioOtros,
      gap: (self !== null && promedioOtros !== null) ? (promedioOtros - self) : null,
    };
  });
};

// Incidentes del período para un colaborador (auto-feed al formulario de evaluación).
const incidentesDelPeriodo = (empId, dateFromCO, dateToCO) => {
  const parse = (s) => {
    if (!s) return null;
    const [d, m, y] = s.split('/').map(Number);
    return new Date(y, m - 1, d).getTime();
  };
  const from = parse(dateFromCO), to = parse(dateToCO);
  return INCIDENTES_CRITICOS.filter(i => {
    if (i.empId !== empId) return false;
    const t = parse(i.fecha);
    if (from && t < from) return false;
    if (to && t > to)   return false;
    return true;
  });
};

// Sugiere capacitaciones del catálogo CRUCE_TECNICO_CONDUCTUAL para una competencia conductual baja.
const sugerirCapacitacionesParaCompetencia = (compId) => {
  const cruce = CRUCE_TECNICO_CONDUCTUAL.find(c => c.conductualId === compId);
  if (!cruce) return [];
  return cruce.tecnicasIds.map(cmpId => {
    const tec = (window.COMPETENCIAS_MAESTRAS || []).find(c => c.id === cmpId);
    return tec ? { competenciaTecnicaId: cmpId, nombre: tec.name || tec.nombre, razon: cruce.razon } : null;
  }).filter(Boolean);
};

// Propone PIP a partir de los resultados de un ciclo (NO crea automáticamente · sólo sugiere a RRHH).
const proponerPIP = (empId, cicloId) => {
  // Mock: Andrés Mejía con dos brechas tras el 90°
  if (empId !== 'E0247') return null;
  return {
    empId, cicloOrigenId: cicloId,
    motivo: 'plan-desarrollo-positivo',
    objetivosMejora: [
      { descripcion: 'Cerrar plan de capacitación obligatorio (CMP-04 + CMP-01)', plazo: '+60d' },
      { descripcion: 'Refuerzo protocolo de cambio de turno', plazo: '+30d' },
    ],
    capacitacionesSugeridas: sugerirCapacitacionesParaCompetencia('CDC-04').slice(0, 2),
    necesitaFirma: true, leyDerivado: 'Ley 527/1999',
  };
};

// Verifica firma electrónica de una evaluación instancia (Ley 527).
const verificarFirmaEvaluacion = (instanciaId) => {
  const ev = EVALUACIONES_INSTANCIA.find(e => e.id === instanciaId);
  if (!ev || !ev.firmaElectronica) return { valida: false, motivo: 'sin-firma' };
  return { valida: true, ...ev.firmaElectronica };
};

// ─── Helpers para el portal del colaborador ─────────────────

const evaluacionesPendientesPara = (empId) => {
  return EVALUACIONES_INSTANCIA.filter(e => e.evaluadorId === empId && e.estado === 'pendiente');
};

const objetivosVigentesPara = (empId) => {
  return OBJETIVOS_CASCADE.filter(o => o.nivel === 'individuo' && o.empId === empId);
};

const checkinsObjetivo = (objId) => OBJETIVO_CHECKINS.filter(c => c.objId === objId);

const incidentesVisiblesPara = (empId) => {
  return INCIDENTES_CRITICOS.filter(i => i.empId === empId && i.visibleAlEvaluado);
};

const kudosRecibidos = (empId) => KUDOS.filter(k => k.paraId === empId);
const kudosEnviados  = (empId) => KUDOS.filter(k => k.deId === empId);

const proximo1on1 = (empId) => {
  const programados = CHECKINS_1ON1.filter(c => c.empId === empId && c.estado === 'programado');
  return programados[0] || null;
};

const ultimos1on1 = (empId, n = 3) => {
  return CHECKINS_1ON1
    .filter(c => c.empId === empId && c.estado === 'realizado')
    .slice(0, n);
};

const pipActivoPara = (empId) => {
  return PLANES_DESARROLLO_PIP.find(p => p.empId === empId && p.estado === 'activo-firmado');
};

const ultimoCicloPublicado = () => {
  return CICLOS_EVALUACION.find(c => c.estado === 'publicado');
};

// ─── Ciclos y empleados de demostración ────────────────────
// Mapa simple para resolver nombres en UI.
const PERSONAS_DESEMPENO = {
  E0023: { nombre: 'Carolina Restrepo Salazar', cargoId: 'CGO-008', initials: 'CR' },
  E0067: { nombre: 'Luis Miguel Marín',         cargoId: 'CGO-004', initials: 'LM' },
  E0094: { nombre: 'María Trujillo Henao',      cargoId: 'CGO-008', initials: 'MT' },
  E0156: { nombre: 'Paula Valencia Ríos',       cargoId: 'CGO-006', initials: 'PV' },
  E0177: { nombre: 'Jorge Iván Patiño',         cargoId: 'CGO-009', initials: 'JP' },
  E0198: { nombre: 'María Fernanda López',      cargoId: 'CGO-003', initials: 'MF' },
  E0205: { nombre: 'Carlos Andrés Vélez',       cargoId: 'CGO-001', initials: 'CV' },
  E0244: { nombre: 'Sandra Milena Ortiz',       cargoId: 'CGO-007', initials: 'SO' },
  E0247: { nombre: 'Andrés Felipe Mejía',       cargoId: 'CGO-001', initials: 'AM' },
  E0142: { nombre: 'Diego Andrés Toro',         cargoId: 'CGO-003', initials: 'DT' },
  E0246: { nombre: 'Laura Gómez Restrepo',      cargoId: 'CGO-002', initials: 'LG' },
  E0245: { nombre: 'Juan David Ruiz',           cargoId: 'CGO-005', initials: 'JR' },
  E0011: { nombre: 'Fernando Henao',            cargoId: 'CGO-001', initials: 'FH' },
  E0128: { nombre: 'Nicolás Cárdenas',          cargoId: 'CGO-009', initials: 'NC' },
};

// ─── Export al window ──────────────────────────────────────

window.MARCO_NORMATIVO_DESEMPENO   = MARCO_NORMATIVO_DESEMPENO;
window.COMPETENCIAS_CONDUCTUALES   = COMPETENCIAS_CONDUCTUALES;
window.CRUCE_TECNICO_CONDUCTUAL    = CRUCE_TECNICO_CONDUCTUAL;
window.NIVELES_ESPERADOS_CARGO     = NIVELES_ESPERADOS_CARGO;
window.ESCALAS_PLANTILLAS          = ESCALAS_PLANTILLAS;
window.OBJETIVOS_CASCADE           = OBJETIVOS_CASCADE;
window.OBJETIVO_CHECKINS           = OBJETIVO_CHECKINS;
window.INCIDENTES_CRITICOS         = INCIDENTES_CRITICOS;
window.CICLOS_EVALUACION           = CICLOS_EVALUACION;
window.PULSE_SURVEYS               = PULSE_SURVEYS;
window.CHECKINS_1ON1               = CHECKINS_1ON1;
window.KUDOS                       = KUDOS;
window.MATRIZ_EVALUADORES          = MATRIZ_EVALUADORES;
window.EVALUACIONES_INSTANCIA      = EVALUACIONES_INSTANCIA;
window.PLANES_DESARROLLO_PIP       = PLANES_DESARROLLO_PIP;
window.NINE_BOX_SNAPSHOTS          = NINE_BOX_SNAPSHOTS;
window.ASSESSMENT_CENTERS          = ASSESSMENT_CENTERS;
window.PERSONAS_DESEMPENO          = PERSONAS_DESEMPENO;

window.getCompConductual                 = getCompConductual;
window.cargoToCompetenciasConductuales   = cargoToCompetenciasConductuales;
window.nivelEsperadoFor                  = nivelEsperadoFor;
window.aplicaMetodologiaParaCargo        = aplicaMetodologiaParaCargo;
window.escalaParaCargo                   = escalaParaCargo;
window.aplicarReglaAnonimato             = aplicarReglaAnonimato;
window.gapPercepcion                     = gapPercepcion;
window.incidentesDelPeriodo              = incidentesDelPeriodo;
window.sugerirCapacitacionesParaCompetencia = sugerirCapacitacionesParaCompetencia;
window.proponerPIP                       = proponerPIP;
window.verificarFirmaEvaluacion          = verificarFirmaEvaluacion;
window.evaluacionesPendientesPara        = evaluacionesPendientesPara;
window.objetivosVigentesPara             = objetivosVigentesPara;
window.checkinsObjetivo                  = checkinsObjetivo;
window.incidentesVisiblesPara            = incidentesVisiblesPara;
window.kudosRecibidos                    = kudosRecibidos;
window.kudosEnviados                     = kudosEnviados;
window.proximo1on1                       = proximo1on1;
window.ultimos1on1                       = ultimos1on1;
window.pipActivoPara                     = pipActivoPara;
window.ultimoCicloPublicado              = ultimoCicloPublicado;
