// Login standalone · HCM Atica
// Único método de acceso: número de documento + contraseña. La recuperación
// se hace por código a un canal ya verificado en la cuenta (SMS, WhatsApp o
// correo) — nunca se pide teléfono/correo a mano ni se ofrece otro método.
const { useState: _lg_useState, useEffect: _lg_useEffect, useRef: _lg_useRef } = React;

// ─── Utilidades ────────────────────────────────────────────

// Quita puntos, espacios y guiones antes de comparar — así "42.221.087",
// "42 221 087" y "42221087" son el mismo documento.
const normalizeDoc = (s) => (s || '').replace(/[.\s-]/g, '').toUpperCase();

const maskPhone = (tel) => {
  const digits = (tel || '').replace(/\D/g, '');
  const last4 = digits.slice(-4) || '0000';
  return `••• ••• ${last4}`;
};
const maskEmail = (email) => {
  if (!email) return '';
  const [user, domain] = email.split('@');
  if (!domain) return email;
  return `${user[0]}•••••••@${domain}`;
};

const LOGIN_ERROR_GENERICO = 'No fue posible iniciar sesión. Verifica los datos ingresados e inténtalo nuevamente.';
const CODIGO_MOCK = '123456';
const CODIGO_VIGENCIA_MIN = 10;

// ─── Datos mock (solo para este prototipo — nunca visibles en la UI) ───────
// Mismas personas y documentos ya usados como referencia en Configuración →
// Usuarios y roles, para mantener coherencia entre módulos.
const AUTH_USERS_SEED = [
  {
    id: 'AUTH-1001', nombre: 'Carolina Restrepo Salazar', tipoDocumento: 'CC', documento: '42221087',
    password: 'AticaCali2026!', estado: 'activo',
    telefono: '+57 315 442 8801', telefonoVerificado: true, whatsappAutorizado: true,
    correo: 'carolina.restrepo@atica.co', correoVerificado: true,
  },
  {
    id: 'AUTH-1002', nombre: 'Paula Valencia Ríos', tipoDocumento: 'CC', documento: '1087665443',
    password: 'MantenimientoPV1', estado: 'activo',
    telefono: '+57 317 556 2290', telefonoVerificado: true, whatsappAutorizado: false,
    correo: null, correoVerificado: false,
  },
  {
    id: 'AUTH-1003', nombre: 'Jorge Iván Patiño', tipoDocumento: 'CC', documento: '75221487',
    password: 'RutaSegura2026', estado: 'activo',
    telefono: '+57 313 220 9987', telefonoVerificado: true, whatsappAutorizado: true,
    correo: null, correoVerificado: false,
  },
  {
    id: 'AUTH-1004', nombre: 'Andrés Felipe Mejía Cardona', tipoDocumento: 'CC', documento: '1087456231',
    password: 'OnboardingAM01', estado: 'pendiente',
    telefono: '+57 311 456 7821', telefonoVerificado: false, whatsappAutorizado: true,
    correo: null, correoVerificado: false,
  },
  {
    id: 'AUTH-1005', nombre: 'Fernando Henao', tipoDocumento: 'CC', documento: '16087443',
    password: 'ExColaborador9', estado: 'inactivo',
    telefono: '+57 300 221 7743', telefonoVerificado: true, whatsappAutorizado: false,
    correo: null, correoVerificado: false,
  },
  {
    id: 'AUTH-1006', nombre: 'Kevin Steven Guerrero Ibarra', tipoDocumento: 'CC', documento: '1094887210',
    password: 'NuevoIngreso2026', estado: 'activo',
    telefono: '+57 312 774 6690', telefonoVerificado: false, whatsappAutorizado: false,
    correo: null, correoVerificado: false,
  },
];

// ─── Iconos inline (mismo estilo que ya usaba este archivo — sin depender
// de components/icons.jsx, que esta entrada standalone no carga) ───────────

