













(function () {
  window.CR = window.CR || {};
  window.CR.screens = window.CR.screens || {};
  var React = window.React;
  var h = React.createElement;
  var useState = React.useState;
  var useEffect = React.useEffect;

  var MINIMO = 12;





  var ROLES = [];
  var nombreDeRol = function (clave) {
    for (var i = 0; i < ROLES.length; i++) if (ROLES[i].clave === clave) return ROLES[i].nombre;
    return clave || '—';
  };

  function fecha(valor) {
    if (!valor) return 'nunca';
    try { return new Date(valor).toLocaleDateString('es-AR', { day: '2-digit', month: '2-digit', year: 'numeric' }); }
    catch (_) { return String(valor).slice(0, 10); }
  }

  function Usuarios(props) {
    var listaState = useState(null); var lista = listaState[0], setLista = listaState[1];
    var errorState = useState(''); var error = errorState[0], setError = errorState[1];
    var okState = useState(''); var ok = okState[0], setOk = okState[1];
    var ocupadoState = useState(''); var ocupado = ocupadoState[0], setOcupado = ocupadoState[1];
    var altaState = useState(false); var alta = altaState[0], setAlta = altaState[1];

    var yo = (props.session && props.session.usuario && props.session.usuario.id) || null;

    function refrescar() {
      return window.CR.backend.usuarios()
        .then(function (u) { setLista(u); setError(''); })
        .catch(function (e) { setError((e && e.message) || 'No pude traer los usuarios.'); setLista([]); });
    }
    /* El catalogo se pide una sola vez y se guarda en el modulo, porque `nombreDeRol` lo usa desde
       afuera del componente. `setRoles` existe SOLO para forzar el re-render: sin el, ROLES se
       llena despues de dibujar y el desplegable queda vacio hasta que algo mas cambie — el mismo
       tipo de bug que la cola de ACKs plegada. */
    var rolesState = useState(ROLES); var setRoles = rolesState[1];
    useEffect(function () {
      refrescar();
      window.CR.backend.rolesCatalogo()
        .then(function (rs) { ROLES = rs || []; setRoles(ROLES); })
        .catch(function (e) {
          ROLES = []; setRoles([]);
          setError((e && e.message) || 'No pude traer los roles: no se pueden asignar hasta que el servidor responda.');
        });
    }, []);

    // Un solo camino para toda acción: deja el aviso, refresca, y NUNCA deja el botón trabado.
    function accion(id, etiqueta, promesa, exito) {
      setOcupado(id + ':' + etiqueta); setError(''); setOk('');
      promesa.then(function () { return refrescar(); })
        .then(function () { setOk(exito); })
        .catch(function (e) { setError((e && e.message) || 'No pude completarlo.'); })
        .finally(function () { setOcupado(''); });
    }

    function cambiarRol(u, clave) {
      if (clave === u.rol) return;
      accion(u.id, 'rol', window.CR.backend.cambiarRolUsuario(u.id, [clave]),
        u.nombre + ' ahora es ' + nombreDeRol(clave) + '.');
    }

    function alternarActivo(u) {
      var texto = u.activo
        ? 'Vas a desactivar a ' + u.nombre + '. Se le cierran las sesiones abiertas y no va a poder entrar hasta que lo reactives. ¿Seguimos?'
        : 'Vas a reactivar a ' + u.nombre + ', que va a poder entrar de nuevo con su contraseña. ¿Seguimos?';
      if (!window.confirm(texto)) return;
      accion(u.id, 'activo', window.CR.backend.activarUsuario(u.id, !u.activo),
        u.nombre + (u.activo ? ' quedó desactivado.' : ' quedó activo de nuevo.'));
    }

    function resetear(u) {
      var provisoria = window.prompt(
        'Contraseña provisoria para ' + u.nombre + ' (mínimo ' + MINIMO + ' caracteres).\n\n'
        + 'Se la tenés que pasar por un canal aparte. Al entrar, el sistema le va a exigir cambiarla.');
      if (provisoria === null) return;
      if (String(provisoria).length < MINIMO) { setError('La provisoria necesita al menos ' + MINIMO + ' caracteres.'); return; }
      accion(u.id, 'reset', window.CR.backend.resetearPasswordUsuario(u.id, provisoria),
        'Listo. Pasale la provisoria a ' + u.nombre + ' por un canal aparte: al entrar tiene que cambiarla.');
    }

    if (lista === null) return h('div', { className: 'card', style: { margin: 24 } }, h('p', { className: 'muted' }, 'Cargando usuarios…'));

    var conClaveProvisoria = lista.filter(function (u) { return u.activo && u.mustChangePassword; }).length;

    return h('section', { className: 'screen' },
      h('header', { className: 'screen-head' },
        h('h2', null, 'Usuarios'),
        h('p', { className: 'muted' }, 'Quién entra al sistema y qué puede hacer. Sólo lo ve y lo cambia un gerente de logística.')),

      error ? h('div', { className: 'alerta alerta--alta', role: 'alert' }, error) : null,
      ok ? h('div', { className: 'alerta alerta--ok', role: 'status' }, ok) : null,

      conClaveProvisoria
        ? h('div', { className: 'alerta alerta--media' },
          conClaveProvisoria === 1
            ? 'Hay 1 usuario activo que todavía no cambió la contraseña provisoria con la que se creó.'
            : 'Hay ' + conClaveProvisoria + ' usuarios activos que todavía no cambiaron la contraseña provisoria con la que se crearon.')
        : null,

      h('div', { className: 'card' },
        h('table', { className: 'tabla' },
          h('thead', null, h('tr', null,
            h('th', null, 'Nombre'), h('th', null, 'Email'), h('th', null, 'Rol'),
            h('th', null, 'Estado'), h('th', null, 'Último acceso'), h('th', null, 'Acciones'))),
          h('tbody', null, lista.map(function (u) {
            var esYo = u.id === yo;
            var trabajando = ocupado.indexOf(u.id + ':') === 0;
            return h('tr', { key: u.id, className: u.activo ? '' : 'fila--inactiva' },
              h('td', null, u.nombre, esYo ? h('span', { className: 'chip', style: { marginLeft: 6 } }, 'vos') : null),
              h('td', null, u.email),
              // El propio gerente NO se cambia el rol: con una flecha del teclado sobre el
              // desplegable perderia esta pantalla en el acto, sin confirmacion y sin poder
              // revertirlo. El servidor lo rechaza igual; aca ademas se dice por que.
              h('td', null, h('select', {
                className: 'input', value: u.rol, disabled: trabajando || !u.activo || esYo,
                title: esYo ? 'No podés cambiarte el rol a vos mismo: perderías el acceso a esta pantalla.' : '',
                onChange: function (e) { cambiarRol(u, e.target.value); }
              }, ROLES.map(function (r) { return h('option', { key: r.clave, value: r.clave }, r.nombre); }))),
              h('td', null,
                u.activo ? h('span', { className: 'chip chip--ok' }, 'Activo') : h('span', { className: 'chip' }, 'Desactivado'),
                u.activo && u.mustChangePassword
                  ? h('span', { className: 'chip chip--warn', style: { marginLeft: 6 }, title: 'Todavía usa la contraseña provisoria con la que se creó' }, 'provisoria')
                  : null),
              h('td', null, fecha(u.ultimoAcceso)),
              h('td', null,
                h('button', {
                  className: 'btn', disabled: trabajando || !u.activo,
                  onClick: function () { resetear(u); },
                  // El propio gerente NO se resetea por acá: ese camino no pide la actual. El servidor
                  // lo rechaza igual; acá se dice POR QUE, que es lo que evita el ticket.
                  title: esYo ? 'Para la tuya usá "Cambiar mi contraseña": ese camino pide la actual.' : 'Le pone una contraseña provisoria'
                }, 'Resetear contraseña'),
                h('button', {
                  className: 'btn', style: { marginLeft: 6 }, disabled: trabajando || (esYo && u.activo),
                  onClick: function () { alternarActivo(u); },
                  title: esYo && u.activo ? 'No podés desactivarte a vos mismo: te quedarías afuera sin poder revertirlo.' : ''
                }, u.activo ? 'Desactivar' : 'Reactivar')));
          })))),

      h('div', { style: { marginTop: 16 } },
        alta
          ? h(AltaUsuario, {
            onCancelar: function () { setAlta(false); },
            onCreado: function (nombre) { setAlta(false); setOk('Usuario creado: ' + nombre + '. Pasale la contraseña provisoria por un canal aparte.'); refrescar(); },
            onError: function (m) { setError(m); }
          })
          : h('button', { className: 'btn btn--primary', onClick: function () { setAlta(true); setOk(''); setError(''); } }, '+ Nuevo usuario')),

      h('div', { className: 'card', style: { marginTop: 16 } },
        h('h3', null, 'Qué puede cada rol'),
        h('ul', { className: 'lista' }, ROLES.map(function (r) {
          return h('li', { key: r.clave }, h('strong', null, r.nombre), ' — ', r.detalle);
        })),
        h('p', { className: 'muted' },
          'Siempre tiene que quedar al menos un gerente de logística activo: si no, nadie podría volver a entrar '
          + 'a administrar usuarios. El sistema no te va a dejar quitar el último.')));
  }

  function AltaUsuario(props) {
    var nombreState = useState(''); var nombre = nombreState[0], setNombre = nombreState[1];
    var emailState = useState(''); var email = emailState[0], setEmail = emailState[1];
    var claveState = useState(''); var clave = claveState[0], setClave = claveState[1];
    var rolState = useState('planificador'); var rol = rolState[0], setRol = rolState[1];
    var busyState = useState(false); var busy = busyState[0], setBusy = busyState[1];

    var puede = !busy && nombre.trim() && email.trim() && clave.length >= MINIMO;

    function submit(e) {
      e.preventDefault();
      if (!puede) return;
      setBusy(true);
      window.CR.backend.crearUsuario({ nombre: nombre.trim(), email: email.trim(), password: clave, roles: [rol] })
        .then(function () { props.onCreado(nombre.trim()); })
        .catch(function (err) { props.onError((err && err.message) || 'No pude crear el usuario.'); })
        .finally(function () { setBusy(false); });
    }

    return h('form', { className: 'card', onSubmit: submit },
      h('h3', null, 'Nuevo usuario'),
      h('label', null, h('span', null, 'Nombre y apellido'),
        h('input', { className: 'input', required: true, value: nombre, onChange: function (e) { setNombre(e.target.value); } })),
      h('label', null, h('span', null, 'Email'),
        h('input', { className: 'input', type: 'email', required: true, value: email, onChange: function (e) { setEmail(e.target.value); } })),
      h('label', null, h('span', null, 'Contraseña provisoria'),
        h('input', {
          className: 'input', type: 'password', autoComplete: 'new-password', required: true, minLength: MINIMO,
          value: clave, onChange: function (e) { setClave(e.target.value); }
        })),
      h('p', { className: 'muted' },
        'Mínimo ' + MINIMO + ' caracteres. Se la pasás por un canal aparte y al entrar el sistema le va a exigir cambiarla.'),
      h('label', null, h('span', null, 'Rol'),
        h('select', { className: 'input', value: rol, onChange: function (e) { setRol(e.target.value); } },
          ROLES.map(function (r) { return h('option', { key: r.clave, value: r.clave }, r.nombre); }))),
      h('p', { className: 'muted' }, (function () {
        for (var i = 0; i < ROLES.length; i++) if (ROLES[i].clave === rol) return ROLES[i].detalle;
        return '';
      })()),
      h('div', { style: { marginTop: 12 } },
        h('button', { className: 'btn btn--primary', type: 'submit', disabled: !puede }, busy ? 'Creando…' : 'Crear usuario'),
        h('button', { className: 'btn', type: 'button', style: { marginLeft: 8 }, onClick: props.onCancelar }, 'Cancelar')));
  }

  window.CR.screens.Usuarios = Usuarios;
})();
