/* onboarding-grupos.jsx — onboarding gerente-only contra la API real. */
(function () {
  var React = window.React, h = React.createElement, ui = window.CR.ui;
  var useEffect = React.useEffect, useState = React.useState;
  function estado(g) { return g.activo ? 'activo' : (g.vinculado || g.jid ? 'vinculado' : 'sin-vincular'); }
  function estadoBadge(g) {
    var meta = { activo: ['ok', 'Activo'], vinculado: ['warn', 'Vinculado · inactivo'], 'sin-vincular': ['neutral', 'Sin vincular'] }[estado(g)];
    return h(ui.Badge, { color: meta[0] }, meta[1]);
  }
  function esResiduo(g) { return g.sinChoferes === true || Number(g.cantidadChoferes || 0) === 0; }



  var SIN_FILTRO_G = { grupo: '', estado: '', choferes: '', tipo: '', duenos: '' };
  var ETIQUETA_G = { grupo: 'Grupo', estado: 'Estado', choferes: 'Choferes', tipo: 'Tipo', duenos: 'Due\u00f1os' };

  function valorGrupo(campo, g) {
    if (campo === 'estado') {
      return { activo: 'Activo', vinculado: 'Vinculado \u00b7 inactivo', 'sin-vincular': 'Sin vincular' }[estado(g)];
    }
    // por CORTES y no por numero exacto: filtrar "7 choferes" no le sirve a nadie; encontrar los
    // residuos (0) y los particulares de uno solo, si.
    if (campo === 'choferes') {
      var n = Number(g.cantidadChoferes || 0);
      return n === 0 ? 'Sin choferes' : (n === 1 ? '1 chofer' : '2 o m\u00e1s');
    }
    if (campo === 'tipo') return g.tipo === 'agencia' ? 'Agencia' : 'Particular';
    if (campo === 'duenos') {
      if ((g.duenos || []).length) return 'Con due\u00f1o';
      return g.tipo === 'agencia' ? 'Pendiente' : 'No requiere';
    }
    return '';
  }

  // El grupo se busca por TEXTO (nombre o jid), no por igualdad: son ~119 y lo que se quiere es
  // encontrar uno, no elegirlo de una lista.
  function pasaFiltroGrupo(g, filtro, salvo) {
    if (salvo !== 'grupo' && filtro.grupo) {
      var q = filtro.grupo.trim().toLowerCase();
      var heno = (String(g.nombre || '') + ' ' + String(g.jid || '')).toLowerCase();
      if (heno.indexOf(q) < 0) return false;
    }
    return ['estado', 'choferes', 'tipo', 'duenos'].every(function (k) {
      if (k === salvo || !filtro[k]) return true;
      return valorGrupo(k, g) === filtro[k];
    });
  }

  function ordenarGrupos(a, b) {
    return Number(esResiduo(a)) - Number(esResiduo(b)) ||
      (b.cantidadChoferes || 0) - (a.cantidadChoferes || 0) ||
      String(a.nombre || '').localeCompare(String(b.nombre || ''));
  }
  function mensajeError(e) {
    var m = String(e && e.message || e || '');
    return ({ segundo_actor_requerido: 'La aprobación debe hacerla otro gerente.', jid_ya_vinculado: 'Ese JID ya está vinculado a otro grupo.',
      grupo_ya_vinculado_a_otro_jid: 'Ese grupo de la base ya está vinculado a otro grupo de WhatsApp. Desvinculalo primero o elegí otro candidato.',
      aprobacion_expirada: 'La propuesta venció. Generá una nueva.', aprobacion_ya_usada: 'Esta propuesta ya fue aprobada.' })[m] || m;
  }
  function scoreCandidato(c) {
    var valor = c && (c.score === undefined ? c.similitud : c.score);
    var numero = Number(valor);
    if (!isFinite(numero)) return 'Sin score';
    return (numero <= 1 ? Math.round(numero * 100) : Math.round(numero)) + '% match';
  }
  function OnboardingGrupos(props) {
    var ds = useState(null), data = ds[0], setData = ds[1];
    var ss = useState({}), selected = ss[0], setSelected = ss[1];
    var bs = useState(true), busy = bs[0], setBusy = bs[1];
    var es = useState(''), error = es[0], setError = es[1];
    var ms = useState(''), mensaje = ms[0], setMensaje = ms[1];
    var zs = useState(''), zona = zs[0], setZona = zs[1];
    var as = useState(false), verArchivados = as[0], setVerArchivados = as[1];
    // Propuestas vivas traidas del backend. Antes la segunda llave era inaplicable: los tokens
    // vivian SOLO en el navegador del que proponia (useState), asi que el segundo gerente
    // abria la pantalla y no veia ningun boton para aprobar.
    var qs = useState([]), pendientes = qs[0], setPendientes = qs[1];
    var vs = useState(null), previa = vs[0], setPrevia = vs[1];
    function cargarPendientes() {
      if (!window.CR.backend.aprobacionesPendientes) return Promise.resolve();
      return window.CR.backend.aprobacionesPendientes()
        .then(setPendientes).catch(function () { /* no romper la pantalla por esto */ });
    }
    function cargar() {
      setBusy(true); setError('');
      return window.CR.backend.descubrirGrupos().then(function (j) {
        j.grupos = (j.grupos || []).slice().sort(ordenarGrupos);
        j.archivados = (j.archivados || j.gruposArchivados || []).slice().sort(ordenarGrupos);
        setData(j);
      }).catch(function (e) { setError(mensajeError(e)); })
        .then(cargarPendientes).then(function () { setBusy(false); });
    }
    useEffect(function () { cargar(); }, []);
    var incs = useState(null), incorporando = incs[0], setIncorporando = incs[1];
    var ags = useState([]), agenciasLista = ags[0], setAgenciasLista = ags[1];
    // la lista de agencias se pide recien al abrir el modal: en esta pantalla no hace falta antes
    function abrirIncorporar(g) {
      setIncorporando({ jid: g.jid, nombre: g.nombre || '', tipo: 'particular', agencia: '' });
      if (!agenciasLista.length && window.CR.backend.agencias) {
        window.CR.backend.agencias().then(function (xs) {
          setAgenciasLista((xs || []).map(function (a) { return a.nombre; }).filter(Boolean));
        }).catch(function () {});
      }
    }
    function incorporar() {
      var p = incorporando;
      // correr() pone un mensaje FIJO al terminar; el conteo real de choferes vinculados se agrega
      // encadenando antes de entregarle la promesa
      correr(window.CR.backend.incorporarGrupo({
        jid: p.jid, nombre: (p.nombre || '').trim(), tipo: p.tipo,
        agencia: p.tipo === 'agencia' && p.agencia ? p.agencia : null
      }).then(function (r) {
        setIncorporando(null);
        if (r && r.choferesVinculados) {
          setMensaje('Grupo incorporado con ' + r.choferesVinculados + ' chofer(es) de la agencia. Nace INACTIVO: activalo desde este tablero.');
        }
      }), 'Grupo incorporado. Nace INACTIVO: activalo desde este tablero cuando corresponda.');
    }
    function aprobarPendientes(ids, firmaUnica) {
      correr(window.CR.backend.activarGruposLote(firmaUnica
        ? { aprobaciones: ids, firmaUnica: true, confirmado: true }
        : { aprobaciones: ids }), ids.length + ' grupo(s) activados.');
    }
    // Firma única: como no hay segunda persona mirando, el operador tiene que leer una previa
    // que dice exactamente qué va a pasar antes de confirmar. Ese es el checkpoint.
    function abrirPrevia(p) {
      setError(''); setBusy(true);
      window.CR.backend.previaActivacion(p.aprobacionId)
        .then(function (j) { setPrevia(j); setBusy(false); })
        .catch(function (e) { setError(mensajeError(e)); setBusy(false); });
    }
    function confirmarFirmaUnica() {
      var id = previa.aprobacionId; setPrevia(null);
      aprobarPendientes([id], true);
    }
    /* ---- CHOFERES DE UN GRUPO (v0.68.0) ---------------------------------------------------------
       Un particular nacia sin choferes y esta pantalla no tenia forma de sumarle uno: "Incorporar"
       cuelga choferes solo por agencia. Medido el 01/09: 9 particulares activos sin chofer, o sea
       9 grupos cuyas rutas no se notificaban a nadie — y se le habia dicho al cliente que su equipo
       podia vincularlos desde aca.
       Regla del cliente (01/09): un particular PUEDE tener mas de un chofer, "no siempre, pero
       eventualmente algunos grupos si". Por eso el boton no se apaga con el primero.
       Lo que SI se dice antes de confirmar: si el chofer ya esta en otro grupo activo, sus rutas
       pasan a notificarse en este, porque manda el vinculo mas reciente. */
    var chs = useState(null), choferesModal = chs[0], setChoferesModal = chs[1];
    function nombresDe(xs) { return (xs || []).map(function (o) { return o.nombre; }).join(', '); }
    function otrosActivos(c) { return (c && c.otrosGrupos || []).filter(function (o) { return o.activo; }); }
    function recargarChoferes(g) {
      return window.CR.backend.choferesDeGrupo(g.id).then(function (j) {
        setChoferesModal(function (m) {
          return Object.assign({}, m || {}, { grupo: j.grupo || g, miembros: j.miembros || [], candidatos: j.candidatos || [], cargando: false, elegido: '' });
        });
      }).catch(function (e) {
        setChoferesModal(function (m) { return Object.assign({}, m || {}, { cargando: false, error: mensajeError(e) }); });
      });
    }
    function abrirChoferes(g) {
      setChoferesModal({ grupo: g, miembros: [], candidatos: [], elegido: '', cargando: true, error: '' });
      recargarChoferes(g);
    }
    function vincularChofer() {
      var m = choferesModal; if (!m || !m.elegido) return;
      var cand = m.candidatos.filter(function (c) { return c.id === m.elegido; })[0];
      if (!cand) return;
      var activos = otrosActivos(cand);
      // La consecuencia se confirma, no se descubre: las rutas de este chofer dejan de notificarse
      // en el grupo donde estaba.
      if (activos.length && !window.confirm('"' + cand.nombre + '" ya está en ' + nombresDe(activos) + '.\n\n' +
        'Sus rutas se notifican en el grupo activo con el vínculo más reciente: al vincularlo acá, pasan a "' +
        m.grupo.nombre + '" y dejan de llegar a ' + nombresDe(activos) + '. ¿Seguir?')) return;
      setChoferesModal(Object.assign({}, m, { cargando: true, error: '' }));
      window.CR.backend.vincularChoferAGrupo(m.grupo.id, cand.id).then(function (r) {
        var nombre = (r && r.choferNombre) || cand.nombre;
        setMensaje(r && r.idempotente
          ? '"' + nombre + '" ya estaba en "' + m.grupo.nombre + '".'
          : '"' + nombre + '" quedó vinculado a "' + m.grupo.nombre + '" (' + Number(r && r.cantidadChoferes || 0) + ' chofer(es)).');
        return recargarChoferes(m.grupo).then(cargar);
      }).catch(function (e) {
        setChoferesModal(function (x) { return Object.assign({}, x || {}, { cargando: false, error: mensajeError(e) }); });
      });
    }
    function desvincularChofer(c) {
      var m = choferesModal; if (!m) return;
      var queda = c.otrosGrupos && c.otrosGrupos.length ? ' Sigue en ' + nombresDe(c.otrosGrupos) + '.' : ' No queda en ningún otro grupo.';
      if (!window.confirm('¿Quitar a "' + c.nombre + '" de "' + m.grupo.nombre + '"?\n\nSus rutas dejan de notificarse en este grupo.' + queda)) return;
      setChoferesModal(Object.assign({}, m, { cargando: true, error: '' }));
      window.CR.backend.desvincularChoferDeGrupo(m.grupo.id, c.id).then(function (r) {
        setMensaje('"' + c.nombre + '" ya no está en "' + m.grupo.nombre + '" (' + Number(r && r.cantidadChoferes || 0) + ' chofer(es)).');
        return recargarChoferes(m.grupo).then(cargar);
      }).catch(function (e) {
        setChoferesModal(function (x) { return Object.assign({}, x || {}, { cargando: false, error: mensajeError(e) }); });
      });
    }
    function etiquetaChofer(c) {
      return c.nombre + (c.patente ? ' · ' + c.patente : '') +
        (c.agencia && String(c.agencia).toUpperCase() !== 'PARTICULAR' ? ' · ' + c.agencia : '') +
        (c.otrosGrupos && c.otrosGrupos.length ? ' · ya en ' + nombresDe(c.otrosGrupos) : '');
    }
    var fgState = useState(SIN_FILTRO_G); var filtroG = fgState[0], setFiltroG = fgState[1];
    var grupos = data && data.grupos || [];
    var archivados = data && data.archivados || [];
    var elegidos = grupos.filter(function (g) { return !!selected[g.id]; });
    var hayFiltroG = Object.keys(SIN_FILTRO_G).some(function (k) { return !!filtroG[k]; });
    var visiblesG = grupos.filter(function (g) { return pasaFiltroGrupo(g, filtroG); });
    // Seleccionados que el filtro NO muestra. Se avisa en vez de descartarlos en silencio: los
    // botones de arriba (marcar particulares, proponer activacion) operan sobre TODO lo elegido.
    var elegidosOcultos = elegidos.filter(function (g) { return !pasaFiltroGrupo(g, filtroG); });
    function opcionesG(campo) {
      var vistos = {}, out = [];
      grupos.forEach(function (g) {
        if (!pasaFiltroGrupo(g, filtroG, campo)) return;
        var v = valorGrupo(campo, g);
        if (v && !vistos[v]) { vistos[v] = true; out.push(v); }
      });
      return out.sort(function (x, y) { return x.localeCompare(y, 'es'); });
    }
    var activos = grupos.filter(function (g) { return g.activo; });
    var totalChoferes = grupos.reduce(function (n, g) { return n + (g.cantidadChoferes || 0); }, 0);
    var choferesActivos = activos.reduce(function (n, g) { return n + (g.cantidadChoferes || 0); }, 0);
    var pct = totalChoferes ? Math.round(choferesActivos * 100 / totalChoferes) : 0;
    var confiables = data && data.confiables || [];
    var dudosos = data && data.dudosos || [];
    var sugerencias = data && data.sugerencias || [];
    var sinCorrespondenciaWa = data && data.sinCorrespondenciaWa || [];
    var sinCorrespondenciaBase = data && data.sinCorrespondenciaBase || [];
    var confiablesVistos = {};
    var confiablesPendientes = confiables.filter(function (m) {
      var grupo = m && m.grupo;
      if (!grupo || !grupo.id || grupo.vinculado || grupo.jid || confiablesVistos[grupo.id]) return false;
      confiablesVistos[grupo.id] = true;
      return true;
    });
    function toggle(id) { var next = Object.assign({}, selected); next[id] = !next[id]; setSelected(next); }
    // Marca los VISIBLES, no los 119: con un filtro puesto, "todos" tiene que significar "todos
    // los que estoy viendo". Marcar los que no se ven y despues apretar "Proponer activacion"
    // manda WhatsApp a choferes de grupos que el operador nunca miro.
    // Los que ya estaban elegidos y el filtro esconde se RESPETAN (no se pisa una seleccion previa).
    function seleccionarTodos(v) {
      var next = {};
      elegidosOcultos.forEach(function (g) { next[g.id] = true; });
      if (v) visiblesG.forEach(function (g) { next[g.id] = true; });
      setSelected(next);
    }
    function correr(tarea, ok) {
      setBusy(true); setError(''); setMensaje('');
      return tarea.then(function () { setMensaje(ok); setSelected({}); return cargar(); })
        .catch(function (e) { setError(mensajeError(e)); setBusy(false); });
    }
    function vincularConfiables() {
      var filtroActivo = Object.keys(selected).some(function (id) { return selected[id]; });
      var matches = confiablesPendientes.filter(function (m) { return !filtroActivo || selected[m.grupo.id]; });
      if (!matches.length) { setError('No hay matches confiables pendientes en la selección.'); return; }
      correr(matches.reduce(function (p, m) { return p.then(function () { return window.CR.backend.vincularGrupo(m.grupo.id, m.whatsapp.jid); }); }, Promise.resolve()),
        matches.length + ' grupo(s) vinculados.');
    }
    function vincularSugerencia(match, candidato) {
      var grupoId = candidato && (candidato.grupoId || candidato.id);
      if (!grupoId || !match.whatsapp || !match.whatsapp.jid) {
        setError('El candidato no tiene los datos necesarios para vincularlo.');
        return;
      }
      correr(window.CR.backend.vincularGrupo(grupoId, match.whatsapp.jid),
        '"' + candidato.nombre + '" quedó vinculado con "' + (match.whatsapp.nombre || match.whatsapp.jid) + '".');
    }
    function marcarParticulares() {
      if (!elegidos.length) { setError('Seleccioná al menos un grupo.'); return; }
      if (!window.confirm('¿Marcar ' + elegidos.length + ' grupo(s) como particulares? No requerirán dueño.')) return;
      correr(elegidos.reduce(function (p, g) { return p.then(function () {
        return window.CR.backend.guardarGrupoConfig({ grupoId: g.id, tipo: 'particular', duenos: [] });
      }); }, Promise.resolve()), elegidos.length + ' grupo(s) marcados como particulares.');
    }
    function cambiarArchivo(g, archivar) {
      var verbo = archivar ? 'archivar' : 'desarchivar';
      var detalle = archivar
        ? 'Dejará de aparecer en el onboarding, pero no se borrará y podrás restaurarlo.'
        : 'Volverá a aparecer entre los grupos del onboarding.';
      if (!window.confirm('¿' + (archivar ? 'Archivar' : 'Desarchivar') + ' "' + g.nombre + '"?\n\n' + detalle)) return;
      correr(window.CR.backend.archivarGrupo(g.id, archivar),
        '"' + g.nombre + '" se pudo ' + verbo + ' correctamente.');
    }
    function proponer() {
      var aptos = elegidos.filter(function (g) { return (g.vinculado || g.jid) && !g.activo; });
      if (!aptos.length) { setError('Seleccioná grupos vinculados e inactivos.'); return; }
      if (!zona) { setError('Elegí la macro-zona del lote.'); return; }
      setBusy(true); setError(''); setMensaje('');
      window.CR.backend.activarGruposLote({ grupos: aptos.map(function (g) { return { grupoId: g.id, macroZona: zona }; }) })
        .then(function () {
          // Este texto decia "la tiene que aprobar OTRO gerente" — quedo viejo al habilitar la
          // firma unica y contradecia al boton que esta dos lineas mas abajo. Un cartel que
          // miente sobre lo que se puede hacer frena al operador aunque el sistema funcione.
          setMensaje('Propuesta creada. Bajá a "Propuestas esperando segunda firma": ahí la activás vos con "Activar (firma única)", o la aprueba otro gerente si hay alguien disponible. Vence en 15 minutos.');
          return cargarPendientes().then(function () { setBusy(false); }); })
        .catch(function (e) { setError(mensajeError(e)); setBusy(false); });
    }


    return h('div', null,
      h(ui.Page, { title: 'Onboarding de grupos', subtitle: 'Vinculá y activá grupos de WhatsApp de forma gradual y controlada.' }),
      h('div', { className: 'alerta alerta--media onboarding-aviso' }, h('b', null, 'Onboarding gradual'),
        h('span', null, 'Sumá pocos grupos por día para reducir el riesgo de bloqueo de la línea de WhatsApp.')),
      error ? h('div', { className: 'alerta alerta--alta', role: 'alert' }, error) : null,
      mensaje ? h('div', { className: 'alerta alerta--baja', role: 'status' }, mensaje) : null,
      h(ui.Card, { title: 'Progreso hacia el GO LIVE' },
        h('div', { className: 'grid grid--stats' },
          h(ui.StatCard, { label: 'Grupos activos', value: activos.length + ' de ' + grupos.length }),
          h(ui.StatCard, { label: 'Choferes cubiertos', value: choferesActivos + ' de ' + totalChoferes, sub: pct + '%' })),
        h('div', { className: 'onboarding-progress', 'aria-label': pct + '% de choferes cubiertos' }, h('span', { style: { width: pct + '%' } }))),
      h(ui.Card, { title: 'Descubrimiento', actions: h(ui.Button, { disabled: busy, onClick: cargar }, busy ? 'Buscando…' : 'Buscar grupos nuevos') },
        !data ? h(ui.EmptyState, { title: busy ? 'Buscando grupos…' : 'Todavía no se buscaron grupos' }) :
          h('div', { className: 'onboarding-buckets' }, h(ui.Badge, { color: 'ok' }, confiables.length + ' matches confiables'),
            h(ui.Badge, { color: 'warn' }, dudosos.length + ' dudosos'),
            h(ui.Badge, { color: 'neutral' }, sinCorrespondenciaWa.length + ' solo en WhatsApp'),
            h(ui.Badge, { color: 'neutral' }, sinCorrespondenciaBase.length + ' solo en la base'),
            archivados.length ? h(ui.Badge, { color: 'muted' }, archivados.length + ' archivados') : null)),
      data ? h(ui.Card, { title: 'Empates detectados · requiere elegir' },
        dudosos.length ? h('div', { className: 'onboarding-dudosos' }, dudosos.map(function (match, indice) {
          var candidatos = match.candidatos || [];
          return h('section', { className: 'onboarding-match', key: (match.whatsapp && match.whatsapp.jid) || indice },
            h('div', { className: 'onboarding-match__origen' },
              h('b', null, match.whatsapp && (match.whatsapp.nombre || match.whatsapp.jid) || 'Grupo de WhatsApp'),
              h('span', { className: 'muted' }, 'El backend detectó un empate. Elegí qué grupo vincular; nunca se resuelve automáticamente.')),
            candidatos.length ? h('div', { className: 'onboarding-candidatos' }, candidatos.map(function (c, cIndice) {
              var grupoId = c.grupoId || c.id;
              var competencia = dudosos.filter(function (otro) {
                return otro !== match && (otro.candidatos || []).some(function (otroCandidato) {
                  return (otroCandidato.grupoId || otroCandidato.id) === grupoId;
                });
              }).length;
              return h('div', { className: 'onboarding-candidato', key: grupoId || cIndice },
                h('div', null, h('b', null, c.nombre || 'Grupo sin nombre'),
                  h('div', { className: 'muted' }, Number(c.cantidadChoferes || 0) + ' choferes'),
                  esResiduo(c) ? h(ui.Badge, { color: 'muted' }, 'Sin choferes / probable duplicado') : null,
                  competencia ? h('div', { className: 'muted' }, 'Compite con ' + competencia + ' grupo(s) de WhatsApp por este grupo base.') : null),
                h(ui.Button, { size: 'sm', disabled: busy || !grupoId,
                  onClick: function () { vincularSugerencia(match, c); },
                  'aria-label': 'Elegir ' + (c.nombre || 'candidato') + ' para ' + (match.whatsapp && match.whatsapp.nombre || 'grupo de WhatsApp') },
                'Elegir y confirmar'));
            })) : h(ui.EmptyState, { title: 'Empate sin candidatos disponibles' }, 'Archivá el duplicado incorrecto y volvé a buscar grupos.')
          );
        })) : h(ui.EmptyState, { title: 'No hay empates pendientes' }, 'Los matches confiables y las sugerencias aparecen en sus secciones.')
      ) : null,
      data ? h(ui.Card, { title: 'Candidatos propuestos por similitud · requiere elegir' },
        sugerencias.length ? h('div', { className: 'onboarding-sugerencias' }, sugerencias.map(function (match, indice) {
          var candidatos = match.candidatos || [];
          return h('section', { className: 'onboarding-match', key: (match.whatsapp && match.whatsapp.jid) || indice },
            h('div', { className: 'onboarding-match__origen' },
              h('b', null, match.whatsapp && (match.whatsapp.nombre || match.whatsapp.jid) || 'Grupo de WhatsApp'),
              h('span', { className: 'muted' }, 'Sigue sin correspondencia hasta que elijas; no se vincula nada automáticamente.')),
            candidatos.length ? h('div', { className: 'onboarding-candidatos' }, candidatos.map(function (c, cIndice) {
              return h('div', { className: 'onboarding-candidato', key: c.grupoId || cIndice },
                h('div', null, h('b', null, c.nombre || 'Grupo sin nombre'),
                  h('div', { className: 'muted' }, scoreCandidato(c) + ' · confianza ' + (c.confianza || 'sin clasificar') + ' · ' + Number(c.cantidadChoferes || 0) + ' choferes')),
                h(ui.Button, { size: 'sm', disabled: busy || !c.grupoId,
                  onClick: function () { vincularSugerencia(match, c); },
                  'aria-label': 'Confirmar ' + (c.nombre || 'candidato') + ' para ' + (match.whatsapp && match.whatsapp.nombre || 'grupo de WhatsApp') },
                'Elegir y confirmar'));
            })) : h(ui.EmptyState, { title: 'Sin candidatos sobre el umbral' }, 'Este grupo conserva el estado sin correspondencia.')
          );
        })) : h(ui.EmptyState, { title: 'No hay candidatos propuestos' }, 'Los grupos sin candidatos conservan el estado sin correspondencia.')) : null,
      data ? h(ui.Card, { title: 'Sin correspondencia' },
        !sinCorrespondenciaWa.length && !sinCorrespondenciaBase.length
          ? h(ui.EmptyState, { title: 'No hay grupos sin correspondencia' })
          : h('div', { className: 'onboarding-sin-correspondencia' },
            sinCorrespondenciaWa.map(function (g, i) { return h('div', { key: g.jid || i, style: { display: 'flex', alignItems: 'center', gap: 8 } },
              h('b', null, g.nombre || g.jid), h('span', { className: 'muted' }, 'Solo en WhatsApp'),
              // antes esto era texto pelado: el grupo se veia pero no habia NADA que hacerle
              h(ui.Button, { size: 'sm', disabled: busy, onClick: function () { abrirIncorporar(g); } }, 'Incorporar')); }),
            sinCorrespondenciaBase.map(function (g, i) { return h('div', { key: g.id || i }, h('b', null, g.nombre || g.id), h('span', { className: 'muted' }, 'Solo en la base · ' + Number(g.cantidadChoferes || 0) + ' choferes')); }))
      ) : null,
      h(ui.Card, { title: 'Todos los grupos', actions: h('span', { className: 'muted' }, elegidos.length + ' seleccionados') },
        h(ui.Toolbar, null,
          h(ui.Field, { label: 'Grupo' },
            h('input', { className: 'input', type: 'search', value: filtroG.grupo, placeholder: 'Buscar por nombre o jid\u2026',
              'aria-label': 'Buscar grupo', style: { minWidth: 200 },
              onChange: function (e) { setFiltroG(Object.assign({}, filtroG, { grupo: e.target.value })); } })),
          h(ui.Field, { label: 'Estado' },
            h(ui.Select, { value: filtroG.estado, placeholder: 'Todos', 'aria-label': 'Filtrar por estado',
              onChange: function (v) { setFiltroG(Object.assign({}, filtroG, { estado: v })); },
              options: opcionesG('estado') })),
          h(ui.Field, { label: 'Choferes' },
            h(ui.Select, { value: filtroG.choferes, placeholder: 'Todos', 'aria-label': 'Filtrar por cantidad de choferes',
              onChange: function (v) { setFiltroG(Object.assign({}, filtroG, { choferes: v })); },
              options: opcionesG('choferes') })),
          h(ui.Field, { label: 'Tipo' },
            h(ui.Select, { value: filtroG.tipo, placeholder: 'Todos', 'aria-label': 'Filtrar por tipo',
              onChange: function (v) { setFiltroG(Object.assign({}, filtroG, { tipo: v })); },
              options: opcionesG('tipo') })),
          h(ui.Field, { label: 'Due\u00f1o(s)' },
            h(ui.Select, { value: filtroG.duenos, placeholder: 'Todos', 'aria-label': 'Filtrar por due\u00f1os',
              onChange: function (v) { setFiltroG(Object.assign({}, filtroG, { duenos: v })); },
              options: opcionesG('duenos') }))),
        hayFiltroG ? h('div', { style: { display: 'flex', gap: 8, flexWrap: 'wrap', marginBottom: 10 } },
          Object.keys(SIN_FILTRO_G).filter(function (k) { return !!filtroG[k]; }).map(function (k) {
            return h('span', { key: k, className: 'chip-filtro' },
              ETIQUETA_G[k] + ': ' + filtroG[k],
              h('button', { type: 'button', title: 'Quitar este filtro',
                'aria-label': 'Quitar el filtro de ' + ETIQUETA_G[k],
                onClick: function () { var n = Object.assign({}, filtroG); n[k] = ''; setFiltroG(n); } }, '\u2715'));
          }).concat([
            h('span', { key: '_n', className: 'muted', style: { alignSelf: 'center' } },
              visiblesG.length + ' de ' + grupos.length),
            h('button', { key: '_todos', className: 'btn btn--ghost btn--sm',
              onClick: function () { setFiltroG(SIN_FILTRO_G); } }, 'Ver todos')
          ])) : null,
        // Un lote se propone sobre lo SELECCIONADO, no sobre lo visible: si el filtro esconde algo
        // elegido, se dice. Descubrirlo despues de activar es descubrirlo tarde.
        elegidosOcultos.length ? h('div', { className: 'muted', style: { marginBottom: 10 } },
          '\u26a0 ' + elegidosOcultos.length + ' grupo(s) seleccionado(s) no se ven con este filtro y ' +
          'igual entran en las acciones de abajo: ' +
          elegidosOcultos.map(function (g) { return g.nombre; }).slice(0, 5).join(', ') +
          (elegidosOcultos.length > 5 ? '\u2026' : ''),
          h('button', { type: 'button', className: 'btn btn--ghost btn--sm', style: { marginLeft: 8 },
            onClick: function () {
              var n = {}; elegidos.forEach(function (g) { if (pasaFiltroGrupo(g, filtroG)) n[g.id] = true; });
              setSelected(n);
            } }, 'Deseleccionar los ocultos')) : null,
        h(ui.Toolbar, null,
          h(ui.Button, { disabled: busy || !confiablesPendientes.length, onClick: vincularConfiables }, 'Vincular matches confiables'),
          h(ui.Button, { variant: 'ghost', disabled: busy || !elegidos.length, onClick: marcarParticulares }, 'Marcar particulares'),
          h(ui.Select, { value: zona, placeholder: 'Macro-zona del lote', options: window.CR.const.MACRO_ZONAS.map(function (z) { return { value: z.k, label: z.label }; }), onChange: setZona, disabled: busy }),
          h(ui.Button, { variant: 'ghost', disabled: busy || !elegidos.length, onClick: proponer }, 'Proponer activación')),
        h(ui.DataTable, { rows: visiblesG, rowKey: 'id', empty: busy ? 'Cargando grupos…' : (hayFiltroG ? 'Ningún grupo coincide con el filtro' : 'No hay grupos en la API.'), columns: [
          { key: 'sel', label: h('input', { type: 'checkbox', checked: !!visiblesG.length && visiblesG.every(function (g) { return !!selected[g.id]; }), onChange: function (e) { seleccionarTodos(e.target.checked); }, 'aria-label': 'Seleccionar todos los visibles' }),
            render: function (g) { return h('input', { type: 'checkbox', checked: !!selected[g.id], onChange: function () { toggle(g.id); }, 'aria-label': 'Seleccionar ' + g.nombre }); } },
          { key: 'nombre', label: 'Grupo', render: function (g) { return h('div', { className: esResiduo(g) ? 'onboarding-residuo' : '' },
            h('div', { className: 'onboarding-nombre' }, h('b', null, g.nombre),
              esResiduo(g) ? h(ui.Badge, { color: 'muted' }, 'Sin choferes / probable duplicado') : null),
            g.jid ? h('div', { className: 'muted onboarding-jid' }, g.jid) : null,
            esResiduo(g) ? h(ui.Button, { variant: 'ghost', size: 'sm', className: 'onboarding-archivar', disabled: busy,
              onClick: function () { cambiarArchivo(g, true); } }, 'Archivar') : null); } },
          { key: 'estado', label: 'Estado', render: estadoBadge },
          { key: 'cantidadChoferes', label: 'Choferes', align: 'right', render: function (g) { return h('div', { className: 'onboarding-choferes' },
            h('span', { className: 'tnum' }, String(Number(g.cantidadChoferes || 0))),
            h('button', { type: 'button', className: 'btn btn--ghost btn--sm', disabled: busy, 'aria-label': 'Choferes de ' + g.nombre,
              onClick: function () { abrirChoferes(g); } }, 'Vincular')); } },
          { key: 'tipo', label: 'Tipo', render: function (g) { return h(ui.Badge, { color: g.tipo === 'agencia' ? 'info' : 'neutral' }, g.tipo === 'agencia' ? 'Agencia' : 'Particular'); } },
          { key: 'duenos', label: 'Dueño(s)', render: function (g) { return (g.duenos || []).length ? g.duenos.map(function (d) { return d.nombre; }).join(', ') : (g.tipo === 'agencia' ? h(ui.Badge, { color: 'danger' }, 'Pendiente') : 'No requiere'); } }
        ] })),
      // Segunda llave: acá el OTRO gerente ve lo propuesto y lo aprueba. Antes esto no existía
      // y la propuesta moría a los 15 minutos sin que nadie pudiera confirmarla.
      pendientes.length ? h(ui.Card, { title: 'Propuestas esperando segunda firma (' + pendientes.length + ')',
        actions: (function () {
          var ajenas = pendientes.filter(function (p) { return !p.propiaPropuesta; });
          return ajenas.length ? h(ui.Button, { disabled: busy,
            onClick: function () { aprobarPendientes(ajenas.map(function (p) { return p.aprobacionId; })); } },
          'Aprobar todas (' + ajenas.length + ')') : null;
        })() },
        h('p', { className: 'muted' }, 'Las propone un gerente y las confirma otro. Vencen a los 15 minutos de creadas.'),
        h(ui.DataTable, { rows: pendientes, rowKey: 'aprobacionId', empty: 'Sin propuestas pendientes.', columns: [
          { key: 'grupoNombre', label: 'Grupo', render: function (p) { return h('div', null,
            h('b', null, p.grupoNombre), p.jid ? h('div', { className: 'muted onboarding-jid' }, p.jid) : null); } },
          { key: 'macroZona', label: 'Macro-zona' },
          { key: 'propuestoPorNombre', label: 'Propuesta por' },
          { key: 'accion', label: 'Acción', render: function (p) {
            return p.propiaPropuesta
              ? h(ui.Button, { size: 'sm', variant: 'danger', disabled: busy,
                onClick: function () { abrirPrevia(p); } }, 'Activar (firma única)')
              : h(ui.Button, { size: 'sm', disabled: busy,
                onClick: function () { aprobarPendientes([p.aprobacionId]); } }, 'Aprobar'); } }
        ] })) : null,

      // Checkpoint de la firma única. Reemplaza al segundo par de ojos, así que dice
      // el jid REAL y cuántos choferes empiezan a recibir mensajes de verdad.
      previa ? h(ui.Modal, { open: true, title: 'Activar grupo con firma única',
        onClose: function () { setPrevia(null); },
        footer: h('div', null,
          h(ui.Button, { variant: 'ghost', onClick: function () { setPrevia(null); } }, 'Cancelar'),
          h(ui.Button, { variant: 'danger', disabled: busy, onClick: confirmarFirmaUnica }, 'Sí, activar y empezar a enviar')) },
        h('div', { className: 'alerta alerta--alta' },
          h('b', null, 'Al confirmar, este grupo empieza a recibir mensajes REALES de WhatsApp.'),
          h('span', null, ' Estás firmando solo: no hay una segunda persona revisando. Leé los datos antes de confirmar.')),
        h('p', null, h('b', null, 'Grupo: '), previa.grupoNombre),
        h('p', null, h('b', null, 'WhatsApp: '), h('code', null, previa.jid || 'sin jid')),
        h('p', null, h('b', null, 'Macro-zona: '), previa.macroZona),
        h('p', null, h('b', null, 'Tipo: '), previa.tipo === 'agencia' ? 'Agencia' : 'Particular'),
        h('p', null, h('b', null, 'Choferes que van a empezar a recibir: '), String(previa.choferes)),
        h('p', { className: 'muted' }, 'Si algo de esto no es lo que esperabas, cancelá y revisá la vinculación del grupo.')) : null,
      choferesModal ? h(ui.Modal, { open: true, title: 'Choferes de "' + choferesModal.grupo.nombre + '"',
        onClose: function () { setChoferesModal(null); },
        footer: h('div', null, h(ui.Button, { variant: 'ghost', onClick: function () { setChoferesModal(null); } }, 'Cerrar')) },
        h('p', { className: 'muted' },
          (choferesModal.grupo.tipo === 'agencia' ? 'Grupo de agencia. ' : 'Grupo particular: puede tener uno o varios choferes. ') +
          'Las rutas de cada chofer se notifican en el grupo activo al que se lo vinculó más recientemente.'),
        choferesModal.error ? h('div', { className: 'alerta alerta--alta' }, choferesModal.error) : null,
        h('h4', null, 'Vinculados (' + choferesModal.miembros.length + ')'),
        choferesModal.miembros.length ? h('ul', { className: 'onboarding-miembros' }, choferesModal.miembros.map(function (c) {
          return h('li', { key: c.id },
            h('span', null, h('b', null, c.nombre),
              c.patente ? h('span', { className: 'muted' }, ' · ' + c.patente) : null,
              c.agencia && String(c.agencia).toUpperCase() !== 'PARTICULAR' ? h('span', { className: 'muted' }, ' · ' + c.agencia) : null,
              c.otrosGrupos && c.otrosGrupos.length ? h('span', { className: 'muted' }, ' · también en ' + nombresDe(c.otrosGrupos)) : null),
            h('button', { type: 'button', className: 'btn btn--ghost btn--sm', 'aria-label': 'Quitar a ' + c.nombre,
              disabled: choferesModal.cargando, onClick: function () { desvincularChofer(c); } }, 'Quitar'));
        })) : h('p', { className: 'muted' }, choferesModal.cargando ? 'Cargando…' : 'Este grupo todavía no tiene choferes: sus rutas no se notifican a nadie.'),
        h('h4', null, 'Sumar un chofer'),
        h(ui.Field, { label: 'Chofer' }, h(ui.Select, { value: choferesModal.elegido, placeholder: 'Elegí un chofer', 'aria-label': 'Chofer a vincular',
          disabled: choferesModal.cargando,
          options: choferesModal.candidatos.map(function (c) { return { value: c.id, label: etiquetaChofer(c) }; }),
          onChange: function (v) { setChoferesModal(Object.assign({}, choferesModal, { elegido: v })); } })),
        (function () {
          var cand = choferesModal.candidatos.filter(function (c) { return c.id === choferesModal.elegido; })[0];
          var activos = otrosActivos(cand);
          return activos.length ? h('div', { className: 'alerta alerta--media onboarding-aviso-otros' },
            h('b', null, '⚠ Ya está en ' + nombresDe(activos) + '.'),
            h('span', null, ' Sus rutas pasan a notificarse en este grupo, porque manda el vínculo más reciente. Si querés que sigan llegando al otro, no lo vincules acá.')) : null;
        })(),
        h(ui.Button, { variant: 'primary', disabled: choferesModal.cargando || !choferesModal.elegido, onClick: vincularChofer }, 'Vincular')) : null,
      h(ui.Card, { title: 'Archivados', actions: h(ui.Button, { variant: 'ghost', onClick: function () { setVerArchivados(!verArchivados); } },
        verArchivados ? 'Ocultar archivados' : 'Ver archivados (' + archivados.length + ')') },
        !verArchivados ? h('p', { className: 'muted onboarding-archivo-ayuda' }, 'Los grupos archivados se ocultan sin borrar datos y se pueden restaurar cuando haga falta.') :
          h(ui.DataTable, { rows: archivados, rowKey: 'id', empty: 'No hay grupos archivados.', columns: [
            { key: 'nombre', label: 'Grupo', render: function (g) { return h('div', { className: 'onboarding-residuo' },
              h('b', null, g.nombre), h('div', { className: 'muted' }, (g.cantidadChoferes || 0) + ' choferes')); } },
            { key: 'estado', label: 'Estado', render: function () { return h(ui.Badge, { color: 'muted' }, 'Archivado'); } },
            { key: 'accion', label: 'Acción', render: function (g) { return h(ui.Button, { variant: 'ghost', size: 'sm', disabled: busy,
              onClick: function () { cambiarArchivo(g, false); } }, 'Desarchivar'); } }
          ] })),
      h(ui.Modal, { open: !!incorporando, title: incorporando ? 'Incorporar ' + (incorporando.nombre || 'grupo') : 'Incorporar',
        onClose: function () { setIncorporando(null); }, footer: h('div', null,
          h(ui.Button, { variant: 'ghost', onClick: function () { setIncorporando(null); } }, 'Cancelar'),
          h(ui.Button, { variant: 'primary', onClick: incorporar,
            disabled: busy || !incorporando || !(incorporando.nombre || '').trim()
              || (incorporando.tipo === 'agencia' && !incorporando.agencia) }, 'Incorporar')) },
        h('p', { className: 'muted' }, 'El grupo nace INACTIVO: no se le manda nada hasta que lo actives desde este tablero, con la previa de siempre.'),
        h(ui.Field, { label: 'Nombre en el sistema' }, h(ui.Input, { value: incorporando && incorporando.nombre || '',
          onChange: function (v) { setIncorporando(Object.assign({}, incorporando, { nombre: v })); } })),
        h(ui.Field, { label: 'Tipo' }, h(ui.Select, { value: incorporando && incorporando.tipo || 'particular',
          options: [{ value: 'particular', label: 'Particular' }, { value: 'agencia', label: 'Agencia' }],
          onChange: function (v) { setIncorporando(Object.assign({}, incorporando, { tipo: v })); } })),
        incorporando && incorporando.tipo === 'agencia' ? h(ui.Field, { label: 'Agencia (obligatoria para tipo agencia)' },
          h(ui.Select, { value: incorporando.agencia || '', placeholder: 'Elegí la agencia',
            options: agenciasLista,
            onChange: function (v) { setIncorporando(Object.assign({}, incorporando, { agencia: v })); } })) : null,
        incorporando && incorporando.tipo === 'agencia' ? h('p', { className: 'muted' },
          'Al incorporarlo se vinculan como miembros los choferes de esa agencia — es lo que permite registrarle un dueño en Dueños de agencia.') : null));
  }
  window.CR.screens = window.CR.screens || {};
  window.CR.screens.OnboardingGrupos = OnboardingGrupos;
})();
