// /home/Autopartes/pos/static/js/chat.js
// AI Chat Widget for Nexus POS — natural language parts lookup

(function () {
  'use strict';

  // ─── State ───
  let isOpen = false;
  let isSending = false;
  let isListening = false;
  let recognition = null;
  let ttsEnabled = true;
  let ttsUtterance = null;
  const history = [];  // conversation history for AI context
  const hasSpeechAPI = ('webkitSpeechRecognition' in window || 'SpeechRecognition' in window);
  const hasTTS = ('speechSynthesis' in window);

  // ─── Build DOM ───
  function init() {
    // FAB button
    const fab = document.createElement('button');
    fab.className = 'chat-fab';
    fab.id = 'chatFab';
    fab.title = 'Asistente IA';
    fab.innerHTML = '&#x1F4AC;';  // speech bubble emoji
    fab.setAttribute('aria-label', 'Abrir asistente IA');

    // Chat panel
    const panel = document.createElement('div');
    panel.className = 'chat-panel';
    panel.id = 'chatPanel';
    panel.innerHTML = `
      <div class="chat-header">
        <h3>Asistente IA — Buscar partes</h3>
        <div class="chat-header-actions">
          ${hasTTS ? '<button class="chat-tts-toggle" id="chatTtsToggle" aria-label="Activar lectura de respuestas" title="Activar lectura de respuestas">&#128266;</button>' : ''}
          <button class="chat-header-close" id="chatClose" aria-label="Cerrar">&times;</button>
        </div>
      </div>
      <div class="chat-messages" id="chatMessages">
        <div class="chat-msg ai">Hola, soy el asistente de Nexus. Dime que refaccion necesitas y te ayudo a encontrarla.</div>
        <div class="chat-typing" id="chatTyping">
          <span></span><span></span><span></span>
        </div>
      </div>
      <div class="chat-input-area">
        <textarea class="chat-input" id="chatInput" placeholder="Ej: Balatas para Tsuru 2015..." rows="1"></textarea>
        <input type="file" id="chatImageInput" accept="image/*" capture="environment" style="display:none;">
        <button class="chat-cam-btn" id="chatCam" aria-label="Enviar foto de parte" title="Identificar parte por foto">&#128247;</button>
        ${hasSpeechAPI ? '<button class="chat-mic-btn" id="chatMic" aria-label="Entrada por voz" title="Entrada por voz">&#127908;</button>' : ''}
        <button class="chat-send-btn" id="chatSend" aria-label="Enviar">&#9654;</button>
      </div>
    `;

    document.body.appendChild(fab);
    document.body.appendChild(panel);

    // Events
    fab.addEventListener('click', toggleChat);
    document.getElementById('chatClose').addEventListener('click', toggleChat);
    document.getElementById('chatSend').addEventListener('click', sendMessage);
    document.getElementById('chatInput').addEventListener('keydown', function (e) {
      if (e.key === 'Enter' && !e.shiftKey) {
        e.preventDefault();
        sendMessage();
      }
    });

    // Camera button — identify part by photo
    document.getElementById('chatCam').addEventListener('click', function () {
      document.getElementById('chatImageInput').click();
    });
    document.getElementById('chatImageInput').addEventListener('change', handleImageUpload);

    // Mic button (only if Speech API available)
    if (hasSpeechAPI) {
      document.getElementById('chatMic').addEventListener('click', toggleVoice);
    }

    // TTS toggle
    if (hasTTS) {
      document.getElementById('chatTtsToggle').addEventListener('click', toggleTTS);
    }

    // Stop TTS when closing
    document.getElementById('chatClose').addEventListener('click', function () {
      if (hasTTS) stopSpeaking();
    });

    // Auto-resize textarea
    document.getElementById('chatInput').addEventListener('input', function () {
      this.style.height = 'auto';
      this.style.height = Math.min(this.scrollHeight, 80) + 'px';
    });
  }

  // ─── Voice Input (Web Speech API) ───
  function toggleVoice() {
    if (isListening) {
      stopVoice();
      return;
    }
    startVoice();
  }

  function startVoice() {
    const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
    if (!SpeechRecognition) return;

    recognition = new SpeechRecognition();
    recognition.lang = 'es-MX';
    recognition.continuous = false;
    recognition.interimResults = true;

    const input = document.getElementById('chatInput');
    const micBtn = document.getElementById('chatMic');
    const savedPlaceholder = input.placeholder;

    recognition.onstart = function () {
      isListening = true;
      micBtn.classList.add('listening');
      input.placeholder = 'Escuchando...';
      input.value = '';
    };

    recognition.onresult = function (e) {
      let interim = '';
      let finalTranscript = '';
      for (let i = e.resultIndex; i < e.results.length; i++) {
        if (e.results[i].isFinal) {
          finalTranscript += e.results[i][0].transcript;
        } else {
          interim += e.results[i][0].transcript;
        }
      }
      if (finalTranscript) {
        input.value = finalTranscript;
      } else {
        input.value = interim;
      }
    };

    recognition.onend = function () {
      isListening = false;
      micBtn.classList.remove('listening');
      input.placeholder = savedPlaceholder;
      recognition = null;
      // Auto-send if we got text
      if (input.value.trim()) {
        sendMessage();
      }
    };

    recognition.onerror = function (e) {
      isListening = false;
      micBtn.classList.remove('listening');
      input.placeholder = savedPlaceholder;
      recognition = null;
      if (e.error === 'no-speech' || e.error === 'audio-capture' || e.error === 'not-allowed') {
        showVoiceToast('No se detecto voz');
      }
    };

    recognition.start();
  }

  function stopVoice() {
    if (recognition) {
      recognition.abort();
      recognition = null;
    }
    isListening = false;
    const micBtn = document.getElementById('chatMic');
    if (micBtn) micBtn.classList.remove('listening');
  }

  function showVoiceToast(msg) {
    const toast = document.createElement('div');
    toast.className = 'chat-voice-toast';
    toast.textContent = msg;
    document.body.appendChild(toast);
    setTimeout(function () { toast.classList.add('visible'); }, 10);
    setTimeout(function () {
      toast.classList.remove('visible');
      setTimeout(function () { toast.remove(); }, 300);
    }, 2000);
  }

  // ─── TTS (Text-to-Speech) ───
  function toggleTTS() {
    ttsEnabled = !ttsEnabled;
    const btn = document.getElementById('chatTtsToggle');
    if (btn) {
      btn.classList.toggle('off', !ttsEnabled);
      btn.setAttribute('title', ttsEnabled ? 'Desactivar lectura de respuestas' : 'Activar lectura de respuestas');
    }
    if (!ttsEnabled) stopSpeaking();
  }

  function speak(text) {
    if (!hasTTS || !ttsEnabled || !text) return;
    stopSpeaking();
    ttsUtterance = new SpeechSynthesisUtterance(text);
    ttsUtterance.lang = 'es-MX';
    ttsUtterance.rate = 1.1;
    ttsUtterance.pitch = 1;
    window.speechSynthesis.speak(ttsUtterance);
  }

  function stopSpeaking() {
    if (hasTTS && window.speechSynthesis.speaking) {
      window.speechSynthesis.cancel();
    }
    ttsUtterance = null;
  }

  // ─── Image Upload (Part identification placeholder) ───
  function handleImageUpload(e) {
    const file = e.target.files && e.target.files[0];
    if (!file) return;

    // Reset input so the same file can be selected again
    e.target.value = '';

    // Validate file type and size (max 5MB)
    if (!file.type.startsWith('image/')) {
      addBubble('Solo se permiten imagenes.', 'ai');
      return;
    }
    if (file.size > 5 * 1024 * 1024) {
      addBubble('La imagen es muy grande (max 5MB).', 'ai');
      return;
    }

    // Show image thumbnail in chat
    const reader = new FileReader();
    reader.onload = function (ev) {
      const container = document.getElementById('chatMessages');
      const typing = document.getElementById('chatTyping');
      const div = document.createElement('div');
      div.className = 'chat-msg user chat-msg-image';
      div.innerHTML = '<img src="' + ev.target.result + '" alt="Foto de parte" style="max-width:180px;max-height:140px;border-radius:8px;display:block;margin-bottom:4px;">'
        + '<span>Identificar esta parte</span>';
      container.insertBefore(div, typing);
      scrollToBottom();

      // Send image to AI vision model for real analysis
      var imageData = ev.target.result;  // full data URL
      var photoPrompt = 'Identifica esta parte automotriz y sugiere terminos de busqueda.';
      history.push({ role: 'user', content: photoPrompt });
      if (history.length > 20) history.splice(0, 2);

      isSending = true;
      document.getElementById('chatSend').disabled = true;
      showTyping(true);

      var token = getToken();
      fetch('/pos/api/chat', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'Authorization': 'Bearer ' + token
        },
        body: JSON.stringify({
          message: photoPrompt,
          image: imageData,
          history: history.slice(-10)
        })
      })
        .then(function (resp) { return resp.json(); })
        .then(function (data) {
          const aiMsg = data.response || 'No pude identificar la parte. Intenta describirla con texto.';
          addBubble(aiMsg, 'ai');
          history.push({ role: 'assistant', content: aiMsg });

          if (data.vehicle && data.vehicle.brand_id) {
            addVehicleBanner(data.vehicle);
          }
          if (data.search_results && data.search_results.length > 0) {
            addPartResults(data.search_results);
          }
        })
        .catch(function (err) {
          addBubble('Error al procesar imagen: ' + err.message, 'ai');
        })
        .finally(function () {
          isSending = false;
          document.getElementById('chatSend').disabled = false;
          showTyping(false);
        });
    };
    reader.readAsDataURL(file);
  }

  function toggleChat() {
    isOpen = !isOpen;
    const panel = document.getElementById('chatPanel');
    const fab = document.getElementById('chatFab');
    if (isOpen) {
      panel.classList.add('open');
      fab.style.display = 'none';
      document.getElementById('chatInput').focus();
    } else {
      panel.classList.remove('open');
      fab.style.display = 'flex';
    }
  }

  function getToken() {
    // app-init.js stores token in window.__pos or localStorage
    if (window.__pos && window.__pos.token) return window.__pos.token;
    return localStorage.getItem('pos_token') || '';
  }

  // ─── Send message ───
  async function sendMessage() {
    if (isSending) return;
    const input = document.getElementById('chatInput');
    const text = input.value.trim();
    if (!text) return;

    input.value = '';
    input.style.height = 'auto';

    // Add user bubble
    addBubble(text, 'user');

    // Keep history for context (last 10 exchanges)
    history.push({ role: 'user', content: text });
    if (history.length > 20) history.splice(0, 2);

    // Show typing
    isSending = true;
    document.getElementById('chatSend').disabled = true;
    showTyping(true);

    try {
      const token = getToken();
      const resp = await fetch('/pos/api/chat', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'Authorization': 'Bearer ' + token
        },
        body: JSON.stringify({
          message: text,
          history: history.slice(-10)
        })
      });

      const data = await resp.json();
      if (!resp.ok) {
        addBubble('Error: ' + (data.error || resp.statusText), 'ai');
        return;
      }

      // AI response bubble
      const aiMsg = data.response || 'Sin respuesta.';
      addBubble(aiMsg, 'ai');
      history.push({ role: 'assistant', content: aiMsg });
      speak(aiMsg);

      // Vehicle info
      if (data.vehicle && data.vehicle.brand_id) {
        addVehicleBanner(data.vehicle);
      }

      // Search results
      if (data.search_results && data.search_results.length > 0) {
        addPartResults(data.search_results);
      }

    } catch (err) {
      addBubble('Error de conexion: ' + err.message, 'ai');
    } finally {
      isSending = false;
      document.getElementById('chatSend').disabled = false;
      showTyping(false);
    }
  }

  // ─── DOM helpers ───
  function addBubble(text, role) {
    const container = document.getElementById('chatMessages');
    const typing = document.getElementById('chatTyping');
    const div = document.createElement('div');
    div.className = 'chat-msg ' + role;
    div.textContent = text;
    container.insertBefore(div, typing);
    scrollToBottom();
  }

  function addVehicleBanner(vehicle) {
    const container = document.getElementById('chatMessages');
    const typing = document.getElementById('chatTyping');
    const div = document.createElement('div');
    div.className = 'chat-vehicle-banner';

    let html = '<strong>' + esc(vehicle.brand || '') + ' ' + esc(vehicle.model || '') + '</strong>';
    if (vehicle.year) html += ' ' + vehicle.year;

    if (vehicle.mye_options && vehicle.mye_options.length > 0) {
      html += '<br>Motorizaciones encontradas:';
      vehicle.mye_options.forEach(function (opt) {
        html += '<br>&bull; ' + esc(opt.engine);
        if (opt.trim) html += ' (' + esc(opt.trim) + ')';
      });
    }

    div.innerHTML = html;
    container.insertBefore(div, typing);
    scrollToBottom();
  }

  function addPartResults(parts) {
    const container = document.getElementById('chatMessages');
    const typing = document.getElementById('chatTyping');

    const wrapper = document.createElement('div');
    wrapper.className = 'chat-parts';

    parts.slice(0, 8).forEach(function (p) {
      const card = document.createElement('div');
      card.className = 'chat-part-card';

      const isLocal = p.source === 'local';
      const stockQty = p.local_stock || 0;
      const stockClass = stockQty > 0 ? 'in-stock' : '';
      const stockText = stockQty > 0 ? (stockQty + ' en stock') : 'Sin stock local';
      const name = p.name_es || p.name_part || '';
      const partNum = p.oem_part_number || p.part_number || '';
      const brand = p.brand || '';
      const priceText = p.price_1 ? ('$' + parseFloat(p.price_1).toFixed(2)) : '';
      const sourceTag = isLocal
        ? '<span style="background:var(--color-success);color:#fff;padding:1px 6px;border-radius:4px;font-size:0.65rem;margin-left:6px;">MI INVENTARIO</span>'
        : '<span style="background:var(--color-primary);color:#fff;padding:1px 6px;border-radius:4px;font-size:0.65rem;margin-left:6px;">CATÁLOGO</span>';

      card.innerHTML =
        '<div class="part-number">' + esc(partNum) + sourceTag + (priceText ? ' &mdash; ' + priceText : '') + '</div>' +
        '<div class="part-name">' + esc(name) + (brand ? ' <span style="color:var(--color-text-muted);">(' + esc(brand) + ')</span>' : '') + '</div>' +
        '<div class="part-stock ' + stockClass + '">' + esc(stockText) + '</div>';

      // Click to open detail (if catalog page has a detail function)
      card.addEventListener('click', function () {
        if (p.id_part && typeof window.openPartDetail === 'function') {
          window.openPartDetail(p.id_part);
          toggleChat();
        }
      });

      wrapper.appendChild(card);
    });

    container.insertBefore(wrapper, typing);
    scrollToBottom();
  }

  function showTyping(show) {
    const el = document.getElementById('chatTyping');
    if (el) el.classList.toggle('visible', show);
    if (show) scrollToBottom();
  }

  function scrollToBottom() {
    const el = document.getElementById('chatMessages');
    if (el) el.scrollTop = el.scrollHeight;
  }

  function esc(s) {
    const d = document.createElement('div');
    d.textContent = s;
    return d.innerHTML;
  }

  // ─── Init when DOM ready ───
  if (document.readyState === 'loading') {
    document.addEventListener('DOMContentLoaded', init);
  } else {
    init();
  }
})();
