



(function () {
  var React = window.React;
  var h = React.createElement;
  var useState = React.useState, useEffect = React.useEffect, useRef = React.useRef;

  function money(n) { return '$' + Number(n || 0).toLocaleString('es-AR'); }

  // explicador local (fallback si el backend no responde) — espeja explicarAsignacion del dev-server
  function explicarLocal(ruta, pregunta) {
    if (!ruta) return 'Elegí una ruta y te explico por qué la asigné así.';
    var m = ruta.motivo || {};
    var razones = [];
    if (ruta.vehiculoSugerido) razones.push('MELI ruteó esta ruta para **' + ruta.vehiculoSugerido + '** (por m³); asigné **' + (ruta.unidad || '—') + '**' + (ruta.unidad === ruta.vehiculoSugerido ? ' (coincide)' : ' (misma o mayor capacidad)') + '.');
    if (m.flotaNueva) razones.push('Es **flota nueva** → prioridad (tu regla).');
    if (m.tarifaDif) razones.push('Tiene **tarifa diferencial**: la dejé como último recurso, sólo porque no había mejor disponible' + (ruta.km ? ' para ' + ruta.km + ' km' : '') + '.');
    else razones.push('**Sin** tarifa diferencial → más económica.');
    if (/PARTICULAR/i.test((m.agencia || '') + (ruta.agencia || ''))) razones.push('Es **particular** (preferís particular vs agencia).');
    if (m.zonaMatch) razones.push('El chofer es de la **misma zona** (' + (ruta.macroZona || '') + ').');
    if (m.desempeno) razones.push('Desempeño: **' + m.desempeno + '**.');
    var txt = 'Ruta **' + (ruta.idRuta || '?') + '** (' + (ruta.servicio || '') + (ruta.macroZona ? ' · ' + ruta.macroZona : '') + (ruta.km ? ' · ' + ruta.km + ' km' : '') + ')\n';
    txt += 'Propuse **' + (ruta.patente || '—') + '** — ' + (ruta.chofer || 's/chofer') + (window.CR.canSeeCosts && ruta.tarifa ? ' · ' + money(ruta.tarifa) : '') + '.\n';
    txt += '\n**Por qué:**\n- ' + razones.join('\n- ');
    var q = String(pregunta || '').toUpperCase();
    var cands = ruta.candidatos || [];
    var otro = cands.filter(function (c) { return q.indexOf(String(c.patente).toUpperCase()) >= 0 && c.patente !== ruta.patente; })[0];
    if (otro) {
      var win = cands.filter(function (c) { return c.patente === ruta.patente; })[0];
      txt += '\n\n**' + ruta.patente + ' vs ' + otro.patente + ':** puntúan ' + (win ? win.score : '?') + ' vs ' + otro.score + '. ';
      var difs = [];
      if (otro.tarifaDiferencial && !(win && win.tarifaDiferencial)) difs.push(otro.patente + ' tiene tarifa diferencial (penaliza)');
      if (win && win.flotaNueva && !otro.flotaNueva) difs.push(ruta.patente + ' es flota nueva');
      if (win && win.particular && !otro.particular) difs.push(ruta.patente + ' es particular');
      txt += difs.length ? 'Diferencia: ' + difs.join('; ') + '.' : 'Están parejos; si preferís ' + otro.patente + ' cambialo con 1 clic — es válido para esta ruta.';
    } else if (cands.length > 1) {
      txt += '\n\nAlternativas válidas: ' + cands.slice(0, 4).map(function (c) { return c.patente + ' (' + c.score + ')'; }).join(', ') + '. Cambiás con 1 clic.';
    }
    return txt;
  }

  // markdown mínimo: **negrita** + saltos de línea
  function fmt(text) {
    return String(text || '').split('\n').map(function (line, i) {
      var parts = line.split(/(\*\*[^*]+\*\*)/g).map(function (p, j) {
        var m = /^\*\*([^*]+)\*\*$/.exec(p);
        return m ? h('strong', { key: j }, m[1]) : p;
      });
      return h('div', { key: i, className: 'cop-line' }, line ? parts : h('span', { style: { display: 'block', height: 6 } }));
    });
  }

  // devuelve { texto, fuente }: fuente 'craneo' = respondió el AGENTE Hermes; 'local' = explicador determinista
  function ask(ruta, texto) {
    if (window.CR.backend && window.CR.backend.enabled) {
      return window.CR.backend.explicarCraneo(ruta, texto).then(function (r) {
        if (r && r.texto) return { texto: r.texto, fuente: r.fuente || 'local' };
        return { texto: explicarLocal(ruta, texto), fuente: 'local' };
      });
    }
    return Promise.resolve({ texto: explicarLocal(ruta, texto), fuente: 'local' });
  }

  var WELCOME = { who: 'craneo', text: 'Soy **CRÁNEO**. Yo armo la propuesta; vos ponés el criterio final. Elegí una ruta y te explico por qué la asigné así — o preguntame “¿por qué este chofer?”, “¿por qué no la patente X?”.' };

  function Copiloto(props) {
    var ruta = props.ruta;
    // msgs viven en el store → sobreviven toggle del dock y navegación
    window.CR.useStore();
    var qState = useState(''); var q = qState[0], setQ = qState[1];
    var busyState = useState(false); var busy = busyState[0], setBusy = busyState[1];
    var boxRef = useRef(null);
    var live = !!(window.CR.backend && window.CR.backend.enabled);

    function getMsgs() {
      var stored = window.CR.store.list('copiloMsgs');
      return stored.length ? stored : [WELCOME];
    }
    function push(who, text, fuente) {
      window.CR.store.bulkSet('copiloMsgs', getMsgs().concat([{ who: who, text: text, fuente: fuente }]));
    }
    var msgs = getMsgs();

    // auto-explica cuando cambia la ruta O su contenido (swap/edición cambian chofer/km/zona con el MISMO
    // id — con dep [ruta.id] la explicación quedaba vieja). La firma resume lo que CRÁNEO explica.
    var firma = ruta ? [ruta.id, ruta.choferId, ruta.patente, ruta.km, ruta.macroZona, ruta.hora, ruta.vehiculoSugerido, ruta.nota].join('|') : null;
    var askSeq = useRef(0);   // descarta respuestas en vuelo si la selección cambió
    useEffect(function () {
      if (!ruta) return;
      var seq = ++askSeq.current;
      push('user', 'Explicame la ruta ' + ruta.idRuta);
      setBusy(true);
      ask(ruta, '').then(function (r) { if (seq === askSeq.current) { push('craneo', r.texto, r.fuente); setBusy(false); } });
    }, [firma]);

    useEffect(function () { if (boxRef.current) boxRef.current.scrollTop = boxRef.current.scrollHeight; }, [msgs, busy]);

    // pregunta libre -> la responde el AGENTE CRÁNEO (Hermes) si el puente está arriba (~9s); si no, el determinista
    function enviar() {
      var texto = (q || '').trim(); if (!texto) return;
      push('user', texto); setQ(''); setBusy(true);
      ask(ruta, texto).then(function (r) { push('craneo', r.texto, r.fuente); }).then(function () { setBusy(false); });
    }

    return h('div', { className: 'copiloto' },
      h('div', { className: 'cop-head' },
        h('div', { className: 'cop-avatar' }, 'C'),
        h('div', { style: { flex: 1 } },
          h('b', null, 'CRÁNEO'),
          h('small', { className: 'muted' }, 'copiloto de asignación')),
        h('span', { className: 'badge badge--' + (live ? 'ok' : 'neutral'), dot: true }, live ? 'Live' : 'Local')),
      h('div', { className: 'cop-body', ref: boxRef },
        msgs.map(function (m, i) {
          if (m.who !== 'craneo') return h('div', { key: i, className: 'cop-msg cop-msg--user' }, h('div', { className: 'cop-bubble cop-bubble--user' }, m.text));
          return h('div', { key: i, className: 'cop-msg cop-msg--craneo' },
            h('div', { className: 'cop-bubble' },
              m.fuente === 'craneo' ? h('div', { className: 'cop-src' }, '🤖 respondió el agente CRÁNEO') : null,
              fmt(m.text)));
        }),
        busy ? h('div', { className: 'cop-msg cop-msg--craneo' }, h('div', { className: 'cop-bubble cop-typing' }, '● ● ●')) : null),
      h('div', { className: 'cop-input' },
        h('input', { className: 'input', placeholder: ruta ? '¿Por qué este chofer? ¿Por qué no…?' : 'Elegí una ruta primero', value: q,
          disabled: !ruta, onChange: function (e) { setQ(e.target.value); }, onKeyDown: function (e) { if (e.key === 'Enter') enviar(); } }),
        h('button', { className: 'btn btn--primary btn--sm', disabled: !ruta || !q.trim(), onClick: enviar }, 'Preguntar')));
  }

  window.CR.Copiloto = Copiloto;
})();