const IcoEnvelope = (p) => <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" {...p}><rect x="3" y="5" width="18" height="14" rx="2" /><path d="m3 7 9 6 9-6" /></svg>;
const IcoLock = (p) => <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" {...p}><rect x="4" y="11" width="16" height="10" rx="2" /><path d="M8 11V7a4 4 0 0 1 8 0v4" /></svg>;
const IcoEyeOpen = (p) => <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" {...p}><path d="M2 12s3-7 10-7 10 7 10 7-3 7-10 7-10-7-10-7z" /><circle cx="12" cy="12" r="3" /></svg>;
const IcoEyeClosed = (p) => <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" {...p}><path d="M2 12s3-7 10-7 10 7 10 7-3 7-10 7-10-7-10-7z" /><circle cx="12" cy="12" r="3" /><line x1="3" y1="3" x2="21" y2="21" /></svg>;
const IcoBack = (p) => <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.2" {...p}><path d="M15 18l-6-6 6-6" /></svg>;
const IcoWarn = (p) => <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" {...p}><path d="M12 9v4M12 17h.01" /><path d="M10.3 3.9 1.8 18a2 2 0 0 0 1.7 3h17a2 2 0 0 0 1.7-3L13.7 3.9a2 2 0 0 0-3.4 0Z" /></svg>;
const IcoCheckCircle = (p) => <svg width="34" height="34" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" {...p}><circle cx="12" cy="12" r="10" /><path d="m8 12 3 3 5-6" /></svg>;
const IcoSms = (p) => <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" {...p}><rect x="3" y="4" width="18" height="14" rx="2" /><path d="M7 8h10M7 12h6" /></svg>;
const IcoWhats = (p) => <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" {...p}><path d="M21 12a9 9 0 1 1-4.2-7.6L21 3l-1.1 4.3A9 9 0 0 1 21 12Z" /><path d="M8.5 9.5c.3 2.8 2.7 5.2 5.5 5.5" /></svg>;
const IcoMail = (p) => <IcoEnvelope width="16" height="16" {...p} />;
const IcoIdCard = (p) => <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" {...p}><rect x="2" y="5" width="20" height="14" rx="2" /><circle cx="8" cy="12" r="2" /><path d="M14 10h5M14 14h3" /></svg>;

// ─── Piezas reutilizables ───────────────────────────────────

const PasswordField = ({ label, value, onChange, autoComplete, placeholder, disabled, extra, error, hintId }) => {
  const [show, setShow] = _lg_useState(false);
  return (
    <label className="lg-field">
      <span className="lg-field-label">
        {label}
        {extra}
      </span>
      <div className={`lg-input-wrap ${value ? 'has-value' : ''} ${error ? 'has-error' : ''}`}>
        <span className="lg-input-icon"><IcoLock /></span>
        <input
          type={show ? 'text' : 'password'}
          value={value}
          onChange={onChange}
          placeholder={placeholder || 'Tu contraseña'}
          autoComplete={autoComplete}
          disabled={disabled}
          aria-invalid={!!error}
          aria-describedby={hintId}
        />
        <button
          type="button" className="lg-input-eye"
          onClick={() => setShow(s => !s)}
          aria-label={show ? 'Ocultar contraseña' : 'Mostrar contraseña'}
          aria-pressed={show}
        >
          {show ? <IcoEyeClosed /> : <IcoEyeOpen />}
        </button>
      </div>
    </label>
  );
};

const StepProgress = ({ step, total = 4 }) => (
  <div className="lg-progress" role="img" aria-label={`Paso ${step} de ${total}`}>
    <div className="lg-progress-track">
      {Array.from({ length: total }).map((_, i) => (
        <span key={i} className={`lg-progress-seg ${i < step ? 'done' : ''}`} />
      ))}
    </div>
    <span className="lg-progress-label">Paso {step} de {total}</span>
  </div>
);

const StepHeader = ({ onBack, backLabel = 'Volver al inicio de sesión' }) => (
  <button type="button" className="lg-step-back" onClick={onBack}>
    <IcoBack /> {backLabel}
  </button>
);

