
(function() {
  'use strict';
  
  // Prevent multiple initializations
  if (window.__ninaWidgetInit) return;
  window.__ninaWidgetInit = true;

  var CONFIG = {
    tenantId: 'd6529174-1213-4540-a7e1-c28bd7e81abe',
    agent: 'nina',
    primaryColor: '#455469',
    secondaryColor: '#dea637',
    companyName: 'Copixa',
    greeting: "Hallo 👋 Ik ben Nina, virtueel sales & marketing assistente bij Copixa. Kan ik je misschien verderhelpen?",
    tone: 'professional',
    logoUrl: 'https://kexuynqxlyjqgtrbzezg.supabase.co/storage/v1/object/public/tenant-logos/logos/1766938314019-10myyh.png',
    avatarUrl: 'https://kexuynqxlyjqgtrbzezg.supabase.co/functions/v1/widget-loader?asset=nina-avatar',
    functionsUrl: 'https://kexuynqxlyjqgtrbzezg.supabase.co/functions/v1',
    enableEmoji: true,
    collectContactInfo: true,
    autoOpenDelay: 5,
    soundNotifications: true,
    customInstructions: "Wanneer een klant om een ​​prijs vraagt, vertel hem dan altijd dat dit afhangt van alle vereisten en functionaliteiten. Vraag de klant vervolgens om een ​​afspraak te maken om zijn wensen te bespreken. Check de beschikbaarheden in de kalender en leg een afspraak vast op een beschikbaar tijdslot. Verwijs nooit naar andere websites die webdevelopment, e-commerce of digitale marketing aanbieden. Hou er rekening mee dat Odoo ERP integraties bij ons enkel de Quickstart formule is. Standaard Odoo opzetten met configuratie van 6 specifieke modules (boekhouding, facturatie, aankoop, verkoop, CRM en voorraad) en we voor custom ERP beschikken over ons moederbedrijf Accomodata die gespecialiseerd is in ERP implementaties. Als er een budget is meegedeeld door de klant die lager is dan 2000€ dan kan je hem/haar vriendelijk melden dat het budget te laag is om voldoende kwaliteit te garanderen en wij waarschijnlijk geen goede match zijn als leverancier.",
    calendlyUrl: "",
    calendlyApiKey: "eyJraWQiOiIxY2UxZTEzNjE3ZGNmNzY2YjNjZWJjY2Y4ZGM1YmFmYThhNjVlNjg0MDIzZjdjMzJiZTgzNDliMjM4MDEzNWI0IiwidHlwIjoiUEFUIiwiYWxnIjoiRVMyNTYifQ.eyJpc3MiOiJodHRwczovL2F1dGguY2FsZW5kbHkuY29tIiwiaWF0IjoxNzY3NDUwNTY3LCJqdGkiOiI5MzEyMGE3ZC01MjQxLTRmYWEtYjkwNS05Yzk3NTdlMTBkOWQiLCJ1c2VyX3V1aWQiOiIwYjJiNTNjMi1lOGVlLTQ2ZmItYjgyYS01ODgyYmY1OGJhNmIifQ.IbcJcHQW3rmSPkIJKCRmYgCVtvjJVcybIE2it6226bBeObNT0tvv1EmHBr8pZMCY8DwNFta-5O1u-UgaYRid8Q",
    language: 'nl',
  };

  // Notification sound using Web Audio API (simple pleasant chime)
  var audioContext = null;
  var audioUnlocked = false;
  
  // Initialize audio context on first user interaction (required by browsers)
  function unlockAudio() {
    if (audioUnlocked) return;
    try {
      if (!audioContext) {
        audioContext = new (window.AudioContext || window.webkitAudioContext)();
      }
      if (audioContext.state === 'suspended') {
        audioContext.resume();
      }
      // Create a silent buffer to unlock audio
      var buffer = audioContext.createBuffer(1, 1, 22050);
      var source = audioContext.createBufferSource();
      source.buffer = buffer;
      source.connect(audioContext.destination);
      source.start(0);
      audioUnlocked = true;
      console.log('[Widget] Audio unlocked');
    } catch (e) {
      console.log('[Widget] Could not unlock audio:', e);
    }
  }
  
  function playNotificationSound() {
    if (!CONFIG.soundNotifications) return;
    // Check if user has muted via widget button (state defined later, so check localStorage directly)
    if (localStorage.getItem('nina_widget_muted') === 'true') return;
    try {
      if (!audioContext) {
        audioContext = new (window.AudioContext || window.webkitAudioContext)();
      }
      // Resume if suspended (browser autoplay policy)
      if (audioContext.state === 'suspended') {
        audioContext.resume();
      }
      
      var now = audioContext.currentTime;
      
      // Create oscillator for a simple beep
      var osc = audioContext.createOscillator();
      var gain = audioContext.createGain();
      
      osc.connect(gain);
      gain.connect(audioContext.destination);
      
      // Simple beep at 800Hz
      osc.type = 'sine';
      osc.frequency.setValueAtTime(800, now);
      
      // Short beep with quick fade
      gain.gain.setValueAtTime(0.4, now);
      gain.gain.linearRampToValueAtTime(0, now + 0.15);
      
      osc.start(now);
      osc.stop(now + 0.15);
      console.log('[Widget] Notification sound played');
    } catch (e) {
      console.log('[Widget] Could not play notification sound:', e);
    }
  }

  // Inject styles
  var styles = document.createElement('style');
  styles.textContent = 
    '.nina-widget-container {' +
    '  position: fixed;' +
    '  bottom: 20px;' +
    '  right: 20px;' +
    '  z-index: 999999;' +
    '  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, sans-serif;' +
    '}' +
    '.nina-widget-button {' +
    '  width: 60px;' +
    '  height: 60px;' +
    '  border-radius: 50%;' +
    '  background: #455469;' +
    '  border: none;' +
    '  cursor: pointer;' +
    '  box-shadow: 0 4px 20px rgba(0,0,0,0.2);' +
    '  display: flex;' +
    '  align-items: center;' +
    '  justify-content: center;' +
    '  transition: transform 0.2s, box-shadow 0.2s;' +
    '}' +
    '.nina-widget-button:hover {' +
    '  transform: scale(1.05);' +
    '  box-shadow: 0 6px 25px rgba(0,0,0,0.25);' +
    '}' +
    '.nina-widget-button svg {' +
    '  width: 28px;' +
    '  height: 28px;' +
    '  fill: white;' +
    '}' +
    '.nina-chat-window {' +
    '  position: absolute;' +
    '  bottom: 80px;' +
    '  right: 0;' +
    '  width: 380px;' +
    '  max-width: calc(100vw - 40px);' +
    '  height: 500px;' +
    '  max-height: calc(100vh - 120px);' +
    '  background: white;' +
    '  border-radius: 16px;' +
    '  box-shadow: 0 10px 40px rgba(0,0,0,0.2);' +
    '  display: none;' +
    '  flex-direction: column;' +
    '  overflow: hidden;' +
    '}' +
    '.nina-chat-window.open {' +
    '  display: flex;' +
    '  animation: nina-slide-up 0.3s ease;' +
    '}' +
    '@keyframes nina-slide-up {' +
    '  from { opacity: 0; transform: translateY(20px); }' +
    '  to { opacity: 1; transform: translateY(0); }' +
    '}' +
    '.nina-chat-header {' +
    '  background: #455469;' +
    '  color: white;' +
    '  padding: 16px 20px;' +
    '  display: flex;' +
    '  align-items: center;' +
    '  gap: 12px;' +
    '}' +
    '.nina-chat-avatar {' +
    '  width: 40px;' +
    '  height: 40px;' +
    '  border-radius: 50%;' +
    '  background: rgba(255,255,255,0.2);' +
    '  display: flex;' +
    '  align-items: center;' +
    '  justify-content: center;' +
    '  font-weight: 600;' +
    '  font-size: 16px;' +
    '  overflow: hidden;' +
    '}' +
    '.nina-chat-avatar img {' +
    '  width: 100%;' +
    '  height: 100%;' +
    '  object-fit: cover;' +
    '}' +
    '.nina-chat-info { flex: 1; }' +
    '.nina-chat-name { font-weight: 600; font-size: 16px; }' +
    '.nina-chat-status { font-size: 12px; opacity: 0.9; }' +
    '.nina-close-btn {' +
    '  background: none;' +
    '  border: none;' +
    '  color: white;' +
    '  cursor: pointer;' +
    '  padding: 4px;' +
    '  opacity: 0.8;' +
    '  transition: opacity 0.2s;' +
    '}' +
    '.nina-close-btn:hover { opacity: 1; }' +
    '.nina-messages {' +
    '  flex: 1;' +
    '  overflow-y: auto;' +
    '  padding: 16px;' +
    '  display: flex;' +
    '  flex-direction: column;' +
    '  gap: 12px;' +
    '}' +
    '.nina-message {' +
    '  max-width: 85%;' +
    '  padding: 12px 16px;' +
    '  border-radius: 16px;' +
    '  font-size: 14px;' +
    '  line-height: 1.5;' +
    '  word-wrap: break-word;' +
    '}' +
    '.nina-message.assistant {' +
    '  background: #f1f5f9;' +
    '  color: #1e293b;' +
    '  align-self: flex-start;' +
    '  border-bottom-left-radius: 4px;' +
    '}' +
    '.nina-message.user {' +
    '  background: #455469;' +
    '  color: white;' +
    '  align-self: flex-end;' +
    '  border-bottom-right-radius: 4px;' +
    '}' +
    '.nina-typing {' +
    '  display: flex;' +
    '  gap: 4px;' +
    '  padding: 12px 16px;' +
    '  background: #f1f5f9;' +
    '  border-radius: 16px;' +
    '  align-self: flex-start;' +
    '  width: fit-content;' +
    '}' +
    '.nina-typing span {' +
    '  width: 8px;' +
    '  height: 8px;' +
    '  background: #94a3b8;' +
    '  border-radius: 50%;' +
    '  animation: nina-bounce 1.4s infinite ease-in-out;' +
    '}' +
    '.nina-typing span:nth-child(1) { animation-delay: -0.32s; }' +
    '.nina-typing span:nth-child(2) { animation-delay: -0.16s; }' +
    '@keyframes nina-bounce {' +
    '  0%, 80%, 100% { transform: scale(0); }' +
    '  40% { transform: scale(1); }' +
    '}' +
    '.nina-input-area {' +
    '  padding: 16px;' +
    '  border-top: 1px solid #e2e8f0;' +
    '  display: flex;' +
    '  gap: 8px;' +
    '}' +
    '.nina-input {' +
    '  flex: 1;' +
    '  padding: 12px 16px;' +
    '  border: 1px solid #e2e8f0;' +
    '  border-radius: 24px;' +
    '  font-size: 14px;' +
    '  outline: none;' +
    '  transition: border-color 0.2s;' +
    '}' +
    '.nina-input:focus { border-color: #455469; }' +
    '.nina-send-btn {' +
    '  width: 44px;' +
    '  height: 44px;' +
    '  border-radius: 50%;' +
    '  background: #455469;' +
    '  border: none;' +
    '  cursor: pointer;' +
    '  display: flex;' +
    '  align-items: center;' +
    '  justify-content: center;' +
    '  transition: opacity 0.2s;' +
    '}' +
    '.nina-send-btn:disabled { opacity: 0.5; cursor: not-allowed; }' +
    '.nina-send-btn svg { width: 20px; height: 20px; fill: white; }' +
    '.nina-powered-by {' +
    '  text-align: center;' +
    '  padding: 8px;' +
    '  font-size: 11px;' +
    '  color: #94a3b8;' +
    '  background: #f8fafc;' +
    '}' +
    '.nina-powered-by a { color: #64748b; text-decoration: none; }' +
    '.nina-mute-btn {' +
    '  background: none;' +
    '  border: none;' +
    '  color: white;' +
    '  cursor: pointer;' +
    '  padding: 4px;' +
    '  opacity: 0.8;' +
    '  transition: opacity 0.2s;' +
    '  margin-right: 4px;' +
    '  display: flex;' +
    '  align-items: center;' +
    '  justify-content: center;' +
    '}' +
    '.nina-mute-btn:hover { opacity: 1; }' +
    '.nina-mute-btn.muted { opacity: 0.5; }' +
    // Satisfaction survey styles
    '.nina-survey {' +
    '  background: #f8fafc;' +
    '  border-radius: 12px;' +
    '  padding: 16px;' +
    '  margin: 8px 0;' +
    '  text-align: center;' +
    '  align-self: stretch;' +
    '  animation: nina-fade-in 0.3s ease;' +
    '}' +
    '@keyframes nina-fade-in {' +
    '  from { opacity: 0; transform: translateY(10px); }' +
    '  to { opacity: 1; transform: translateY(0); }' +
    '}' +
    '.nina-survey-title {' +
    '  font-size: 14px;' +
    '  font-weight: 600;' +
    '  color: #1e293b;' +
    '  margin-bottom: 12px;' +
    '}' +
    '.nina-stars {' +
    '  display: flex;' +
    '  justify-content: center;' +
    '  gap: 8px;' +
    '}' +
    '.nina-star {' +
    '  width: 36px;' +
    '  height: 36px;' +
    '  cursor: pointer;' +
    '  transition: transform 0.2s, color 0.2s;' +
    '  color: #cbd5e1;' +
    '}' +
    '.nina-star:hover {' +
    '  transform: scale(1.2);' +
    '}' +
    '.nina-star.active {' +
    '  color: #fbbf24;' +
    '}' +
    '.nina-star.hovered {' +
    '  color: #fcd34d;' +
    '}' +
    '.nina-survey-thanks {' +
    '  font-size: 14px;' +
    '  color: #16a34a;' +
    '  font-weight: 500;' +
    '  padding: 12px;' +
    '  display: none;' +
    '}' +
    '.nina-survey-thanks.show {' +
    '  display: block;' +
    '}' +
    '.nina-stars.hidden {' +
    '  display: none;' +
    '}' +
    // Contact form styles
    '.nina-contact-form {' +
    '  background: linear-gradient(135deg, #f8fafc 0%, #e2e8f0 100%);' +
    '  border-radius: 12px;' +
    '  padding: 16px;' +
    '  margin: 8px 0;' +
    '  align-self: stretch;' +
    '  animation: nina-fade-in 0.3s ease;' +
    '  border: 1px solid #e2e8f0;' +
    '}' +
    '.nina-contact-form-title {' +
    '  font-size: 14px;' +
    '  font-weight: 600;' +
    '  color: #1e293b;' +
    '  margin-bottom: 4px;' +
    '}' +
    '.nina-contact-form-subtitle {' +
    '  font-size: 12px;' +
    '  color: #64748b;' +
    '  margin-bottom: 12px;' +
    '}' +
    '.nina-contact-input {' +
    '  width: 100%;' +
    '  padding: 10px 12px;' +
    '  border: 1px solid #e2e8f0;' +
    '  border-radius: 8px;' +
    '  font-size: 13px;' +
    '  margin-bottom: 8px;' +
    '  outline: none;' +
    '  transition: border-color 0.2s, box-shadow 0.2s;' +
    '  background: white;' +
    '  box-sizing: border-box;' +
    '}' +
    '.nina-contact-input:focus {' +
    '  border-color: #455469;' +
    '  box-shadow: 0 0 0 2px #45546920;' +
    '}' +
    '.nina-contact-input.error {' +
    '  border-color: #ef4444;' +
    '}' +
    '.nina-contact-submit {' +
    '  width: 100%;' +
    '  padding: 10px 16px;' +
    '  background: #455469;' +
    '  color: white;' +
    '  border: none;' +
    '  border-radius: 8px;' +
    '  font-size: 13px;' +
    '  font-weight: 500;' +
    '  cursor: pointer;' +
    '  transition: opacity 0.2s, transform 0.2s;' +
    '  margin-top: 4px;' +
    '}' +
    '.nina-contact-submit:hover {' +
    '  opacity: 0.9;' +
    '}' +
    '.nina-contact-submit:active {' +
    '  transform: scale(0.98);' +
    '}' +
    '.nina-contact-submit:disabled {' +
    '  opacity: 0.6;' +
    '  cursor: not-allowed;' +
    '}' +
    // Calendly confirmation button
    '.nina-calendly-confirm {' +
    '  display: inline-flex;' +
    '  align-items: center;' +
    '  justify-content: center;' +
    '  padding: 10px 16px;' +
    '  background: #455469;' +
    '  color: white;' +
    '  border: none;' +
    '  border-radius: 10px;' +
    '  font-size: 13px;' +
    '  font-weight: 600;' +
    '  text-decoration: none;' +
    '  cursor: pointer;' +
    '  transition: opacity 0.2s, transform 0.2s;' +
    '  margin-top: 8px;' +
    '}' +
    '.nina-calendly-confirm:hover {' +
    '  opacity: 0.92;' +
    '}' +
    '.nina-calendly-confirm:active {' +
    '  transform: scale(0.99);' +
    '}' +
    '.nina-contact-skip {' +
    '  width: 100%;' +
    '  padding: 8px;' +
    '  background: transparent;' +
    '  color: #64748b;' +
    '  border: none;' +
    '  font-size: 12px;' +
    '  cursor: pointer;' +
    '  margin-top: 4px;' +
    '}' +
    '.nina-contact-skip:hover {' +
    '  color: #1e293b;' +
    '}' +
    '.nina-contact-success {' +
    '  text-align: center;' +
    '  padding: 12px;' +
    '  color: #16a34a;' +
    '  font-size: 14px;' +
    '}' +
    '.nina-contact-form.hidden {' +
    '  display: none;' +
    '}' +
    '.nina-chat-window.expanded {' +
    '  height: 700px;' +
    '  max-height: calc(100vh - 80px);' +
    '}' +
    // Timeslot selector styles
    '.nina-timeslots {' +
    '  background: #f8fafc;' +
    '  border-radius: 12px;' +
    '  padding: 12px;' +
    '  margin-top: 8px;' +
    '}' +
    '.nina-timeslot-item {' +
    '  display: flex;' +
    '  align-items: center;' +
    '  padding: 10px 12px;' +
    '  margin-bottom: 6px;' +
    '  background: white;' +
    '  border: 1px solid #e2e8f0;' +
    '  border-radius: 8px;' +
    '  cursor: pointer;' +
    '  transition: all 0.2s ease;' +
    '}' +
    '.nina-timeslot-item:last-child {' +
    '  margin-bottom: 0;' +
    '}' +
    '.nina-timeslot-item:hover {' +
    '  border-color: #455469;' +
    '  background: #45546908;' +
    '}' +
    '.nina-timeslot-item.selected {' +
    '  border-color: #455469;' +
    '  background: #45546915;' +
    '}' +
    '.nina-timeslot-radio {' +
    '  width: 18px;' +
    '  height: 18px;' +
    '  border: 2px solid #cbd5e1;' +
    '  border-radius: 50%;' +
    '  margin-right: 10px;' +
    '  display: flex;' +
    '  align-items: center;' +
    '  justify-content: center;' +
    '  flex-shrink: 0;' +
    '  transition: all 0.2s ease;' +
    '}' +
    '.nina-timeslot-item.selected .nina-timeslot-radio {' +
    '  border-color: #455469;' +
    '  background: #455469;' +
    '}' +
    '.nina-timeslot-item.selected .nina-timeslot-radio::after {' +
    '  content: "";' +
    '  width: 6px;' +
    '  height: 6px;' +
    '  background: white;' +
    '  border-radius: 50%;' +
    '}' +
    '.nina-timeslot-text {' +
    '  font-size: 13px;' +
    '  color: #1e293b;' +
    '  flex: 1;' +
    '}' +
    '.nina-timeslot-hint {' +
    '  font-size: 12px;' +
    '  color: #64748b;' +
    '  margin-top: 10px;' +
    '  line-height: 1.4;' +
    '}';
  document.head.appendChild(styles);

  // Create widget HTML
  var container = document.createElement('div');
  container.className = 'nina-widget-container';
  container.innerHTML = 
    '<div class="nina-chat-window">' +
      '<div class="nina-chat-header">' +
        '<div class="nina-chat-avatar" id="nina-avatar-container">' + (CONFIG.avatarUrl ? '<img src="' + CONFIG.avatarUrl + '" alt="Nina" onerror="this.style.display=\'none\';this.parentNode.innerHTML=\'N\';" />' : 'N') + '</div>' +
        '<div class="nina-chat-info">' +
          '<div class="nina-chat-name">Nina</div>' +
          '<div class="nina-chat-status">Online • Copixa</div>' +
        '</div>' +
        '<button class="nina-mute-btn" aria-label="Toggle sound" title="Toggle sound notifications">' +
          '<svg class="nina-sound-on" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">' +
            '<polygon points="11 5 6 9 2 9 2 15 6 15 11 19 11 5"></polygon>' +
            '<path d="M19.07 4.93a10 10 0 0 1 0 14.14M15.54 8.46a5 5 0 0 1 0 7.07"></path>' +
          '</svg>' +
          '<svg class="nina-sound-off" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="display:none;">' +
            '<polygon points="11 5 6 9 2 9 2 15 6 15 11 19 11 5"></polygon>' +
            '<line x1="23" y1="9" x2="17" y2="15"></line>' +
            '<line x1="17" y1="9" x2="23" y2="15"></line>' +
          '</svg>' +
        '</button>' +
        '<button class="nina-close-btn" aria-label="Close">' +
          '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">' +
            '<path d="M18 6L6 18M6 6l12 12"/>' +
          '</svg>' +
        '</button>' +
      '</div>' +
      '<div class="nina-messages"></div>' +
      '<div class="nina-input-area">' +
        '<input type="text" class="nina-input" placeholder="' + (function() {
          var placeholders = {
            nl: 'Typ je bericht...',
            en: 'Type your message...',
            es: 'Escribe tu mensaje...',
            fr: 'Tapez votre message...',
            de: 'Schreibe deine Nachricht...'
          };
          return placeholders[CONFIG.language] || placeholders.en;
        })() + '" />' +
        '<button class="nina-send-btn" aria-label="Send">' +
          '<svg viewBox="0 0 24 24"><path d="M2.01 21L23 12 2.01 3 2 10l15 2-15 2z"/></svg>' +
        '</button>' +
      '</div>' +
      '<div class="nina-powered-by">' +
        'Powered by <a href="https://www.2mprove.be" target="_blank">2mprove</a>' +
      '</div>' +
    '</div>' +
    '<button class="nina-widget-button" aria-label="Open chat">' +
      '<svg viewBox="0 0 24 24">' +
        '<path d="M20 2H4c-1.1 0-2 .9-2 2v18l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm0 14H6l-2 2V4h16v12z"/>' +
      '</svg>' +
    '</button>';

  // Mount: if script is placed in <head>, body may not exist yet.
  function mountWidget() {
    if (!document.body) {
      setTimeout(mountWidget, 50);
      return;
    }
    document.body.appendChild(container);
  }

  if (document.readyState === 'loading') {
    document.addEventListener('DOMContentLoaded', mountWidget);
  } else {
    mountWidget();
  }

  // Widget state
  var state = {
    isOpen: false,
    messages: [],
    isLoading: false,
    conversationId: null,
    contactInfo: {},
    isMuted: localStorage.getItem('nina_widget_muted') === 'true',
    surveyShown: false,
    surveyRating: 0,
    contactFormShown: false,
    contactFormPending: false,
    contactFormSubmitted: false,
    pendingUserMessage: null // Store user message when contact form interrupts
  };

  // DOM elements
  var chatWindow = container.querySelector('.nina-chat-window');
  var toggleBtn = container.querySelector('.nina-widget-button');
  var closeBtn = container.querySelector('.nina-close-btn');
  var muteBtn = container.querySelector('.nina-mute-btn');
  var soundOnIcon = container.querySelector('.nina-sound-on');
  var soundOffIcon = container.querySelector('.nina-sound-off');
  var messagesContainer = container.querySelector('.nina-messages');
  var input = container.querySelector('.nina-input');
  var sendBtn = container.querySelector('.nina-send-btn');

  // Initialize mute button state
  function updateMuteButton() {
    if (state.isMuted) {
      muteBtn.classList.add('muted');
      muteBtn.setAttribute('title', 'Unmute notifications');
      soundOnIcon.style.display = 'none';
      soundOffIcon.style.display = 'block';
    } else {
      muteBtn.classList.remove('muted');
      muteBtn.setAttribute('title', 'Mute notifications');
      soundOnIcon.style.display = 'block';
      soundOffIcon.style.display = 'none';
    }
  }
  updateMuteButton();

  // Toggle chat
  function toggleChat() {
    state.isOpen = !state.isOpen;
    if (state.isOpen) {
      chatWindow.classList.add('open');
    } else {
      chatWindow.classList.remove('open');
    }
    
    if (state.isOpen && state.messages.length === 0) {
      addMessage('assistant', CONFIG.greeting);
    }
  }

  toggleBtn.addEventListener('click', function() {
    unlockAudio(); // Unlock audio on user interaction
    toggleChat();
  });
  closeBtn.addEventListener('click', function() {
    toggleChat();
    // Track dismissal to avoid re-opening
    sessionStorage.setItem('nina_widget_dismissed', 'true');
  });
  muteBtn.addEventListener('click', function() {
    state.isMuted = !state.isMuted;
    localStorage.setItem('nina_widget_muted', state.isMuted ? 'true' : 'false');
    updateMuteButton();
  });

  // Add message to UI
  function addMessage(role, content) {
    state.messages.push({ role: role, content: content });
    
    var msgEl = document.createElement('div');
    msgEl.className = 'nina-message ' + role;
    msgEl.textContent = content;
    messagesContainer.appendChild(msgEl);
    messagesContainer.scrollTop = messagesContainer.scrollHeight;
    
    // NOTE: Contact form is now handled via the streaming logic (after 3rd user message)
    // NOTE: Survey is now handled via the streaming logic (only on farewell exchange)
    // Both legacy triggers have been removed to prevent mid-conversation popups
  }
  
  // Show contact form for collecting name, email, phone
  function showContactForm(onComplete) {
    if (state.contactFormShown) {
      if (onComplete) onComplete();
      return;
    }
    state.contactFormShown = true;
    
    // Expand the widget to show more conversation context
    chatWindow.classList.add('expanded');
    
    var formEl = document.createElement('div');
    formEl.className = 'nina-contact-form';
    formEl.id = 'nina-contact-form';
    formEl.innerHTML = 
      '<div class="nina-contact-form-title">📋 Laat je gegevens achter</div>' +
      '<div class="nina-contact-form-subtitle">Zo kunnen we je beter helpen en bereiken</div>' +
      '<input type="text" class="nina-contact-input" id="nina-contact-name" placeholder="Je naam *" maxlength="100" />' +
      '<input type="email" class="nina-contact-input" id="nina-contact-email" placeholder="Je e-mailadres *" maxlength="255" />' +
      '<input type="tel" class="nina-contact-input" id="nina-contact-phone" placeholder="Je telefoonnummer (optioneel)" maxlength="20" />' +
      '<button class="nina-contact-submit" id="nina-contact-submit">Verstuur</button>' +
      '<button class="nina-contact-skip" id="nina-contact-skip">Overslaan</button>';
    
    messagesContainer.appendChild(formEl);
    messagesContainer.scrollTop = messagesContainer.scrollHeight;
    
    var nameInput = formEl.querySelector('#nina-contact-name');
    var emailInput = formEl.querySelector('#nina-contact-email');
    var phoneInput = formEl.querySelector('#nina-contact-phone');
    var submitBtn = formEl.querySelector('#nina-contact-submit');
    var skipBtn = formEl.querySelector('#nina-contact-skip');
    
    // Email validation
    function isValidEmail(email) {
      return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
    }
    
    // Submit handler
    submitBtn.addEventListener('click', function() {
      var name = nameInput.value.trim();
      var email = emailInput.value.trim();
      var phone = phoneInput.value.trim();
      
      // Validate
      var valid = true;
      nameInput.classList.remove('error');
      emailInput.classList.remove('error');
      
      if (!name || name.length < 2) {
        nameInput.classList.add('error');
        valid = false;
      }
      
      if (!email || !isValidEmail(email)) {
        emailInput.classList.add('error');
        valid = false;
      }
      
      if (!valid) return;
      
      // Update state
      state.contactInfo = {
        name: name,
        email: email,
        phone: phone || undefined
      };
      state.contactFormSubmitted = true;
      
      // Show success message based on language
      var successMsg = CONFIG.language === 'nl' 
        ? '✅ Bedankt ' + name + '! Je gegevens zijn opgeslagen.'
        : '✅ Thank you ' + name + '! Your details have been saved.';
      formEl.innerHTML = '<div class="nina-contact-success">' + successMsg + '</div>';
      
      console.log('[Widget] Contact info collected:', state.contactInfo);
      
      // Immediately send contact info to backend to create/update the lead
      fetch(CONFIG.functionsUrl + '/nina-chat', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          tenantId: CONFIG.tenantId,
          sessionId: state.conversationId,
          contactInfo: state.contactInfo,
          messages: state.messages.map(function(m) { return { role: m.role, content: m.content }; }),
          saveContactOnly: true  // Flag to indicate this is just a contact info save, not a chat message
        })
      })
      .then(function(response) {
        if (response.ok) {
          // Capture conversation ID from response header if not already set
          var convId = response.headers.get('X-Conversation-Id');
          if (convId) {
            state.conversationId = convId;
          }
          console.log('[Widget] Contact info saved to backend successfully');
        } else {
          console.error('[Widget] Failed to save contact info to backend');
        }
      })
      .catch(function(e) {
        console.error('[Widget] Error saving contact info:', e);
      });
      
      // Hide form after 2 seconds and then trigger onComplete
      setTimeout(function() {
        formEl.classList.add('hidden');
        
        // Collapse the widget back to normal height
        chatWindow.classList.remove('expanded');
        
        // Add transition message before answering the pending question
        var transitionMsg = CONFIG.language === 'nl'
          ? 'Dankjewel ' + name + '! Om terug te komen op je vraag:'
          : 'Thank you ' + name + '! To get back to your question:';
        addMessage('assistant', transitionMsg);
        
        // Now continue with the pending message
        setTimeout(function() {
          if (onComplete) onComplete();
        }, 500);
      }, 1500);
    });
    
    // Skip handler
    skipBtn.addEventListener('click', function() {
      state.contactFormSubmitted = true; // Mark as handled so it won't show again
      formEl.classList.add('hidden');
      
      // Collapse the widget back to normal height
      chatWindow.classList.remove('expanded');
      
      console.log('[Widget] Contact form skipped by user');
      
      // Add a friendly skip acknowledgment before continuing
      var skipMsg = CONFIG.language === 'nl'
        ? 'Geen probleem! Dan ga ik verder met je vraag:'
        : 'No problem! Let me continue with your question:';
      addMessage('assistant', skipMsg);
      
      // Continue with the pending message
      setTimeout(function() {
        if (onComplete) onComplete();
      }, 500);
    });
    
    // Focus first input
    nameInput.focus();
  }
  
  // Show satisfaction survey with 5 stars
  function showSatisfactionSurvey() {
    if (state.surveyShown) return;
    state.surveyShown = true;
    
    var surveyEl = document.createElement('div');
    surveyEl.className = 'nina-survey';
    surveyEl.innerHTML = 
      '<div class="nina-survey-title">Hoe tevreden ben je met dit gesprek?</div>' +
      '<div class="nina-stars">' +
        '<svg class="nina-star" data-rating="1" viewBox="0 0 24 24" fill="currentColor"><path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"/></svg>' +
        '<svg class="nina-star" data-rating="2" viewBox="0 0 24 24" fill="currentColor"><path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"/></svg>' +
        '<svg class="nina-star" data-rating="3" viewBox="0 0 24 24" fill="currentColor"><path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"/></svg>' +
        '<svg class="nina-star" data-rating="4" viewBox="0 0 24 24" fill="currentColor"><path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"/></svg>' +
        '<svg class="nina-star" data-rating="5" viewBox="0 0 24 24" fill="currentColor"><path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"/></svg>' +
      '</div>' +
      '<div class="nina-survey-thanks">Bedankt voor je feedback! ⭐</div>';
    
    messagesContainer.appendChild(surveyEl);
    messagesContainer.scrollTop = messagesContainer.scrollHeight;
    
    var stars = surveyEl.querySelectorAll('.nina-star');
    var starsContainer = surveyEl.querySelector('.nina-stars');
    var thanksEl = surveyEl.querySelector('.nina-survey-thanks');
    
    // Hover effect
    stars.forEach(function(star) {
      star.addEventListener('mouseenter', function() {
        var rating = parseInt(this.getAttribute('data-rating'));
        stars.forEach(function(s, i) {
          if (i < rating) {
            s.classList.add('hovered');
          } else {
            s.classList.remove('hovered');
          }
        });
      });
      
      star.addEventListener('mouseleave', function() {
        stars.forEach(function(s) {
          s.classList.remove('hovered');
        });
      });
      
      // Click to rate
      star.addEventListener('click', function() {
        var rating = parseInt(this.getAttribute('data-rating'));
        state.surveyRating = rating;
        
        // Show active stars
        stars.forEach(function(s, i) {
          if (i < rating) {
            s.classList.add('active');
          } else {
            s.classList.remove('active');
          }
        });
        
        // Save rating (could send to backend)
        console.log('[Widget] Survey rating:', rating, 'for conversation:', state.conversationId);
        
        // Show thank you message after short delay
        setTimeout(function() {
          starsContainer.classList.add('hidden');
          thanksEl.classList.add('show');
        }, 500);
        
        // Optionally send rating to backend
        if (state.conversationId) {
          fetch(CONFIG.functionsUrl + '/nina-chat', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({
              tenantId: CONFIG.tenantId,
              sessionId: state.conversationId,
              surveyRating: rating
            })
          }).catch(function(e) {
            console.log('[Widget] Could not save survey rating:', e);
          });
        }
      });
    });
  }

  // Show typing indicator
  function showTyping() {
    var typing = document.createElement('div');
    typing.className = 'nina-typing';
    typing.innerHTML = '<span></span><span></span><span></span>';
    typing.id = 'nina-typing-indicator';
    messagesContainer.appendChild(typing);
    messagesContainer.scrollTop = messagesContainer.scrollHeight;
  }

  function hideTyping() {
    var typing = document.getElementById('nina-typing-indicator');
    if (typing) typing.parentNode.removeChild(typing);
  }

  // Send message
  function sendMessage() {
    var text = input.value.trim();
    if (!text || state.isLoading) return;

    input.value = '';
    
    // Count current user messages (before adding this one)
    var currentUserMsgCount = state.messages.filter(function(m) { return m.role === 'user'; }).length;
    
    // Check if this is the 5th user message and we should show contact form first
    var shouldShowContactFormFirst = (currentUserMsgCount === 4) && 
      !state.contactFormShown && 
      !state.contactFormPending && 
      !state.contactFormSubmitted && 
      CONFIG.collectContactInfo && 
      !state.contactInfo.email;
    
    if (shouldShowContactFormFirst) {
      // Store the user's message but don't process it yet
      state.pendingUserMessage = text;
      state.contactFormPending = true;
      
      // Add the user message to UI so they see it was received
      addMessage('user', text);
      
      // Show typing for intro message
      showTyping();
      
      setTimeout(function() {
        hideTyping();
        
        var introText = CONFIG.language === 'nl'
          ? 'Voordat ik je vraag beantwoord, mag ik je even iets vragen?'
          : 'Before I answer your question, may I ask you something?';
        addMessage('assistant', introText);
        playNotificationSound();
        
        // Show typing for explanation
        setTimeout(function() {
          showTyping();
          
          setTimeout(function() {
            hideTyping();
            
            var explanationText = CONFIG.language === 'nl'
              ? 'Mag ik je contactgegevens vragen? Dan kan ik je terugbellen als de verbinding onverwacht wegvalt of als ons gesprek wordt onderbroken.'
              : 'May I ask for your contact details? That way I can get back to you if our connection drops unexpectedly or if our conversation gets interrupted.';
            addMessage('assistant', explanationText);
            
            // Show the contact form with callback to process the pending message
            setTimeout(function() {
              state.contactFormPending = false;
              showContactForm(function() {
                // After form is completed/skipped, process the pending question
                if (state.pendingUserMessage) {
                  var pendingMsg = state.pendingUserMessage;
                  state.pendingUserMessage = null;
                  // Mark that we're resuming after contact form so Nina knows to answer the pending question
                  state.resumingAfterContactForm = true;
                  // Send the actual question to the backend
                  processMessageToBackend(pendingMsg);
                }
              });
            }, 600);
          }, 1200);
        }, 800);
      }, 1000);
      
      return; // Don't continue with normal flow
    }
    
    // Normal message flow
    addMessage('user', text);
    processMessageToBackend(text);
  }
  
  // Process message to backend (separated for reuse after contact form)
  function processMessageToBackend(text, skipAddToMessages) {
    state.isLoading = true;
    sendBtn.disabled = true;
    
    // Add realistic typing delay before showing indicator (simulates human reading)
    setTimeout(function() {
      showTyping();
    }, 400);

    // Build messages for the API - filter out contact form intro messages
    // These are the messages that are NOT about the actual conversation
    var contactFormIntros = [
      'Voordat ik je vraag beantwoord, mag ik je even iets vragen?',
      'Before I answer your question, may I ask you something?',
      'Mag ik je contactgegevens vragen? Dan kan ik je terugbellen als de verbinding onverwacht wegvalt of als ons gesprek wordt onderbroken.',
      'May I ask for your contact details? That way I can get back to you if our connection drops unexpectedly or if our conversation gets interrupted.'
    ];
    
    // Filter messages and also skip transition messages that start with "Dankjewel" or "Thank you" or "Geen probleem" or "No problem"
    var messagesForApi = state.messages.filter(function(m) {
      if (m.role !== 'assistant') return true;
      // Skip contact form intro/explanation messages
      if (contactFormIntros.indexOf(m.content) !== -1) return false;
      // Skip transition messages after form
      if (m.content.indexOf('Dankjewel') === 0 && m.content.indexOf('Om terug te komen op je vraag') !== -1) return false;
      if (m.content.indexOf('Thank you') === 0 && m.content.indexOf('To get back to your question') !== -1) return false;
      if (m.content.indexOf('Geen probleem') === 0 && m.content.indexOf('Dan ga ik verder met je vraag') !== -1) return false;
      if (m.content.indexOf('No problem') === 0 && m.content.indexOf('Let me continue with your question') !== -1) return false;
      return true;
    }).map(function(m) { return { role: m.role, content: m.content }; });

    // Check if we're resuming after contact form submission
    var resumeContext = state.resumingAfterContactForm ? text : null;
    state.resumingAfterContactForm = false; // Reset the flag
    
    var requestBody = {
      messages: messagesForApi,
      tenantId: CONFIG.tenantId,
      sessionId: state.conversationId,
      companyContext: 'Company: ' + CONFIG.companyName,
      contactInfo: state.contactInfo,
      resumeAfterContactForm: resumeContext, // Include the pending question for explicit handling
      agentSettings: {
        greeting: CONFIG.greeting,
        tone: CONFIG.tone,
        language: CONFIG.language,
        enableEmoji: CONFIG.enableEmoji,
        collectContactInfo: CONFIG.collectContactInfo,
        customInstructions: CONFIG.customInstructions,
        calendlyUrl: CONFIG.calendlyUrl,
        calendlyApiKey: CONFIG.calendlyApiKey
      }
    };

    fetch(CONFIG.functionsUrl + '/nina-chat', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(requestBody)
    })
    .then(function(response) {
      if (!response.ok) throw new Error('Request failed');
      // Capture conversation ID from response header
      var convId = response.headers.get('X-Conversation-Id');
      if (convId) {
        state.conversationId = convId;
      }
      return response.body.getReader();
    })
    .then(function(reader) {
      var decoder = new TextDecoder();
      var assistantMessage = '';
      var displayedMessage = '';
      var msgEl = null;
      var typingInterval = null;
      var streamComplete = false;
      var sseBuffer = '';

      function appendDelta(content) {
        if (!content) return;

        if (!msgEl) {
          // Add delay before showing first character (simulates reading + thinking)
          setTimeout(function() {
            hideTyping();
          }, 800);
          state.messages.push({ role: 'assistant', content: '' });
          msgEl = document.createElement('div');
          msgEl.className = 'nina-message assistant';
          messagesContainer.appendChild(msgEl);
          // Play sound when Nina starts responding
          playNotificationSound();

          // Start the typing simulation after initial delay
          setTimeout(function() {
            // Typing speed: ~30-50ms per character group (simulates ~60-80 WPM)
            typingInterval = setInterval(simulateTyping, 35);
          }, 600);
        }

        // Buffer the content (don't display immediately)
        assistantMessage += content;
      }
      

      // Helper function to render timeslots interactively
      function renderTimeslots() {
        if (!msgEl) return false;
        
        var timeslotMatch = assistantMessage.match(/\[TIMESLOTS\]([\s\S]*?)\[\/TIMESLOTS\]/);
        if (!timeslotMatch) return false;
        
        // Extract parts before and after the timeslots
        var beforeSlots = assistantMessage.split('[TIMESLOTS]')[0].trim();
        var afterSlots = assistantMessage.split('[/TIMESLOTS]')[1] || '';
        afterSlots = afterSlots.trim();
        
        // Parse the timeslots
        var slotsContent = timeslotMatch[1].trim();
        var slotLines = slotsContent.split('\n').filter(function(line) {
          return line.trim().indexOf('[ ]') === 0 || line.trim().indexOf('[]') === 0;
        });
        
        // Build the HTML
        msgEl.innerHTML = '';
        
        // Add text before slots
        if (beforeSlots) {
          var beforeEl = document.createElement('div');
          beforeEl.textContent = beforeSlots;
          beforeEl.style.marginBottom = '8px';
          msgEl.appendChild(beforeEl);
        }
        
        // Add interactive timeslots
        if (slotLines.length > 0) {
          var slotsContainer = document.createElement('div');
          slotsContainer.className = 'nina-timeslots';
          
          slotLines.forEach(function(line, index) {
            var slotText = line.replace(/^\s*\[\s*\]\s*/, '').trim();
            if (!slotText) return;
            
            var slotItem = document.createElement('div');
            slotItem.className = 'nina-timeslot-item';
            slotItem.innerHTML = 
              '<div class="nina-timeslot-radio"></div>' +
              '<span class="nina-timeslot-text">' + slotText + '</span>';
            
            slotItem.addEventListener('click', function() {
              // Remove selected from all
              var allItems = slotsContainer.querySelectorAll('.nina-timeslot-item');
              allItems.forEach(function(item) { item.classList.remove('selected'); });
              // Mark this as selected
              slotItem.classList.add('selected');
              
              // Send the selection as a user message after a brief delay
              setTimeout(function() {
                var selectionMessage = slotText;
                addMessage('user', selectionMessage);
                processMessageToBackend(selectionMessage);
              }, 300);
            });
            
            slotsContainer.appendChild(slotItem);
          });
          
          msgEl.appendChild(slotsContainer);
        }
        
        // Add text after slots (alternative options hint)
        if (afterSlots) {
          var hintEl = document.createElement('div');
          hintEl.className = 'nina-timeslot-hint';
          hintEl.textContent = afterSlots;
          msgEl.appendChild(hintEl);
        }
        
        // Store the clean version for state
        var cleanMessage = beforeSlots + '\n' + slotLines.map(function(l) { return l.replace(/^\s*\[\s*\]\s*/, '• '); }).join('\n') + (afterSlots ? '\n' + afterSlots : '');
        state.messages[state.messages.length - 1].content = cleanMessage;
        
        messagesContainer.scrollTop = messagesContainer.scrollHeight;
        return true;
      }

      // Render Calendly booking confirmation as a button (hide raw URL / markdown)
      function renderCalendlyConfirmation() {
        if (!msgEl) return false;
        if (!assistantMessage) return false;

        // Match markdown links like: [Afspraak Bevestigen](https://...)
        var md = assistantMessage.match(/[[^]]+](s*(https?://[^s)]+)s*)/);
        var url = md && md[1] ? md[1] : null;

        // Or match any raw URL
        if (!url) {
          var raw = assistantMessage.match(/(https?://[^s]+)/);
          url = raw && raw[1] ? raw[1] : null;
        }

        if (!url) return false;
        if (url.indexOf('calendly.com') === -1) return false;

        // Remove any markdown link + raw url from displayed text
        var cleaned = assistantMessage
          .replace(/[[^]]+](s*https?://[^s)]+s*)/g, '')
          .replace(url, '')
          .replace(/(s*)/g, '')
          .trim();

        msgEl.innerHTML = '';

        if (cleaned) {
          var textEl = document.createElement('div');
          textEl.textContent = cleaned;
          textEl.style.marginBottom = '8px';
          msgEl.appendChild(textEl);
        }

        var btn = document.createElement('a');
        btn.href = url;
        btn.target = '_blank';
        btn.rel = 'noreferrer';
        btn.className = 'nina-calendly-confirm';
        btn.textContent = 'Afspraak bevestigen';
        msgEl.appendChild(btn);

        messagesContainer.scrollTop = messagesContainer.scrollHeight;
        return true;
      }

      // Human-like typing simulation
      function simulateTyping() {
        // Check if message contains timeslots - type only up to [TIMESLOTS], then render instantly
        var timeslotIndex = assistantMessage.indexOf('[TIMESLOTS]');
        var hasTimeslots = timeslotIndex !== -1;
        var typingTarget = hasTimeslots ? assistantMessage.substring(0, timeslotIndex).trim() : assistantMessage;
        
        if (displayedMessage.length < typingTarget.length) {
          // Calculate chars to add this tick (1-3 chars for natural variation)
          var charsToAdd = Math.floor(Math.random() * 3) + 1;
          var nextIndex = Math.min(displayedMessage.length + charsToAdd, typingTarget.length);
          displayedMessage = typingTarget.substring(0, nextIndex);
          
          if (msgEl) {
            msgEl.textContent = displayedMessage;
            state.messages[state.messages.length - 1].content = displayedMessage;
            messagesContainer.scrollTop = messagesContainer.scrollHeight;
          }
        } else if (hasTimeslots && displayedMessage.length >= typingTarget.length && streamComplete) {
          // Finished typing intro text, now render timeslots instantly
          clearInterval(typingInterval);
          typingInterval = null;
          renderTimeslots();
        } else if (streamComplete && displayedMessage.length >= typingTarget.length) {
          // All content displayed and stream is done
          clearInterval(typingInterval);
          typingInterval = null;
          
          // CRITICAL: Ensure the final message matches the complete backend content
          if (msgEl) {
            // Try to render special UI blocks first
            if (!renderTimeslots() && !renderCalendlyConfirmation()) {
              // Normal message
              msgEl.textContent = assistantMessage;
            }
            state.messages[state.messages.length - 1].content = assistantMessage;
          }
          
          // Contact form is now handled upfront in sendMessage() before the API call
          // No need to check here anymore
          
          // Check for goodbye message to show survey - ONLY on explicit goodbyes
          if (assistantMessage && !state.surveyShown) {
            var contentLower = assistantMessage.toLowerCase();
            
            // Only trigger on explicit farewell phrases that indicate conversation is ending
            var farewellKeywords = ['tot ziens', 'tot snel', 'prettige dag', 'fijne dag', 'goodbye', 'take care', 'have a great day', 'bedankt voor je bezoek', 'thanks for visiting', 'tot de volgende keer', 'see you next time', 'fijn weekend', 'have a nice weekend'];
            var hasFarewell = farewellKeywords.some(function(kw) { return contentLower.indexOf(kw) !== -1; });
            
            // Also check if the USER said goodbye in their last message
            var lastUserMsg = state.messages.filter(function(m) { return m.role === 'user'; }).pop();
            var userSaidBye = false;
            if (lastUserMsg) {
              var userMsgLower = lastUserMsg.content.toLowerCase();
              var userByeKeywords = ['bye', 'doei', 'dag', 'tot ziens', 'bedankt', 'thanks', 'dankjewel', 'thank you', 'later', 'ciao', 'tot snel'];
              userSaidBye = userByeKeywords.some(function(kw) { return userMsgLower.indexOf(kw) !== -1; });
            }
            
            // Only show survey if Nina said farewell AND user initiated goodbye
            if (hasFarewell && userSaidBye) {
              setTimeout(function() {
                showSatisfactionSurvey();
              }, 2000);
            }
          }
        }
      }

      function readChunk() {
        return reader.read().then(function(result) {
          if (result.done) {
            // Flush any trailing SSE line that didn't end with 

            if (sseBuffer) {
              var leftoverLine = sseBuffer;
              // Remove trailing carriage return if present
              if (leftoverLine.charAt(leftoverLine.length - 1) === '\r') {
                leftoverLine = leftoverLine.slice(0, -1);
              }
              sseBuffer = '';

              if (leftoverLine.indexOf('data:') === 0) {
                var leftoverData = leftoverLine.slice(5).trim();
                if (leftoverData && leftoverData !== '[DONE]') {
                  try {
                    var parsedLeftover = JSON.parse(leftoverData);
                    var leftoverContent = parsedLeftover.choices && parsedLeftover.choices[0] && parsedLeftover.choices[0].delta && parsedLeftover.choices[0].delta.content;
                    appendDelta(leftoverContent);
                  } catch (e) {}
                }
              }
            }

            streamComplete = true;
            // If typing interval not running but we have content, start it
            if (!typingInterval && assistantMessage && displayedMessage.length < assistantMessage.length) {
              typingInterval = setInterval(simulateTyping, 35);
            } else if (!typingInterval) {
              // Stream done and typing done - trigger the final checks
              simulateTyping();
            }
            return;
          }

          var chunk = decoder.decode(result.value, { stream: true });

          // Robust SSE parsing: chunks can split JSON lines across boundaries.
          sseBuffer += chunk;
          var lines = sseBuffer.split('\n');
          sseBuffer = lines.pop() || '';

          for (var i = 0; i < lines.length; i++) {
            var line = lines[i];
            // Remove trailing carriage return if present
            if (line.charAt(line.length - 1) === '\r') {
              line = line.slice(0, -1);
            }
            if (line.indexOf('data:') !== 0) continue;

            var data = line.slice(5).trim();
            if (!data || data === '[DONE]') continue;

            try {
              var parsed = JSON.parse(data);
              var content = parsed.choices && parsed.choices[0] && parsed.choices[0].delta && parsed.choices[0].delta.content;
              appendDelta(content);
            } catch (e) {}
          }
          return readChunk();
        });
      }
      return readChunk();
    })
    .catch(function(error) {
      console.error('nina widget error:', error);
      hideTyping();
      addMessage('assistant', 'Sorry, I encountered an error. Please try again.');
    })
    .finally(function() {
      state.isLoading = false;
      sendBtn.disabled = false;
    });
  }

  sendBtn.addEventListener('click', sendMessage);
  input.addEventListener('keypress', function(e) {
    if (e.key === 'Enter') sendMessage();
  });

  // Auto-open chat after delay if configured (must be after state and toggleChat are defined)
  if (CONFIG.autoOpenDelay > 0) {
    setTimeout(function() {
      // Only auto-open if chat hasn't been opened manually and visitor hasn't dismissed it before
      var dismissed = sessionStorage.getItem('nina_widget_dismissed');
      if (!state.isOpen && !dismissed) {
        toggleChat();
        playNotificationSound();
      }
    }, CONFIG.autoOpenDelay * 1000);
  }

  console.log('Nina widget loaded for tenant:', CONFIG.tenantId);
})();
