// Sprint 3 · ICONTEC final pieces
// 1) HashMigration · regenera hashes de certs históricos
// 2) ReassignmentEngine · motor de reasignación automática
// 3) RoleSwitcher + RoleRestricted · permisos con enforcement
// 4) ExpedientePDFModal · expediente firmado del colaborador

const { useState: _ix_useState, useEffect: _ix_useEffect } = React;

// ─── Datos mock ───────────────────────────────────────────

const MIG_PENDING_CERTS = [
  { id: 'CERT-2025-c-09-00742', emp: 'Carolina Restrepo Salazar', empId: 'E0023', course: 'Inducción Atica',     date: '02/02/2019', version: 'v1.0' },
  { id: 'CERT-2025-c-09-00821', emp: 'Luis Miguel Marín',         empId: 'E0067', course: 'Inducción Atica',     date: '11/04/2021', version: 'v1.2' },
  { id: 'CERT-2025-c-05-01102', emp: 'María Trujillo Henao',      empId: 'E0094', course: 'Reglamento Interno · v2',   date: '17/08/2022', version: 'v2.5' },
  { id: 'CERT-2025-c-02-01415', emp: 'Carlos Andrés Vélez',       empId: 'E0205', course: 'BPM',                       date: '14/03/2024', version: 'v1.1' },
  { id: 'CERT-2025-c-07-01512', emp: 'María Fernanda López',      empId: 'E0198', course: 'Manipulación de alimentos', date: '08/01/2024', version: 'v1.0' },
  { id: 'CERT-2025-c-11-01821', emp: 'Jorge Iván Patiño',         empId: 'E0177', course: 'SG-SST general',            date: '11/06/2023', version: 'v1.0' },
  { id: 'CERT-2025-c-02-02041', emp: 'Paula Valencia Ríos',       empId: 'E0156', course: 'BPM',                       date: '03/02/2025', version: 'v1.2' },
  { id: 'CERT-2025-c-09-02102', emp: 'Diego Andrés Toro',         empId: 'E0142', course: 'Inducción Atica',     date: '20/03/2025', version: 'v1.3' },
  { id: 'CERT-2025-c-12-02180', emp: 'Nicolás Cárdenas',          empId: 'E0128', course: 'Manejo defensivo',          date: '05/09/2024', version: 'v1.0' },
  { id: 'CERT-2025-c-09-02212', emp: 'Adriana Restrepo',          empId: 'E0298', course: 'Inducción Atica',     date: '01/02/2026', version: 'v1.5' },
  { id: 'CERT-2025-c-11-02244', emp: 'Andrés Felipe Mejía',       empId: 'E0247', course: 'SG-SST general',            date: '12/05/2024', version: 'v2.0' },
  { id: 'CERT-2025-c-05-02289', emp: 'Sandra Milena Ortiz',       empId: 'E0244', course: 'Reglamento Interno · v2',   date: '21/04/2026', version: 'v2.5' },
];

const RA_RECENT_RUNS = [
  { id: 'RAJ-2026-0509-A', when: '09/05/2026 03:00:14', detected: 12, reassigned: 12, sessionsCreated: 3, notifSent: 24, status: 'completed', duration: '4.2s' },
  { id: 'RAJ-2026-0508-A', when: '08/05/2026 03:00:09', detected: 8,  reassigned: 8,  sessionsCreated: 2, notifSent: 16, status: 'completed', duration: '3.1s' },
  { id: 'RAJ-2026-0507-A', when: '07/05/2026 03:00:11', detected: 5,  reassigned: 5,  sessionsCreated: 1, notifSent: 10, status: 'completed', duration: '2.8s' },
  { id: 'RAJ-2026-0506-A', when: '06/05/2026 03:00:18', detected: 3,  reassigned: 2,  sessionsCreated: 1, notifSent: 4,  status: 'partial',  duration: '5.2s', issue: '1 colaborador sin email registrado · notificación pendiente' },
  { id: 'RAJ-2026-0505-A', when: '05/05/2026 03:00:08', detected: 7,  reassigned: 7,  sessionsCreated: 2, notifSent: 14, status: 'completed', duration: '3.4s' },
];

const RA_UPCOMING = [
  { cmp: 'CMP-01', cmpName: 'Manejo seguro de maquinaria de clasificación', expiringIn: 5, count: 4, action: 'Programar sesión grupal · 14/05', area: 'Operaciones' },
  { cmp: 'CMP-02', cmpName: 'Buenas Prácticas de Manufactura',         expiringIn: 8, count: 7, action: 'E-learning auto-asignado',       area: 'Aprovechamiento/Operaciones' },
  { cmp: 'CMP-12', cmpName: 'Manejo defensivo y seguridad vial',       expiringIn: 12, count: 3, action: 'Programar sesión presencial Barranquilla', area: 'Recolección' },
  { cmp: 'CMP-04', cmpName: 'Trabajo seguro en alturas',                expiringIn: 18, count: 1, action: 'Inscripción individual · CCS',  area: 'Mantenimiento' },
];

// ═══════════════════════════════════════════════════════════
// 1) Hash migration · banner + modal flow
// ═══════════════════════════════════════════════════════════