// Título de cada paso — recibe el foco al entrar al paso, para lectores de
// pantalla y navegación por teclado.
const StepTitle = ({ children, stepKey }) => {
  const ref = _lg_useRef(null);
  _lg_useEffect(() => { ref.current && ref.current.focus(); }, [stepKey]);
  return <h2 className="lg-form-h2" ref={ref} tabIndex={-1}>{children}</h2>;
};

const Alert = ({ children, tone = 'error' }) => (
  <div className={`lg-alert ${tone}`} role={tone === 'error' ? 'alert' : 'status'} aria-live={tone === 'error' ? 'assertive' : 'polite'}>
    {children ? (<>{tone === 'error' ? <IcoWarn /> : <IcoCheckCircle width={16} height={16} />} <span>{children}</span></>) : null}
  </div>
);

// ─── Formulario de login ─────────────────────────────────────

const LoginForm = ({ users, onSuccess, onForgot, initialDoc }) => {
  const [documento, setDocumento] = _lg_useState(initialDoc || '');
  const [password, setPassword] = _lg_useState('');
  const [stage, setStage] = _lg_useState('idle'); // idle | signing | redirecting
  const [error, setError] = _lg_useState('');

  const submit = (e) => {
    if (e) e.preventDefault();
    if (stage !== 'idle') return;
    setError('');
    const doc = normalizeDoc(documento);
    if (!doc || !password) { setError(LOGIN_ERROR_GENERICO); return; }
    setStage('signing');
    setTimeout(() => {
      const user = users.find(u => normalizeDoc(u.documento) === doc);
      const ok = user && user.estado === 'activo' && user.password === password;
      if (!ok) { setStage('idle'); setError(LOGIN_ERROR_GENERICO); return; }
      setStage('redirecting');
      setTimeout(() => onSuccess(), 650);
    }, 850);
  };

  return (
    <>
      <div className="lg-form-head">
        <h2 className="lg-form-h2">Inicia sesión</h2>
      </div>

      <form className="lg-form-body" onSubmit={submit} noValidate>
        <label className="lg-field">
          <span className="lg-field-label">Número de documento</span>
          <div className={`lg-input-wrap ${documento ? 'has-value' : ''}`}>
            <span className="lg-input-icon"><IcoIdCard /></span>
            <input
              type="text" inputMode="numeric" autoComplete="username"
              value={documento} onChange={(e) => setDocumento(e.target.value)}
              placeholder="Ingresa tu documento"
              disabled={stage !== 'idle'}
              aria-describedby="doc-hint"
            />
          </div>
          <span id="doc-hint" className="lg-field-hint">Tu usuario es el número de documento registrado en Atica</span>
        </label>

        <PasswordField
          label="Contraseña"
          value={password}
          onChange={(e) => setPassword(e.target.value)}
          autoComplete="current-password"
          disabled={stage !== 'idle'}
          extra={<button type="button" className="lg-link" onClick={onForgot}>¿Olvidaste tu contraseña?</button>}
        />

        <Alert>{error}</Alert>

        <button type="submit" className={`lg-submit ${stage !== 'idle' ? 'busy' : ''}`} disabled={stage !== 'idle'} aria-busy={stage !== 'idle'}>
          {stage === 'idle' && <>Iniciar sesión <span className="lg-submit-arrow">→</span></>}
          {stage === 'signing' && <><span className="lg-spinner" /> Verificando…</>}
          {stage === 'redirecting' && <><span className="lg-spinner" /> Cargando tu espacio…</>}
        </button>
      </form>
    </>
  );
};

// ─── Recuperación · Paso 1: identificar cuenta ───────────────

