/* ==========================================================================
   Niwa Chatbot -- Conversion Busters Compatibility Shim
   ---------------------------------------------------------------------------
   Provides the window.niwaAI.* API (openChat, _send, handleResponse,
   addBotMessage, sendMessage, restoreCouponMessage) using the new
   Niwa module system. No jQuery dependency.

   This file bridges the CB module (conversion-busters.js) which still uses
   jQuery internally. The shim itself is pure vanilla JS.

   NAMESPACE: window.niwaAI
   ========================================================================== */

(function () {
  'use strict';

  var Niwa = window.Niwa || {};
  var F = window.NiwaAIFrontend || {};

  /* -- Helpers ------------------------------------------------------------ */

  function findBodyEl() {
    return document.querySelector('.niwa-morph__body')
      || document.querySelector('.niwa-center__body');
  }

  function scrollToLatest() {
    var bodyEl = findBodyEl();
    if (bodyEl && Niwa.ScrollBehavior) {
      Niwa.ScrollBehavior.scrollToBottom(bodyEl);
    }
  }

  function ensureOpen() {
    if (Niwa.MorphController && !Niwa.MorphController.isOpen()) {
      Niwa.MorphController.open();
    }
  }

  function getSessionIdSafe() {
    return (Niwa.Utils && Niwa.Utils.getSession) ? Niwa.Utils.getSession() : '';
  }

  function newFrontendRequestId(session) {
    var suffix = '';
    try {
      if (window.crypto && window.crypto.getRandomValues) {
        var bytes = new Uint32Array(2);
        window.crypto.getRandomValues(bytes);
        suffix = bytes[0].toString(36) + bytes[1].toString(36);
      }
    } catch (e) { /* ignore crypto errors */ }
    if (!suffix) {
      suffix = Math.random().toString(36).slice(2) + Date.now().toString(36);
    }
    var sessionPart = String(session || 'anon').replace(/[^a-zA-Z0-9_-]/g, '').slice(-18);
    return ['front', sessionPart || 'anon', Date.now().toString(36), suffix].join('_').slice(0, 96);
  }

  function extractAjaxErrorSafe(response, fallback) {
    return (Niwa.Utils && Niwa.Utils.extractAjaxErrorMessage)
      ? Niwa.Utils.extractAjaxErrorMessage(response, fallback)
      : (fallback || '');
  }

  function normalizeCouponCode(code) {
    if (Niwa.MessageRenderer && typeof Niwa.MessageRenderer.normalizeCouponCode === 'function') {
      return Niwa.MessageRenderer.normalizeCouponCode(code);
    }
    if (typeof code !== 'string' && typeof code !== 'number') return null;
    var normalized = String(code).trim().toUpperCase();
    return /^[A-Z0-9-]{4,20}$/.test(normalized) ? normalized : null;
  }

  function parseJsonLenient(raw) {
    if (raw && typeof raw === 'object') return raw;
    if (typeof raw !== 'string') return null;

    try { return JSON.parse(raw); } catch (e) { /* continue */ }

    var cleaned = raw.replace(/\uFEFF/g, '').replace(/\x1B\[[0-9;]*m/g, '').trim();
    if (!cleaned) return null;
    try { return JSON.parse(cleaned); } catch (e) { /* continue */ }

    var lines = cleaned.split('\n');
    for (var i = 0; i < lines.length; i++) {
      var line = (lines[i] || '').trim();
      if (line.charAt(0) === '{' || line.charAt(0) === '[') {
        try { return JSON.parse(lines.slice(i).join('\n').trim()); } catch (e) { /* continue */ }
      }
    }

    var idx = cleaned.search(/[\{\[]/);
    if (idx >= 0) {
      try { return JSON.parse(cleaned.slice(idx).trim()); } catch (e) { /* ignore */ }
    }

    return null;
  }

  /* -- Poll queued response ----------------------------------------------- */

  function pollQueuedResponse(queueToken, startedAt, requestId, session) {
    if (!queueToken) {
      if (Niwa.MessageRenderer) Niwa.MessageRenderer.hideTyping();
      window.niwaAI.addBotMessage('Request missing queue token.');
      return;
    }

    var ajaxUrl = window.NiwaAI && window.NiwaAI.ajax;
    var ajaxNonce = window.NiwaAI && window.NiwaAI.nonce;
    if (!ajaxUrl || !ajaxNonce) {
      if (Niwa.MessageRenderer) Niwa.MessageRenderer.hideTyping();
      window.niwaAI.addBotMessage('Assistant configuration is incomplete.');
      return;
    }

    var beganAt = startedAt || Date.now();
    var pollCount = 0;

    function tick() {
      pollCount++;
      var fd = new FormData();
      fd.append('action', 'niwa_ai_chat_queue_status');
      fd.append('nonce', ajaxNonce);
      fd.append('queue_token', queueToken);
      if (requestId) {
        fd.append('request_id', requestId);
      }
      if (session) {
        fd.append('session', session);
      }

      fetch(ajaxUrl, { method: 'POST', body: fd })
        .then(function (r) { return r.text(); })
        .then(function (rawText) {
          var response = parseJsonLenient(rawText);

          if (!response) {
            if (Date.now() - beganAt > 90000) {
              if (Niwa.MessageRenderer) Niwa.MessageRenderer.hideTyping();
              window.niwaAI.addBotMessage('Queued response timed out. Please try again.');
              return;
            }
            var delay = pollCount <= 3 ? 500 : (pollCount <= 6 ? 1000 : 2500);
            setTimeout(tick, delay);
            return;
          }

          var payload = response.data || {};

          if (response.success && payload.done && payload.payload) {
            if (Niwa.MessageRenderer) Niwa.MessageRenderer.hideTyping();
            window.niwaAI.handleResponse({ success: true, data: payload.payload });
            return;
          }

          if (response.success && payload.queued) {
            if (Date.now() - beganAt > 90000) {
              if (Niwa.MessageRenderer) Niwa.MessageRenderer.hideTyping();
              window.niwaAI.addBotMessage('Queue timeout. Please try again in a moment.');
              return;
            }
            if (Niwa.MessageRenderer) Niwa.MessageRenderer.showTyping();
            var delayQueued = pollCount <= 3 ? 500 : (pollCount <= 6 ? 1000 : 2500);
            setTimeout(tick, delayQueued);
            return;
          }

          if (Niwa.MessageRenderer) Niwa.MessageRenderer.hideTyping();
          window.niwaAI.handleResponse(response);
        })
        .catch(function () {
          if (Date.now() - beganAt > 90000) {
            if (Niwa.MessageRenderer) Niwa.MessageRenderer.hideTyping();
            window.niwaAI.addBotMessage('Queued response timed out. Please try again.');
            return;
          }
          var delayCatch = pollCount <= 3 ? 500 : (pollCount <= 6 ? 1000 : 2500);
          setTimeout(tick, delayCatch);
        });
    }

    tick();
  }

  /* -- Build niwaAI namespace --------------------------------------------- */

  window.niwaAI = window.niwaAI || {};

  window.niwaAI.openChat = function () {
    ensureOpen();
    setTimeout(scrollToLatest, 300);
  };

  window.niwaAI._send = function (text, isUserInitiated) {
    isUserInitiated = isUserInitiated || false;

    if (!text || !String(text).trim()) return;
    text = String(text).trim();

    if (isUserInitiated && text) {
      // Reset CB state if coupon_sent
      var cbState = '';
      if (F.cb && F.cb.flow && typeof F.cb.flow.state === 'string') {
        cbState = F.cb.flow.state;
      } else {
        try { cbState = sessionStorage.getItem('niwa_ai_cb_state') || ''; } catch (e) { /* ignore */ }
      }

      if (cbState === 'coupon_sent' || (Niwa.state && Niwa.state.chatState && Niwa.state.chatState.cbReadyForReset)) {
        if (F.cb && F.cb.flow) {
          F.cb.flow.set('idle');
        } else {
          try { sessionStorage.setItem('niwa_ai_cb_state', 'idle'); } catch (e) { /* ignore */ }
        }
        if (Niwa.state && Niwa.state.chatState) {
          Niwa.state.chatState.cbReadyForReset = false;
        }
        if (F.cb && F.cb.cartMonitor && typeof F.cb.cartMonitor.setCbActive === 'function') {
          F.cb.cartMonitor.setCbActive(false);
        }
      }

      if (Niwa.state && Niwa.state.postFlowMute) {
        if (typeof Niwa.state.setPostFlowMute === 'function') Niwa.state.setPostFlowMute(false);
      }

      if (Niwa.ChatClient && typeof Niwa.ChatClient.sendMessage === 'function') {
        Niwa.ChatClient.sendMessage(text);
        return;
      }
    }

    // Block auto-messages during postFlowMute
    if (Niwa.state && Niwa.state.postFlowMute && !isUserInitiated) return;

    // Show typing
    if (Niwa.MessageRenderer) Niwa.MessageRenderer.showTyping();

    var ajaxUrl = window.NiwaAI && window.NiwaAI.ajax;
    var ajaxNonce = window.NiwaAI && window.NiwaAI.nonce;

    if (!ajaxUrl || !ajaxNonce) {
      if (Niwa.MessageRenderer) Niwa.MessageRenderer.hideTyping();
      window.niwaAI.addBotMessage('Assistant configuration is incomplete.');
      return;
    }

    var fd = new FormData();
    var session = getSessionIdSafe();
    var requestId = newFrontendRequestId(session);
    fd.append('action', (window.NiwaAI && window.NiwaAI.action) || 'niwa_ai_chat');
    fd.append('nonce', ajaxNonce);
    fd.append('_ajax_nonce', ajaxNonce);
    fd.append('message', text);
    fd.append('session', session);
    fd.append('request_id', requestId);

    var emergencyTimeout = setTimeout(function () {
      if (Niwa.MessageRenderer) Niwa.MessageRenderer.hideTyping();
      window.niwaAI.addBotMessage('Request took too long. Please try again.');
    }, 130000);

    fetch(ajaxUrl, { method: 'POST', body: fd })
      .then(function (r) { return r.text(); })
      .then(function (rawText) {
        clearTimeout(emergencyTimeout);

        var response = parseJsonLenient(rawText);
        if (!response) {
          if (Niwa.MessageRenderer) Niwa.MessageRenderer.hideTyping();
          var fallback = rawText ? rawText.slice(0, 400).trim() : 'Empty or invalid server response.';
          response = { success: false, data: { message: fallback } };
        }

        var queuedPayload = response.success && response.data ? response.data : null;
        if (queuedPayload && queuedPayload.queued && queuedPayload.queue_token) {
          pollQueuedResponse(queuedPayload.queue_token, Date.now(), queuedPayload.request_id || requestId, queuedPayload.session || session);
          return;
        }

        if (Niwa.MessageRenderer) Niwa.MessageRenderer.hideTyping();
        window.niwaAI.handleResponse(response);
      })
      .catch(function () {
        clearTimeout(emergencyTimeout);
        if (Niwa.MessageRenderer) Niwa.MessageRenderer.hideTyping();
        window.niwaAI.addBotMessage('An error occurred. Please try again.');
      });
  };

  window.niwaAI.sendMessage = function (text) {
    window.niwaAI._send(text, true);
  };

  window.niwaAI.handleResponse = function (res) {
    if (!Niwa.MessageRenderer) return;

    // Normalize payload
    var payload = res;
    if (res && typeof res === 'object' && typeof res.success !== 'undefined') {
      if (res.success && res.data && typeof res.data === 'object') {
        payload = res.data;
      } else if (!res.success) {
        if (res.data && typeof res.data === 'object') {
          payload = res.data;
        } else if (typeof res.data === 'string' && res.data.trim()) {
          payload = { message: res.data };
        } else {
          payload = {};
        }
      }
    }

    if (payload && !payload.message) {
      var extracted = extractAjaxErrorSafe(res, '');
      if (extracted) payload.message = extracted;
    }

    // Map new backend format
    if (payload) {
      if (payload.answer && !payload.message) payload.message = payload.answer;
      if (payload.cards && Array.isArray(payload.cards) && !payload.products) {
        var normFn = Niwa.Utils && Niwa.Utils.normalizeProduct;
        payload.products = payload.cards.map(function (c) { return normFn ? normFn(c) : c; });
      }
      if (!payload.suggestions) payload.suggestions = null;
    }

    // Strip NO_SEARCH_NEEDED signal
    var suppressedSignal = false;
    if (payload && payload.message) {
      var cleaned = payload.message.replace(/\[?\bNO_SEARCH_NEEDED\b\]?/gi, '').trim();
      if (cleaned !== payload.message.trim()) {
        payload.message = cleaned || null;
        if (!payload.message) suppressedSignal = true;
      }
    }

    var hasContent = false;
    var payloadCouponCode = normalizeCouponCode(
      payload && (payload.couponCode || payload.coupon_code)
    );

    if (payload && payload.message) {
      Niwa.MessageRenderer.addMessage(payload.message, 'bot', {
        couponCode: payloadCouponCode
      });
      hasContent = true;
    } else if (payload && payload.reply) {
      Niwa.MessageRenderer.addMessage(payload.reply, 'bot', {
        couponCode: payloadCouponCode
      });
      hasContent = true;
    }

    if (payload && payload.products && payload.products.length && Niwa.ProductManager) {
      Niwa.ProductManager.renderProducts(payload.products);
      hasContent = true;
    }

    if (payload && payload.suggestions && !(payload.products && payload.products.length)) {
      Niwa.MessageRenderer.renderSuggestions(payload.suggestions, payload.suggestions_codes);
      hasContent = true;
    }

    if (!hasContent && !suppressedSignal) {
      var labels = (window.NiwaAI && window.NiwaAI.labels) || {};
      Niwa.MessageRenderer.addMessage(labels.ask_what_you_need || 'How can I help you?', 'bot');
    }
  };

  window.niwaAI.addBotMessage = function (message, options) {
    var rendererOptions = (options && typeof options === 'object') ? Object.assign({}, options) : {};
    if (typeof rendererOptions.forceNewGroup === 'undefined') {
      rendererOptions.forceNewGroup = true;
    }
    var couponCode = normalizeCouponCode(rendererOptions.couponCode);
    if (couponCode) {
      rendererOptions.couponCode = couponCode;
      try {
        sessionStorage.setItem('niwa_ai_last_coupon', JSON.stringify({
          message: String(message || ''),
          couponCode: couponCode
        }));
      } catch (e) { /* ignore */ }
    }

    ensureOpen();
    setTimeout(function () {
      if (Niwa.MessageRenderer) {
        Niwa.MessageRenderer.addMessage(message, 'bot', rendererOptions);
      }
      scrollToLatest();
    }, 100);
  };

  window.niwaAI.restoreCouponMessage = function () {
    try {
      var data = sessionStorage.getItem('niwa_ai_last_coupon');
      if (!data) return;
      var parsed = JSON.parse(data);
      if (!parsed || !parsed.message) return;
      // Check if message already in history
      var history = (Niwa.MessageRenderer && Niwa.MessageRenderer.getHistory) ? Niwa.MessageRenderer.getHistory() : [];
      for (var i = 0; i < history.length; i++) {
        if (history[i].content === parsed.message) return; // Already restored
      }
      if (Niwa.MessageRenderer) {
        Niwa.MessageRenderer.addMessage(parsed.message, 'bot', {
          source: 'coupon_restore',
          couponCode: normalizeCouponCode(parsed.couponCode)
        });
      }
    } catch (e) { /* ignore */ }
  };
})();