const HashMigrationBanner = ({ onOpen }) => (
  <div className="ic-mig-banner">
    <div className="ic-mig-banner-icon"><IconAlert size={18} /></div>
    <div style={{ flex: 1, minWidth: 0 }}>
      <div className="ic-mig-banner-title">{MIG_PENDING_CERTS.length} certificados sin hash criptográfico</div>
      <div className="ic-mig-banner-sub">
        Estos certificados fueron emitidos antes de la versión <b>v3.0</b> del sistema (cuando aún no se generaba hash automático). Al regenerarlos retroactivamente quedan auditables y verificables públicamente vía QR.
      </div>
    </div>
    <button className="btn primary" onClick={onOpen}>
      <IconShield size={14} /> Iniciar migración
    </button>
  </div>
);

const HashMigrationModal = ({ onClose }) => {
  const [step, setStep]     = _ix_useState(1);
  const [progress, setProgress] = _ix_useState(0);   // índice del cert que se está procesando
  const [migrated, setMigrated] = _ix_useState([]); // ids ya migrados con hash

  _ix_useEffect(() => {
    document.body.style.overflow = 'hidden';
    const onEsc = (e) => { if (e.key === 'Escape' && step !== 2) onClose(); };
    window.addEventListener('keydown', onEsc);
    return () => { document.body.style.overflow = ''; window.removeEventListener('keydown', onEsc); };
  }, [step]);

  // Animación: cada 600ms procesa un cert
  _ix_useEffect(() => {
    if (step !== 2) return;
    if (progress >= MIG_PENDING_CERTS.length) {
      setTimeout(() => setStep(3), 800);
      return;
    }
    const t = setTimeout(() => {
      const c = MIG_PENDING_CERTS[progress];
      const fakeHash = Array.from({ length: 16 }, () =>
        '0123456789abcdef'[Math.floor(Math.random() * 16)]
      ).join('');
      setMigrated(m => [...m, { ...c, hash: fakeHash }]);
      setProgress(p => p + 1);
    }, 580);
    return () => clearTimeout(t);
  }, [step, progress]);

  return (
    <div className="modal-overlay" onMouseDown={(e) => { if (e.target === e.currentTarget && step !== 2) onClose(); }}>
      <div className="modal" style={{ maxWidth: 900, height: 'calc(100vh - 96px)' }}>
        <div className="modal-head">
          <div>
            <div className="muted mono" style={{ fontSize: 11 }}>MIGRATION-2026-001</div>
            <div className="modal-title">Migración de hashes · certificados pre-v3.0</div>
            <div className="modal-sub">
              Genera el hash criptográfico SHA-256 retroactivamente para los {MIG_PENDING_CERTS.length} certificados que quedaron sin sello al migrar de la versión anterior del sistema.
            </div>
          </div>
          {step !== 2 && (
            <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>

        {/* Step indicator */}
        <div className="ic-mig-stepper">
          <div className={`ic-mig-step ${step >= 1 ? 'on' : ''} ${step > 1 ? 'done' : ''}`}>
            <span>{step > 1 ? <IconCheck size={11} /> : 1}</span>
            <span>Revisar lista</span>
          </div>
          <div className={`ic-mig-step-line ${step > 1 ? 'done' : ''}`} />
          <div className={`ic-mig-step ${step >= 2 ? 'on' : ''} ${step > 2 ? 'done' : ''}`}>
            <span>{step > 2 ? <IconCheck size={11} /> : 2}</span>
            <span>Procesar</span>
          </div>
          <div className={`ic-mig-step-line ${step > 2 ? 'done' : ''}`} />
          <div className={`ic-mig-step ${step >= 3 ? 'on' : ''}`}>
            <span>{step >= 3 ? <IconCheck size={11} /> : 3}</span>
            <span>Confirmar</span>
          </div>
        </div>

        <div className="modal-body" style={{ padding: 0 }}>

          {step === 1 && (
            <div style={{ padding: 22 }}>
              <div className="ic-mig-info">
                <IconShield size={14} />
                <div>
                  <div style={{ fontWeight: 700, fontSize: 13 }}>¿Cómo funciona la migración?</div>
                  <div className="muted" style={{ fontSize: 12, marginTop: 4, lineHeight: 1.5 }}>
                    Para cada certificado, el sistema reconstruye el expediente con los datos disponibles (asistencia, evaluación, evidencias, versión del contenido) y genera un hash SHA-256 que se ancla al certificado. <b>Los datos del certificado original NO cambian.</b> Solo se agrega el hash como sello criptográfico que el verificador público puede validar.
                  </div>
                </div>
              </div>

              <div className="muted-xs" style={{ marginTop: 16, marginBottom: 10 }}>Certificados a migrar · {MIG_PENDING_CERTS.length} registros</div>
              <div className="ic-mig-list">
                {MIG_PENDING_CERTS.map(c => (
                  <div key={c.id} className="ic-mig-row">
                    <div className="muted mono" style={{ fontSize: 11 }}>{c.id}</div>
                    <div>
                      <div style={{ fontWeight: 600, fontSize: 12.5 }}>{c.emp}</div>
                      <div className="muted mono" style={{ fontSize: 10.5 }}>{c.empId}</div>
                    </div>
                    <div style={{ fontSize: 12 }}>{c.course}</div>
                    <div className="mono muted" style={{ fontSize: 11.5 }}>{c.date}</div>
                    <div><span className="pill navy mono" style={{ fontSize: 10.5 }}>{c.version}</span></div>
                    <span className="ic-mig-status pending"><IconClock size={11} /> Sin hash</span>
                  </div>
                ))}
              </div>
            </div>
          )}

          {step === 2 && (
            <div className="ic-mig-running">
              <div className="ic-mig-running-head">
                <div className="mi-motor" style={{ background: 'transparent', border: 'none', padding: 0 }}>
                  <div className="mi-motor-spinner" />
                  <div>
                    <div style={{ fontWeight: 800, fontSize: 16, color: 'var(--navy-800)' }}>
                      Procesando expedientes históricos
                      <span className="mi-motor-text" />
                    </div>
                    <div className="muted" style={{ fontSize: 12, marginTop: 2 }}>
                      Reconstruyendo cadena de evidencia · generando hash SHA-256 · firmando sello
                    </div>
                  </div>
                </div>
                <div className="ic-mig-running-pct">
                  <div className="mono" style={{ fontSize: 28, fontWeight: 800, color: 'var(--navy-800)' }}>
                    {progress}<small style={{ fontSize: 14, color: 'var(--text-muted)' }}>/{MIG_PENDING_CERTS.length}</small>
                  </div>
                </div>
              </div>

              <div className="ic-mig-progress">
                <div className="ic-mig-progress-fill" style={{ width: `${(progress / MIG_PENDING_CERTS.length) * 100}%` }} />
              </div>

              <div className="muted-xs" style={{ padding: '14px 22px 6px' }}>Bitácora en tiempo real</div>
              <div className="ic-mig-livelog">
                {migrated.slice().reverse().map((m, i) => (
                  <div key={m.id} className={`ic-mig-loglet ${i === 0 ? 'fresh' : ''}`}>
                    <span className="ic-mig-loglet-icon"><IconCheck size={11} /></span>
                    <div style={{ flex: 1, minWidth: 0 }}>
                      <div style={{ fontSize: 12, fontWeight: 600 }}>
                        Hash generado para <span className="mono">{m.id}</span>
                      </div>
                      <div className="muted mono" style={{ fontSize: 10.5, marginTop: 2 }}>
                        {m.emp} · {m.course} · sello <span style={{ color: 'var(--green-600)' }}>{m.hash}…</span>
                      </div>
                    </div>
                  </div>
                ))}
              </div>
            </div>
          )}

          {step === 3 && (
            <div className="ic-mig-done">
              <div className="mi-stamp">
                <div className="mi-stamp-mark">MIGRADO<span>{MIG_PENDING_CERTS.length} certs</span></div>
              </div>
              <h3 style={{ fontSize: 20, fontWeight: 800, marginTop: 18, marginBottom: 6, letterSpacing: '-0.015em' }}>
                Migración completada
              </h3>
              <p className="muted" style={{ fontSize: 13.5, maxWidth: 460, lineHeight: 1.55, textAlign: 'center', margin: '0 auto 16px' }}>
                Los <b>{MIG_PENDING_CERTS.length} certificados</b> históricos quedaron auditables. Cada uno tiene ahora un hash SHA-256 verificable públicamente vía QR. La acción quedó registrada en la bitácora con el detalle completo.
              </p>

              <div className="ic-mig-summary">
                <div className="ic-mig-sum-row">
                  <span className="muted-xs">Migrados</span>
                  <span className="mono" style={{ fontSize: 14, fontWeight: 800, color: 'var(--green-600)' }}>{MIG_PENDING_CERTS.length}</span>
                </div>
                <div className="ic-mig-sum-row">
                  <span className="muted-xs">Algoritmo</span>
                  <span className="mono" style={{ fontSize: 12 }}>SHA-256 · ancla al expediente reconstruido</span>
                </div>
                <div className="ic-mig-sum-row">
                  <span className="muted-xs">Ejecutado por</span>
                  <span style={{ fontSize: 12.5 }}>Carolina Restrepo · Admin RRHH</span>
                </div>
                <div className="ic-mig-sum-row">
                  <span className="muted-xs">Bitácora</span>
                  <span className="mono" style={{ fontSize: 11.5 }}>AL-2392 · creada hace un momento</span>
                </div>
                <div className="ic-mig-sum-row">
                  <span className="muted-xs">Verificación pública</span>
                  <span style={{ fontSize: 12 }}>Activa para los 12 certificados</span>
                </div>
              </div>
            </div>
          )}
        </div>

        <div className="modal-foot">
          {step === 1 && (
            <>
              <button className="btn" onClick={onClose}>Cancelar</button>
              <div style={{ flex: 1 }} />
              <button className="btn primary" onClick={() => setStep(2)}>
                <IconShield size={14} /> Iniciar migración de {MIG_PENDING_CERTS.length} certificados
              </button>
            </>
          )}
          {step === 2 && (
            <>
              <span className="muted" style={{ fontSize: 12, marginRight: 'auto' }}>
                <IconShield size={12} /> Procesando · no cierres esta ventana
              </span>
              <button className="btn" disabled>Espera unos segundos…</button>
            </>
          )}
          {step === 3 && (
            <>
              <button className="btn"><IconExternal size={13} /> Ver en bitácora</button>
              <div style={{ flex: 1 }} />
              <button className="btn primary" onClick={onClose}><IconCheck size={14} /> Cerrar</button>
            </>
          )}
        </div>
      </div>
    </div>
  );
};

// ═══════════════════════════════════════════════════════════
// 2) Reassignment Engine · pestaña dentro del Motor
// ═══════════════════════════════════════════════════════════

const ReassignmentEngine = () => {
  const total = RA_RECENT_RUNS.reduce((a, r) => a + r.detected, 0);
  const ok = RA_RECENT_RUNS.reduce((a, r) => a + r.reassigned, 0);
  const sessions = RA_RECENT_RUNS.reduce((a, r) => a + r.sessionsCreated, 0);
  const notifs = RA_RECENT_RUNS.reduce((a, r) => a + r.notifSent, 0);

  return (
    <div className="ic-ra">
      {/* Banner del motor */}
      <div className="ic-ra-banner">
        <div className="ic-ra-banner-engine">
          <IconZap size={26} />
        </div>
        <div style={{ flex: 1, minWidth: 0 }}>
          <div style={{ fontSize: 16, fontWeight: 800, color: 'var(--text)', letterSpacing: '-0.01em' }}>
            Motor de reasignación automática · activo
          </div>
          <div className="muted" style={{ fontSize: 12.5, marginTop: 3, lineHeight: 1.5 }}>
            Job <span className="mono">cron · 0 3 * * *</span> · revisa diariamente a las <b>03:00 AM</b> qué competencias vencen en los próximos 30 días, crea las reasignaciones, agrupa cuando hay ≥ 3 colaboradores con la misma necesidad, y notifica al jefe directo + colaborador.
          </div>
        </div>
        <span className="pill green" style={{ flexShrink: 0 }}>
          <span className="status-dot" style={{ background: 'var(--green-600)' }} /> 5 ejecuciones consecutivas exitosas
        </span>
      </div>

      {/* Stats */}
      <div className="ic-ra-stats">
        <div className="ic-ra-stat">
          <div className="ic-ra-stat-icon navy"><IconAlert size={16} /></div>
          <div>
            <div className="ic-ra-stat-num">{total}</div>
            <div className="ic-ra-stat-lbl">Vencimientos detectados</div>
            <div className="muted" style={{ fontSize: 10.5 }}>últimos 5 días</div>
          </div>
        </div>
        <div className="ic-ra-stat">
          <div className="ic-ra-stat-icon green"><IconCheck size={16} /></div>
          <div>
            <div className="ic-ra-stat-num pos">{ok}</div>
            <div className="ic-ra-stat-lbl">Reasignaciones generadas</div>
            <div className="muted" style={{ fontSize: 10.5 }}>{Math.round((ok / total) * 100)}% de detección</div>
          </div>
        </div>
        <div className="ic-ra-stat">
          <div className="ic-ra-stat-icon blue"><IconRocket size={16} /></div>
          <div>
            <div className="ic-ra-stat-num">{sessions}</div>
            <div className="ic-ra-stat-lbl">Sesiones agrupadas auto</div>
            <div className="muted" style={{ fontSize: 10.5 }}>≥ 3 colaboradores · misma competencia</div>
          </div>
        </div>
        <div className="ic-ra-stat">
          <div className="ic-ra-stat-icon amber"><IconMegaphone size={16} /></div>
          <div>
            <div className="ic-ra-stat-num">{notifs}</div>
            <div className="ic-ra-stat-lbl">Notificaciones enviadas</div>
            <div className="muted" style={{ fontSize: 10.5 }}>email + jefe directo</div>
          </div>
        </div>
      </div>

      {/* Configuración */}
      <div className="ic-ra-card">
        <div className="ic-ra-card-head">
          <div>
            <h3>Reglas del motor</h3>
            <div className="muted" style={{ fontSize: 12.5 }}>Parámetros que rigen la reasignación automática</div>
          </div>
          <button className="btn"><IconExternal size={13} /> Editar reglas</button>
        </div>
        <div className="ic-ra-rules">
          <div className="ic-ra-rule">
            <div className="ic-ra-rule-icon"><IconClock size={14} /></div>
            <div style={{ flex: 1 }}>
              <div className="ic-ra-rule-name">Anticipación de detección</div>
              <div className="muted" style={{ fontSize: 11.5 }}>El motor mira los <b style={{ color: 'var(--text)' }}>30 días</b> siguientes para anticipar reasignaciones</div>
            </div>
            <span className="ic-ra-rule-val mono">30 días</span>
          </div>
          <div className="ic-ra-rule">
            <div className="ic-ra-rule-icon"><IconUsers size={14} /></div>
            <div style={{ flex: 1 }}>
              <div className="ic-ra-rule-name">Umbral de agrupación</div>
              <div className="muted" style={{ fontSize: 11.5 }}>Si ≥ N colaboradores comparten la misma competencia a vencer, programa <b style={{ color: 'var(--text)' }}>una sola sesión</b></div>
            </div>
            <span className="ic-ra-rule-val mono">≥ 3</span>
          </div>
          <div className="ic-ra-rule">
            <div className="ic-ra-rule-icon"><IconMegaphone size={14} /></div>
            <div style={{ flex: 1 }}>
              <div className="ic-ra-rule-name">Notificación al jefe directo</div>
              <div className="muted" style={{ fontSize: 11.5 }}>Si el colaborador no responde en <b style={{ color: 'var(--text)' }}>72 horas</b>, copia automática al jefe</div>
            </div>
            <span className="ic-ra-rule-val mono">72 h</span>
          </div>
          <div className="ic-ra-rule">
            <div className="ic-ra-rule-icon"><IconShield size={14} /></div>
            <div style={{ flex: 1 }}>
              <div className="ic-ra-rule-name">Bloqueo si la competencia es crítica</div>
              <div className="muted" style={{ fontSize: 11.5 }}>Competencias <b style={{ color: 'var(--rose-600)' }}>criticidad alta</b> con vigencia vencida bloquean el ingreso del colaborador a su área</div>
            </div>
            <span className="ic-ra-rule-val">Activo</span>
          </div>
        </div>
      </div>

      {/* Próximas reasignaciones */}
      <div className="ic-ra-card">
        <div className="ic-ra-card-head">
          <div>
            <h3>Próximas reasignaciones · planificadas</h3>
            <div className="muted" style={{ fontSize: 12.5 }}>Lo que el motor ejecutará automáticamente en los próximos días</div>
          </div>
        </div>
        <div className="ic-ra-upcoming">
          {RA_UPCOMING.map((u, i) => (
            <div key={i} className="ic-ra-up-row">
              <div className="ic-ra-up-days">
                <div className="mono" style={{ fontSize: 22, fontWeight: 800, color: u.expiringIn <= 7 ? 'var(--rose-600)' : u.expiringIn <= 14 ? 'var(--amber-600)' : 'var(--text)' }}>{u.expiringIn}</div>
                <div className="muted" style={{ fontSize: 10.5 }}>días</div>
              </div>
              <div style={{ flex: 1, minWidth: 0 }}>
                <div style={{ fontWeight: 700, fontSize: 13 }}>{u.cmpName}</div>
                <div className="muted" style={{ fontSize: 11.5, marginTop: 2 }}>
                  <span className="mono">{u.cmp}</span> · {u.area} · <b style={{ color: 'var(--text)' }}>{u.count}</b> colaborador{u.count === 1 ? '' : 'es'} afectado{u.count === 1 ? '' : 's'}
                </div>
              </div>
              <div className="ic-ra-up-action">
                <IconRocket size={11} /> {u.action}
              </div>
            </div>
          ))}
        </div>
      </div>

      {/* Bitácora del motor */}
      <div className="ic-ra-card">
        <div className="ic-ra-card-head">
          <div>
            <h3>Bitácora · ejecuciones recientes</h3>
            <div className="muted" style={{ fontSize: 12.5 }}>Cada job queda registrado con su detalle y duración</div>
          </div>
          <button className="btn"><IconExternal size={13} /> Ver historial completo</button>
        </div>
        <div className="ic-ra-runs">
          {RA_RECENT_RUNS.map(r => (
            <div key={r.id} className={`ic-ra-run ${r.status}`}>
              <div className="ic-ra-run-status">
                {r.status === 'completed' ? <IconCheck size={13} /> : <IconAlert size={13} />}
              </div>
              <div style={{ flex: 1, minWidth: 0 }}>
                <div style={{ display: 'flex', alignItems: 'center', gap: 10, flexWrap: 'wrap' }}>
                  <span className="mono" style={{ fontSize: 12, fontWeight: 800, color: 'var(--text)' }}>{r.id}</span>
                  <span className={`pill ${r.status === 'completed' ? 'green' : 'amber-soft'}`} style={{ fontSize: 10.5 }}>
                    {r.status === 'completed' ? 'Completado' : 'Parcial'}
                  </span>
                  <span className="muted mono" style={{ fontSize: 10.5 }}>{r.when}</span>
                  <span className="muted mono" style={{ fontSize: 10.5 }}>· {r.duration}</span>
                </div>
                <div className="ic-ra-run-meta">
                  <span><IconAlert size={10} /> {r.detected} detectados</span>
                  <span><IconCheck size={10} /> {r.reassigned} reasignados</span>
                  <span><IconRocket size={10} /> {r.sessionsCreated} sesiones</span>
                  <span><IconMegaphone size={10} /> {r.notifSent} notificaciones</span>
                </div>
                {r.issue && (
                  <div className="ic-ra-run-issue">
                    <IconAlert size={11} /> {r.issue}
                  </div>
                )}
              </div>
            </div>
          ))}
        </div>
      </div>
    </div>
  );
};

// ═══════════════════════════════════════════════════════════
// 3) Role Switcher + Restricted gate
// ═══════════════════════════════════════════════════════════

const IC_ROLE_META = {
  admin:      { label: 'Gestión Humana',    short: 'Gestión Humana', desc: 'Carolina Restrepo · acceso total + bitácora', tone: 'rose',  initials: 'CR' },
  jefe:       { label: 'Jefe',              short: 'Jefe',      desc: 'Luis Miguel Marín · su equipo y aprobaciones', tone: 'blue',  initials: 'LM' },
  nuevo:      { label: 'Colaborador',       short: 'Colaborador', desc: 'Andrés Felipe Mejía · autoservicio', tone: 'teal', initials: 'AM' },
};

const RoleSwitcher = ({ currentRole, setCurrentRole }) => {
  const [open, setOpen] = _ix_useState(false);
  const meta = IC_ROLE_META[currentRole];

  _ix_useEffect(() => {
    const onClick = () => setOpen(false);
    if (open) {
      document.addEventListener('click', onClick);
      return () => document.removeEventListener('click', onClick);
    }
  }, [open]);

  return (
    <div className="ic-role-wrap" onClick={(e) => e.stopPropagation()}>
      <button className={`ic-role-btn ic-role-${meta.tone}`} onClick={() => setOpen(o => !o)}>
        <span className={`ic-role-pip ${meta.tone}`}>{meta.initials}</span>
        <span style={{ display: 'flex', flexDirection: 'column', alignItems: 'flex-start', gap: 1 }}>
          <span style={{ fontSize: 9.5, fontWeight: 700, color: 'var(--text-muted)', textTransform: 'uppercase', letterSpacing: 0.06 }}>Ver como</span>
          <span style={{ fontSize: 11.5, fontWeight: 700, color: 'var(--text)' }}>{meta.short}</span>
        </span>
        <svg width="10" height="10" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5"><path d="m6 9 6 6 6-6" /></svg>
      </button>

      {open && (
        <div className="ic-role-menu">
          <div className="muted-xs" style={{ padding: '4px 12px 8px', borderBottom: '1px solid var(--border)' }}>
            Modo demo · permisos en vivo
          </div>
          {Object.entries(IC_ROLE_META).map(([k, m]) => (
            <button
              key={k}
              className={`ic-role-item ${currentRole === k ? 'active' : ''}`}
              onClick={() => { setCurrentRole(k); setOpen(false); }}
            >
              <span className={`ic-role-pip ${m.tone}`}>{m.initials}</span>
              <div style={{ flex: 1, minWidth: 0, textAlign: 'left' }}>
                <div style={{ fontWeight: 700, fontSize: 12.5 }}>{m.label}</div>
                <div className="muted" style={{ fontSize: 10.5, marginTop: 2 }}>{m.desc}</div>
              </div>
              {currentRole === k && <IconCheck size={13} style={{ color: 'var(--green-600)' }} />}
            </button>
          ))}
          <div className="ic-role-foot">
            <IconShield size={11} /> Cambiar de rol no afecta operaciones · solo recorta permisos visualmente
          </div>
        </div>
      )}
    </div>
  );
};

// Gate · si el rol no está permitido, muestra estado vacío profesional
const RoleRestricted = ({ allow, currentRole, children, label = 'esta sección' }) => {
  if (allow.includes(currentRole)) return children;
  const meta = IC_ROLE_META[currentRole];
  return (
    <div className="ic-role-blocked">
      <div className="ic-role-blocked-icon">
        <svg width="42" height="42" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6">
          <rect x="4" y="11" width="16" height="10" rx="2" />
          <path d="M8 11V7a4 4 0 0 1 8 0v4" />
        </svg>
      </div>
      <h3 className="ic-role-blocked-title">Acceso restringido</h3>
      <p className="ic-role-blocked-sub">
        Tu rol actual <b className={`cf-role-badge ${meta.tone}`} style={{ display: 'inline-block', verticalAlign: 'middle' }}>{meta.label}</b> no tiene permisos para ver {label}.
      </p>
      <p className="muted" style={{ fontSize: 12, lineHeight: 1.5, maxWidth: 420 }}>
        Esta restricción está vigilada por la matriz de permisos de <b>Configuración · Usuarios y roles</b>. Solo {allow.map(r => IC_ROLE_META[r].label).join(' · ')} pueden acceder a este contenido.
      </p>
      <div className="ic-role-blocked-meta mono">
        Intento registrado · {new Date().toLocaleString('es-CO')} · IP 190.85.247.32
      </div>
    </div>
  );
};

// ═══════════════════════════════════════════════════════════
// 4) Expediente PDF · modal del expediente firmado
// ═══════════════════════════════════════════════════════════

const ExpedientePDFModal = ({ onClose }) => {
  const [stage, setStage] = _ix_useState('preview');  // preview | signing | signed

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

  const sign = () => {
    setStage('signing');
    setTimeout(() => setStage('signed'), 1800);
  };

  return (
    <div className="modal-overlay" onMouseDown={(e) => { if (e.target === e.currentTarget && stage !== 'signing') onClose(); }}>
      <div className="modal" style={{ maxWidth: 1100, height: 'calc(100vh - 64px)' }}>
        <div className="modal-head">
          <div>
            <div className="muted mono" style={{ fontSize: 11 }}>EXP-2026-E0205-001</div>
            <div className="modal-title">Expediente firmado · entregable a auditor ICONTEC</div>
            <div className="modal-sub">Vista previa del PDF que se generará y firmará electrónicamente con el sello del administrador. <b>12 páginas · 5 secciones · hash global del expediente.</b></div>
          </div>
          <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>

        <div className="cert-stage" style={{ background: 'linear-gradient(180deg, #ECEEF5 0%, #E1E5F0 100%)' }}>
          <div className="ic-exp-doc">

            {/* Cover */}
            <div className="ic-exp-cover">
              <div className="ic-exp-cover-band" />
              <div style={{ display: 'flex', alignItems: 'center', gap: 14 }}>
                <div className="cv-brand-mark plataforma" style={{ width: 48, height: 48, fontSize: 24 }}><AticaMark size={30} tri="#fff" leaf="var(--sky-500)" /></div>
                <div className="ic-exp-cover-divider" />
                <div className="cv-brand-mark client" style={{ width: 48, height: 48, fontSize: 24 }}>a</div>
                <div style={{ flex: 1 }}>
                  <div style={{ fontWeight: 800, fontSize: 14 }}>Atica S.A.S.</div>
                  <div className="muted mono" style={{ fontSize: 11 }}>NIT 900.123.456-7</div>
                </div>
              </div>

              <div className="ic-exp-cover-eyebrow">Expediente de competencias y formación · Auditoría ICONTEC</div>
              <h1 className="ic-exp-cover-title">Carlos Andrés Vélez</h1>
              <div className="ic-exp-cover-sub">Operario de Clasificación · Operaciones · Cali · ID E0205</div>

              <div className="ic-exp-cover-meta">
                <div><div className="muted-xs">Período evaluado</div><div className="ic-exp-meta-val mono">14/03/2024 → 05/05/2026</div></div>
                <div><div className="muted-xs">Cumplimiento global</div><div className="ic-exp-meta-val pos">83%</div></div>
                <div><div className="muted-xs">Competencias requeridas</div><div className="ic-exp-meta-val mono">6</div></div>
                <div><div className="muted-xs">Certificados vigentes</div><div className="ic-exp-meta-val pos mono">4</div></div>
              </div>

              <div className="ic-exp-cover-emit">
                <div>
                  <div className="muted-xs">Generado por</div>
                  <div style={{ fontWeight: 700, fontSize: 12.5, marginTop: 3 }}>Carolina Restrepo Salazar</div>
                  <div className="muted" style={{ fontSize: 11 }}>Jefe de RRHH · firma certificada</div>
                </div>
                <div>
                  <div className="muted-xs">Fecha de emisión</div>
                  <div className="mono" style={{ fontWeight: 700, fontSize: 12.5, marginTop: 3 }}>05/05/2026 · 14:42</div>
                  <div className="muted mono" style={{ fontSize: 11 }}>EXP-2026-E0205-001</div>
                </div>
              </div>
            </div>

            {/* Sección · Resumen */}
            <div className="ic-exp-section">
              <div className="ic-exp-section-h">1 · Resumen de cumplimiento</div>
              <div className="ic-exp-grid">
                <div className="ic-exp-stat green">
                  <div className="ic-exp-stat-num">4</div>
                  <div className="ic-exp-stat-lbl">Vigentes</div>
                </div>
                <div className="ic-exp-stat amber">
                  <div className="ic-exp-stat-num">1</div>
                  <div className="ic-exp-stat-lbl">En curso</div>
                </div>
                <div className="ic-exp-stat rose">
                  <div className="ic-exp-stat-num">1</div>
                  <div className="ic-exp-stat-lbl">Vencida (reasignada)</div>
                </div>
                <div className="ic-exp-stat navy">
                  <div className="ic-exp-stat-num">12</div>
                  <div className="ic-exp-stat-lbl">Eventos en bitácora</div>
                </div>
              </div>
              <p style={{ fontSize: 12.5, lineHeight: 1.6, marginTop: 10, color: 'var(--text)' }}>
                El colaborador <b>Carlos Andrés Vélez</b> mantiene cumplimiento al <b>83%</b> de las competencias críticas requeridas por su cargo. La única competencia vencida (CMP-03 · Manipulación higiénica de alimentos) fue reasignada automáticamente por el motor el 02/05/2026.
              </p>
            </div>

            {/* Sección · Timeline */}
            <div className="ic-exp-section">
              <div className="ic-exp-section-h">2 · Línea de tiempo inmutable · 4 eventos clave</div>
              <div className="ic-exp-timeline">
                {[
                  { date: '12/04/2026', label: 'Aprobó CMP-01 con 92/100',                hash: 'a4f2c1e8…d4b6a9f1', tone: 'green' },
                  { date: '20/08/2025', label: 'Aprobó CMP-11 (SG-SST) con 84/100',       hash: 'b7e3d8a1…f9c4e2b6', tone: 'green' },
                  { date: '02/05/2026', label: 'CMP-03 venció · reasignada automática',   hash: '—',                tone: 'rose' },
                  { date: '14/03/2024', label: 'Aprobó CMP-09 (Inducción) con 95/100',    hash: 'c2a1f4e7…b9d3a5c8', tone: 'green' },
                ].map((e, i) => (
                  <div key={i} className={`ic-exp-tl ic-exp-tl-${e.tone}`}>
                    <span className="ic-exp-tl-date mono">{e.date}</span>
                    <span className="ic-exp-tl-label">{e.label}</span>
                    <span className="ic-exp-tl-hash mono">{e.hash}</span>
                  </div>
                ))}
              </div>
            </div>

            {/* Sección · Certificados */}
            <div className="ic-exp-section">
              <div className="ic-exp-section-h">3 · Certificados emitidos · 4 documentos</div>
              <div className="ic-exp-certs-grid">
                {[
                  { id: 'CERT-2026-c-01-04821', cmp: 'CMP-01', course: 'Manejo seguro de maquinaria', date: '12/04/2026', score: 92, version: 'v3.2' },
                  { id: 'CERT-2024-c-09-01102', cmp: 'CMP-09', course: 'Inducción Atica',       date: '14/03/2024', score: 95, version: 'v2.0' },
                  { id: 'CERT-2026-c-05-03415', cmp: 'CMP-06', course: 'RIT · Reforma Laboral 2025', date: '10/02/2026', score: 88, version: 'v1.4' },
                  { id: 'CERT-2025-c-11-09921', cmp: 'CMP-11', course: 'SG-SST general',              date: '20/08/2025', score: 84, version: 'v2.1' },
                ].map(c => (
                  <div key={c.id} className="ic-exp-cert">
                    <div className="ic-exp-cert-head">
                      <div className="muted mono" style={{ fontSize: 9 }}>{c.cmp} · {c.id}</div>
                    </div>
                    <div className="ic-exp-cert-name">{c.course}</div>
                    <div className="ic-exp-cert-meta">
                      <div><div className="muted-xs">Nota</div><div className="mono pos" style={{ fontWeight: 800 }}>{c.score}/100</div></div>
                      <div><div className="muted-xs">Versión</div><div className="mono">{c.version}</div></div>
                      <div><div className="muted-xs">Fecha</div><div className="mono">{c.date}</div></div>
                    </div>
                  </div>
                ))}
              </div>
            </div>

            {/* Sección · Cadena de evidencia */}
            <div className="ic-exp-section">
              <div className="ic-exp-section-h">4 · Cadena de evidencia consolidada</div>
              <div className="ic-exp-evidence">
                {[
                  ['Asistencia firmada electrónicamente',  '4 sesiones · OTP email + SMS'],
                  ['Evaluaciones aplicadas',                '4 evaluaciones · 100% completadas'],
                  ['Evidencias adjuntas',                   '14 archivos · actas + fotos + listas'],
                  ['Versiones de contenido ancladas',       'v3.2 · v2.0 · v1.4 · v2.1 (todas activas o históricas válidas)'],
                  ['Instructores identificados',            'Carlos F. Vélez · ARL Sura · plataforma interna'],
                ].map(([lbl, val], i) => (
                  <div key={i} className="ic-exp-ev-row">
                    <span className="ic-exp-ev-icon"><IconCheck size={11} /></span>
                    <span className="ic-exp-ev-lbl">{lbl}</span>
                    <span className="ic-exp-ev-val">{val}</span>
                  </div>
                ))}
              </div>
            </div>

            {/* Sección · Hash global + firma */}
            <div className="ic-exp-section ic-exp-section-final">
              <div className="ic-exp-section-h">5 · Hash global del expediente · firma del administrador</div>
              <div className="ic-exp-hash-block">
                <div>
                  <div className="muted-xs">SHA-256 del expediente completo</div>
                  <div className="ic-exp-hash mono">a4f2c1e89b7d3f5e26c8d4b1a9f3e7c5d8b2a4f6e9c1d3b5a7f8e0c2d4b6a9f1</div>
                  <div className="muted" style={{ fontSize: 10.5, marginTop: 6, lineHeight: 1.45 }}>
                    Este hash sella la integridad del PDF: si cualquier byte cambia, el sello se invalida. El auditor puede verificarlo en <span className="mono">verifica.atica.co/EXP-E0205-001</span>.
                  </div>
                </div>
                <div className="ic-exp-sign">
                  {stage === 'signed'
                    ? <>
                        <div className="mi-stamp" style={{ width: 100, height: 100 }}>
                          <div className="mi-stamp-mark" style={{ width: 90, height: 90, fontSize: 11 }}>FIRMADO<span style={{ fontSize: 8 }}>Carolina R.</span></div>
                        </div>
                        <div className="muted mono" style={{ fontSize: 10, textAlign: 'center', marginTop: 6 }}>
                          firma digital · 05/05/2026
                        </div>
                      </>
                    : <>
                        <div className="ic-exp-sign-line" />
                        <div className="ic-exp-sign-name">Carolina Restrepo Salazar</div>
                        <div className="muted" style={{ fontSize: 10 }}>Jefe de RRHH</div>
                      </>
                  }
                </div>
              </div>
            </div>

          </div>
        </div>

        <div className="modal-foot">
          {stage === 'preview' && (
            <>
              <button className="btn" onClick={onClose}>Cerrar</button>
              <span className="muted" style={{ fontSize: 12, marginLeft: 'auto', marginRight: 12 }}>
                <IconShield size={12} /> El PDF generado quedará en la bitácora con timestamp y hash
              </span>
              <button className="btn"><IconExternal size={13} /> Descargar borrador (sin firma)</button>
              <button className="btn primary" onClick={sign}>
                <IconShield size={14} /> Firmar y emitir expediente oficial
              </button>
            </>
          )}
          {stage === 'signing' && (
            <>
              <span className="mi-motor" style={{ background: 'transparent', border: 'none', padding: 0 }}>
                <span className="mi-motor-spinner" />
                <span>Firmando digitalmente · sellando expediente<span className="mi-motor-text" /></span>
              </span>
            </>
          )}
          {stage === 'signed' && (
            <>
              <span className="muted" style={{ fontSize: 12, marginRight: 'auto' }}>
                <IconCheck size={12} style={{ color: 'var(--green-600)' }} /> Firmado digitalmente · expediente sellado · listo para entregar al auditor
              </span>
              <button className="btn"><IconMegaphone size={13} /> Enviar a soporte ICONTEC</button>
              <button className="btn primary"><IconExternal size={14} /> Descargar PDF firmado</button>
            </>
          )}
        </div>
      </div>
    </div>
  );
};

window.HashMigrationBanner = HashMigrationBanner;
window.HashMigrationModal  = HashMigrationModal;
window.ReassignmentEngine  = ReassignmentEngine;
window.RoleSwitcher        = RoleSwitcher;
window.RoleRestricted      = RoleRestricted;
window.ExpedientePDFModal  = ExpedientePDFModal;
window.IC_ROLE_META           = IC_ROLE_META;