const RecoverStep1 = ({ documento, setDocumento, onBack, onFound, users }) => {
  const [loading, setLoading] = _lg_useState(false);
  const [error, setError] = _lg_useState('');

  const continuar = (e) => {
    if (e) e.preventDefault();
    if (loading) return;
    const doc = normalizeDoc(documento);
    if (!doc) { setError(LOGIN_ERROR_GENERICO); return; }
    setError('');
    setLoading(true);
    // Mismo tiempo de respuesta exista o no la cuenta — no delatar nada por timing.
    setTimeout(() => {
      setLoading(false);
      const user = users.find(u => normalizeDoc(u.documento) === doc);
      if (!user || user.estado !== 'activo') { setError(LOGIN_ERROR_GENERICO); return; }
      onFound(user);
    }, 800);
  };

  return (
    <>
      <StepHeader onBack={onBack} />
      <StepProgress step={1} />
      <StepTitle stepKey="1">Recupera tu contraseña</StepTitle>
      <p className="lg-form-sub">Ingresa tu número de documento para consultar los canales registrados en tu cuenta.</p>

      <form className="lg-form-body" onSubmit={continuar} noValidate>
        <label className="lg-field">
          <span className="lg-field-label">Número de documento</span>
          <div className={`lg-input-wrap ${documento ? 'has-value' : ''}`}>
            <span className="lg-input-icon"><IcoIdCard /></span>
            <input
              type="text" inputMode="numeric" autoComplete="username"
              value={documento} onChange={(e) => setDocumento(e.target.value)}
              placeholder="Ingresa tu documento"
              disabled={loading}
              aria-describedby="doc-hint-rec"
            />
          </div>
          <span id="doc-hint-rec" className="lg-field-hint">Usa el mismo número de documento con el que inicias sesión</span>
        </label>

        <Alert>{error}</Alert>

        <button type="submit" className={`lg-submit ${loading ? 'busy' : ''}`} disabled={loading} aria-busy={loading}>
          {loading ? <><span className="lg-spinner" /> Consultando…</> : 'Continuar'}
        </button>
      </form>
    </>
  );
};

// ─── Recuperación · Paso 2: elegir canal ─────────────────────

const CANAL_META = {
  sms: { label: 'SMS', icon: IcoSms },
  whatsapp: { label: 'WhatsApp', icon: IcoWhats },
  correo: { label: 'Correo', icon: IcoMail },
};

const RecoverStep2 = ({ cuenta, onBack, onSend }) => {
  const [canal, setCanal] = _lg_useState(null);
  const [enviando, setEnviando] = _lg_useState(false);

  const smsHabilitado = !!cuenta.telefono && cuenta.telefonoVerificado;
  const smsExiste = !!cuenta.telefono;
  const waHabilitado = smsHabilitado && cuenta.whatsappAutorizado;
  const waExiste = !!cuenta.telefono;
  const correoHabilitado = !!cuenta.correo && cuenta.correoVerificado;
  const correoExiste = !!cuenta.correo;

  const opciones = [
    smsExiste && { id: 'sms', habilitado: smsHabilitado, texto: `Mensaje de texto al ${maskPhone(cuenta.telefono)}`, motivo: !smsHabilitado ? 'Teléfono pendiente de verificación — comunícate con Gestión Humana' : '' },
    waExiste && { id: 'whatsapp', habilitado: waHabilitado, texto: `WhatsApp al ${maskPhone(cuenta.telefono)}`, motivo: !waHabilitado ? (!smsHabilitado ? 'Teléfono pendiente de verificación' : 'WhatsApp no autorizado — comunícate con Gestión Humana') : '' },
    correoExiste && { id: 'correo', habilitado: correoHabilitado, texto: `Correo a ${maskEmail(cuenta.correo)}`, motivo: !correoHabilitado ? 'Correo pendiente de verificación — comunícate con Gestión Humana' : '' },
  ].filter(Boolean);

  const hayHabilitados = opciones.some(o => o.habilitado);

  const enviar = () => {
    if (!canal || enviando) return;
    setEnviando(true);
    setTimeout(() => onSend(canal), 700);
  };

  return (
    <>
      <StepHeader onBack={onBack} backLabel="Atrás" />
      <StepProgress step={2} />
      <StepTitle stepKey="2">¿Dónde quieres recibir el código?</StepTitle>

      {!hayHabilitados ? (
        <Alert>No fue posible completar la recuperación por este medio. Comunícate con Gestión Humana.</Alert>
      ) : (
        <p className="lg-form-sub">Selecciona un canal registrado y verificado en tu cuenta.</p>
      )}

      <div className="range-list" role="radiogroup" aria-label="Canal de recuperación">
        {opciones.map(o => {
          const meta = CANAL_META[o.id];
          const Ico = meta.icon;
          return (
            <label key={o.id} className={`range-row ${!o.habilitado ? 'disabled' : ''} ${canal === o.id ? 'active' : ''}`}>
              <input
                type="radio" name="lg-canal" disabled={!o.habilitado}
                checked={canal === o.id} onChange={() => setCanal(o.id)}
              />
              <div style={{ display: 'flex', alignItems: 'flex-start', gap: 10, flex: 1 }}>
                <span className="lg-canal-ico"><Ico /></span>
                <div>
                  <div style={{ fontSize: 13, fontWeight: 600 }}>{meta.label}</div>
                  <div className="muted" style={{ fontSize: 11.5, marginTop: 1 }}>{o.habilitado ? o.texto : o.motivo}</div>
                </div>
              </div>
            </label>
          );
        })}
      </div>

      {hayHabilitados && (
        <button type="button" className={`lg-submit ${enviando ? 'busy' : ''}`} disabled={!canal || enviando} onClick={enviar} aria-busy={enviando} style={{ marginTop: 6 }}>
          {enviando ? <><span className="lg-spinner" /> Enviando…</> : 'Enviar código'}
        </button>
      )}
    </>
  );
};

// ─── Recuperación · Paso 3: verificar código ─────────────────

const RecoverStep3 = ({ cuenta, canal, desafio, onNuevoDesafio, onBack, onVerified }) => {
  const [codigo, setCodigo] = _lg_useState('');
  const [error, setError] = _lg_useState('');
  const [envio, setEnvio] = _lg_useState('enviado'); // enviando | enviado | fallido
  const [cooldown, setCooldown] = _lg_useState(60);

  _lg_useEffect(() => {
    if (cooldown <= 0) return;
    const t = setTimeout(() => setCooldown(c => Math.max(0, c - 8)), 500);
    return () => clearTimeout(t);
  }, [cooldown]);

  const meta = CANAL_META[canal];
  const destino = canal === 'correo' ? maskEmail(cuenta.correo) : maskPhone(cuenta.telefono);

  const verificar = (e) => {
    if (e) e.preventDefault();
    if (!desafio) return;
    if (desafio.usado || Date.now() > desafio.expiraEn) {
      setError('Este código ya venció. Solicita uno nuevo para continuar.');
      return;
    }
    if (codigo !== desafio.codigo) {
      setError('El código ingresado no es válido. Verifícalo e inténtalo nuevamente.');
      return;
    }
    setError('');
    onVerified();
  };

  const reenviar = () => {
    if (cooldown > 0 || envio === 'enviando') return;
    setEnvio('enviando');
    setError('');
    setTimeout(() => {
      // Simula una falla de entrega ocasional — no consume intento ni
      // aplica el tiempo de espera, para permitir reintentar de inmediato.
      if (Math.random() < 0.15) { setEnvio('fallido'); return; }
      setCodigo('');
      setEnvio('enviado');
      setCooldown(60);
      onNuevoDesafio(canal);
    }, 700);
  };

  return (
    <>
      <StepHeader onBack={onBack} backLabel="Atrás" />
      <StepProgress step={3} />
      <StepTitle stepKey="3">Ingresa el código</StepTitle>
      <p className="lg-form-sub">
        Te enviamos un código por <b>{meta.label}</b> a <b>{destino}</b>. Es válido durante {CODIGO_VIGENCIA_MIN} minutos y solo puede usarse una vez.
      </p>

      <form className="lg-form-body" onSubmit={verificar} noValidate>
        <label className="lg-field">
          <span className="lg-field-label">Código de 6 dígitos</span>
          <input
            className="lg-otp-input"
            type="text" inputMode="numeric" autoComplete="one-time-code"
            maxLength={6}
            value={codigo}
            onChange={(e) => setCodigo(e.target.value.replace(/\D/g, '').slice(0, 6))}
            placeholder="······"
            aria-describedby="otp-hint"
          />
          <span id="otp-hint" className="lg-field-hint">Revisa tu {meta.label.toLowerCase()} — el código expira {CODIGO_VIGENCIA_MIN} minutos después del envío</span>
        </label>

        <Alert>{error}</Alert>
        {envio === 'fallido' && <Alert>No fue posible enviar el código. Intenta de nuevo.</Alert>}
        {envio === 'enviado' && !error && <Alert tone="status">Código enviado.</Alert>}

        <button type="submit" className="lg-submit" disabled={codigo.length !== 6}>Verificar código</button>
      </form>

      <div className="lg-otp-actions">
        <button type="button" className="lg-link" disabled={cooldown > 0 || envio === 'enviando'} onClick={reenviar}>
          {envio === 'enviando' ? 'Enviando…' : cooldown > 0 ? `Podrás reenviar en ${cooldown} segundos` : 'Reenviar código'}
        </button>
        <button type="button" className="lg-link" onClick={onBack}>Usar otro canal</button>
      </div>
    </>
  );
};

// ─── Recuperación · Paso 4: crear contraseña ─────────────────

const RecoverStep4 = ({ cuenta, onDone }) => {
  const [nueva, setNueva] = _lg_useState('');
  const [confirmar, setConfirmar] = _lg_useState('');

  const cumpleLongitud = nueva.trim().length >= 15;
  const coincide = nueva.length > 0 && nueva === confirmar;
  const esDiferente = nueva.length > 0 && nueva !== cuenta.password;

  const errorConfirmar = confirmar.length > 0 && !coincide ? 'Las contraseñas no coinciden.' : '';
  const errorIgual = nueva.length > 0 && cumpleLongitud && !esDiferente ? 'La nueva contraseña debe ser diferente de la anterior.' : '';

  const puedeGuardar = cumpleLongitud && coincide && esDiferente;

  const guardar = (e) => {
    if (e) e.preventDefault();
    if (!puedeGuardar) return;
    onDone(nueva);
  };

  return (
    <>
      <StepProgress step={4} />
      <StepTitle stepKey="4">Crea una nueva contraseña</StepTitle>
      <p className="lg-form-sub">Puedes usar una frase larga que sea fácil de recordar y difícil de adivinar.</p>

      <form className="lg-form-body" onSubmit={guardar} noValidate>
        <PasswordField
          label="Nueva contraseña" value={nueva}
          onChange={(e) => setNueva(e.target.value)}
          autoComplete="new-password" placeholder="Mínimo 15 caracteres"
          hintId="req-hint"
        />
        <div id="req-hint" className={`lg-req ${cumpleLongitud ? 'ok' : ''}`}>
          <span className="lg-req-dot" aria-hidden="true">{cumpleLongitud ? '✓' : '•'}</span> Mínimo 15 caracteres
        </div>
        {errorIgual && <Alert>{errorIgual}</Alert>}

        <PasswordField
          label="Confirmar contraseña" value={confirmar}
          onChange={(e) => setConfirmar(e.target.value)}
          autoComplete="new-password" placeholder="Repite la nueva contraseña"
          error={!!errorConfirmar}
        />
        {errorConfirmar && <Alert>{errorConfirmar}</Alert>}

        <button type="submit" className="lg-submit" disabled={!puedeGuardar}>Actualizar contraseña</button>
      </form>
    </>
  );
};

// ─── Recuperación · confirmación final ───────────────────────

const RecoverSuccess = ({ onDone }) => (
  <div className="lg-success">
    <div className="lg-success-ico"><IcoCheckCircle /></div>
    <StepTitle stepKey="success">Tu contraseña fue actualizada</StepTitle>
    <p className="lg-form-sub" style={{ textAlign: 'center' }}>Ya puedes ingresar a HCM Atica con tu nueva contraseña.</p>
    <button type="button" className="lg-submit" onClick={onDone}>Volver al inicio de sesión</button>
  </div>
);

// ─── Orquestador de recuperación ─────────────────────────────

const RecoverFlow = ({ users, initialDoc, onExit, onPasswordUpdated }) => {
  const [step, setStep] = _lg_useState(1);
  const [documento, setDocumento] = _lg_useState(initialDoc || '');
  const [cuenta, setCuenta] = _lg_useState(null);
  const [canal, setCanal] = _lg_useState(null);
  const [desafio, setDesafio] = _lg_useState(null);

  const crearDesafio = (canalElegido) => {
    setCanal(canalElegido);
    setDesafio({
      codigo: CODIGO_MOCK,
      creadoEn: Date.now(),
      expiraEn: Date.now() + CODIGO_VIGENCIA_MIN * 60 * 1000,
      usado: false,
    });
  };

  if (step === 1) {
    return (
      <RecoverStep1
        documento={documento} setDocumento={setDocumento}
        onBack={() => onExit()} users={users}
        onFound={(u) => { setCuenta(u); setStep(2); }}
      />
    );
  }
  if (step === 2) {
    return (
      <RecoverStep2
        cuenta={cuenta}
        onBack={() => setStep(1)}
        onSend={(canalElegido) => { crearDesafio(canalElegido); setStep(3); }}
      />
    );
  }
  if (step === 3) {
    return (
      <RecoverStep3
        cuenta={cuenta} canal={canal} desafio={desafio}
        onNuevoDesafio={crearDesafio}
        onBack={() => setStep(2)}
        onVerified={() => { setDesafio(d => d ? { ...d, usado: true } : d); setStep(4); }}
      />
    );
  }
  if (step === 4) {
    return (
      <RecoverStep4
        cuenta={cuenta}
        onDone={(nuevaPassword) => { onPasswordUpdated(cuenta.id, nuevaPassword); setStep('success'); }}
      />
    );
  }
  return <RecoverSuccess onDone={() => onExit(cuenta.documento)} />;
};

// ─── Panel de marca ───────────────────────────────────────────

const BrandPanel = () => (
  <aside className="lg-brand">
    <div className="lg-brand-bg" aria-hidden />
    <div className="lg-brand-center">
      <div className="lg-atica-logo">
        <AticaMark size={56} tri="#FFFFFF" leaf="var(--sky-500)" />
        <span className="lg-atica-word">atica</span>
      </div>
      <div className="lg-brand-tagline">
        <h1 className="lg-brand-h1">Bienvenido a tu espacio en Atica</h1>
        <p className="lg-brand-phrase">Ingenio que transforma</p>
      </div>
    </div>
  </aside>
);

// ─── Raíz ────────────────────────────────────────────────────

const Login = () => {
  const [users, setUsers] = _lg_useState(AUTH_USERS_SEED);
  const [view, setView] = _lg_useState('login'); // login | recover
  const [prefillDoc, setPrefillDoc] = _lg_useState('');

  const handlePasswordUpdated = (userId, nuevaPassword) => {
    setUsers(list => list.map(u => u.id === userId ? { ...u, password: nuevaPassword } : u));
  };

  const exitRecover = (docParaAyuda) => {
    setPrefillDoc(typeof docParaAyuda === 'string' ? docParaAyuda : '');
    setView('login');
  };

  return (
    <div className="lg-page">
      <BrandPanel />
      <main className="lg-form">
        <div className="lg-form-inner">
          {view === 'login' ? (
            <LoginForm
              users={users}
              initialDoc={prefillDoc}
              onSuccess={() => { window.location.href = 'HCM Atica Dashboard v2.html'; }}
              onForgot={() => setView('recover')}
            />
          ) : (
            <RecoverFlow
              users={users}
              initialDoc={prefillDoc}
              onExit={exitRecover}
              onPasswordUpdated={handlePasswordUpdated}
            />
          )}
        </div>
      </main>
    </div>
  );
};

window.Login = Login;
