import _typeof from "@babel/runtime/helpers/typeof";
import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
import _regeneratorRuntime from "@babel/runtime/regenerator";
/**
 * Slow Lane Client: Backend context encoding for autocomplete.
 *
 * Fires a BE request on word boundaries to encode document context.
 * Expects the typeahead-encodings API format:
 *   Request:  { text, session_id }
 *   Response: { semantic_vector: number[], lm_logits: Record<string, number> }
 */

import { abortExp, EXPERIENCE_NAME, failExp, startExp, succeedExp } from '../analytics/ufo';
import { isAutocompleteDebugEnabled } from './debug-mode';

// ─── Types ───────────────────────────────────────────────────────────────────

/** Request payload for typeahead-encodings endpoint. */

/** Response from typeahead-encodings endpoint. */

// ─── Constants ───────────────────────────────────────────────────────────────

// eslint-disable-next-line require-unicode-regexp
var WORD_BOUNDARY_CHARS = /[\s.,;:!?]/;
// eslint-disable-next-line require-unicode-regexp
var TRAILING_SLASH_REGEX = /\/$/;
var DEFAULT_DEBOUNCE_MS = 300;

/**
 * Check if text ends with a word boundary character (space or punctuation).
 */
export var isWordBoundary = function isWordBoundary(text) {
  if (!text || text.length === 0) {
    return false;
  }
  var lastChar = text[text.length - 1];
  return WORD_BOUNDARY_CHARS.test(lastChar);
};

// ─── Slow Lane Client ────────────────────────────────────────────────────────

export var createSlowLaneClient = function createSlowLaneClient(config) {
  var baseUrl = config.baseUrl,
    configSessionId = config.sessionId,
    _config$productKey = config.productKey,
    productKey = _config$productKey === void 0 ? 'confluence' : _config$productKey,
    _config$endpoint = config.endpoint,
    endpoint = _config$endpoint === void 0 ? '/gateway/api/v1/autocomplete/typeahead-encodings' : _config$endpoint,
    _config$debounceMs = config.debounceMs,
    debounceMs = _config$debounceMs === void 0 ? DEFAULT_DEBOUNCE_MS : _config$debounceMs,
    _config$fetchFn = config.fetchFn,
    fetchFn = _config$fetchFn === void 0 ? fetch : _config$fetchFn,
    onUpdate = config.onUpdate;
  var sessionId = configSessionId !== null && configSessionId !== void 0 ? configSessionId : crypto.randomUUID();
  var headers = {
    'Content-Type': 'application/json',
    'x-experience-id': 'confluence-smart-typeahead-encodings',
    'x-product': productKey
  };
  var debounceTimer = null;
  var lastRequestedText = '';
  var storedContextVector = null;
  var storedLmLogits = null;
  var requestSeq = 0;
  var inflightRequestId = null;
  var doUpdateContext = /*#__PURE__*/function () {
    var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(text, requestId) {
      var url, payload, res, data, _t;
      return _regeneratorRuntime.wrap(function (_context) {
        while (1) switch (_context.prev = _context.next) {
          case 0:
            if (!(!text || text.trim().length === 0)) {
              _context.next = 1;
              break;
            }
            return _context.abrupt("return");
          case 1:
            url = "".concat(baseUrl.replace(TRAILING_SLASH_REGEX, '')).concat(endpoint);
            payload = {
              text: text,
              session_id: sessionId
            };
            startExp(EXPERIENCE_NAME.SLOW_LANE_FETCH, requestId, {
              textLength: text.length,
              isLocalLLM: false
            });
            if (isAutocompleteDebugEnabled()) {
              // eslint-disable-next-line no-console
              console.groupCollapsed("%c[SlowLane] %c\uD83D\uDCE4 Sending context | ".concat(text.length, " chars"), 'color: #9c27b0; font-weight: bold;', 'color: inherit;');
              text.split('\n').forEach(function (line, i, arr) {
                // eslint-disable-next-line no-console
                console.log("  ".concat(i === arr.length - 1 ? '▶' : ' ', " ").concat(line));
              });
              // eslint-disable-next-line no-console
              console.groupEnd();
            }
            _context.prev = 2;
            _context.next = 3;
            return fetchFn(url, {
              method: 'POST',
              headers: headers,
              body: JSON.stringify(payload)
            });
          case 3:
            res = _context.sent;
            if (res.ok) {
              _context.next = 4;
              break;
            }
            storedContextVector = null;
            storedLmLogits = null;
            failExp(EXPERIENCE_NAME.SLOW_LANE_FETCH, requestId, {
              status: res.status,
              errorType: 'http_error',
              isLocalLLM: false
            });
            if (isAutocompleteDebugEnabled()) {
              // eslint-disable-next-line no-console
              console.log("%c[SlowLane] %c\u274C Request failed (".concat(res.status, ")"), 'color: #9c27b0; font-weight: bold;', 'color: #f44336;');
            }
            return _context.abrupt("return");
          case 4:
            _context.next = 5;
            return res.json();
          case 5:
            data = _context.sent;
            if (data.semantic_vector && Array.isArray(data.semantic_vector)) {
              storedContextVector = new Float32Array(data.semantic_vector);
            } else {
              storedContextVector = null;
            }
            if (data.lm_logits && _typeof(data.lm_logits) === 'object') {
              storedLmLogits = data.lm_logits;
            } else {
              storedLmLogits = null;
            }
            if (isAutocompleteDebugEnabled()) {
              // eslint-disable-next-line no-console
              console.groupCollapsed("%c[SlowLane] %c\uD83D\uDCE5 Response received", 'color: #9c27b0; font-weight: bold;', 'color: inherit;');
              // eslint-disable-next-line no-console
              console.log(storedContextVector ? "\u2705 semantic_vector: ".concat(storedContextVector.length, " dims") : '❌ No semantic_vector');
              // eslint-disable-next-line no-console
              console.log(storedLmLogits ? "\u2705 lm_logits: ".concat(Object.keys(storedLmLogits).length, " tokens") : '❌ No lm_logits');
              // eslint-disable-next-line no-console
              console.groupEnd();
            }
            succeedExp(EXPERIENCE_NAME.SLOW_LANE_FETCH, requestId, {
              textLength: text.length,
              hasVector: storedContextVector !== null,
              hasLmLogits: storedLmLogits !== null,
              isLocalLLM: false
            });
            onUpdate === null || onUpdate === void 0 || onUpdate({
              textLength: text.length,
              hasVector: storedContextVector !== null,
              hasLmLogits: storedLmLogits !== null
            });
            // eslint-disable-next-line no-unused-vars
            _context.next = 7;
            break;
          case 6:
            _context.prev = 6;
            _t = _context["catch"](2);
            storedContextVector = null;
            storedLmLogits = null;
            failExp(EXPERIENCE_NAME.SLOW_LANE_FETCH, requestId, {
              errorType: 'network',
              isLocalLLM: false
            });
            if (isAutocompleteDebugEnabled()) {
              // eslint-disable-next-line no-console
              console.log('%c[SlowLane] %c❌ Network error — context cleared', 'color: #9c27b0; font-weight: bold;', 'color: #f44336;');
            }
          case 7:
            _context.prev = 7;
            if (inflightRequestId === requestId) {
              inflightRequestId = null;
            }
            return _context.finish(7);
          case 8:
          case "end":
            return _context.stop();
        }
      }, _callee, null, [[2, 6, 7, 8]]);
    }));
    return function doUpdateContext(_x, _x2) {
      return _ref.apply(this, arguments);
    };
  }();
  var updateContextDebounced = function updateContextDebounced(text) {
    if (debounceTimer) {
      clearTimeout(debounceTimer);
    }
    lastRequestedText = text;
    debounceTimer = setTimeout(function () {
      debounceTimer = null;
      if (inflightRequestId !== null) {
        abortExp(EXPERIENCE_NAME.SLOW_LANE_FETCH, inflightRequestId, 'superseded', {
          isLocalLLM: false
        });
      }
      var requestId = String(++requestSeq);
      inflightRequestId = requestId;
      doUpdateContext(lastRequestedText, requestId);
    }, debounceMs);
  };
  return {
    updateContext: updateContextDebounced,
    getContextVector: function getContextVector() {
      return storedContextVector;
    },
    getLmLogits: function getLmLogits() {
      return storedLmLogits;
    },
    setContextVector: function setContextVector(vector) {
      storedContextVector = vector;
    },
    setLmLogits: function setLmLogits(logits) {
      storedLmLogits = logits;
    },
    isWordBoundary: isWordBoundary
  };
};
var defaultSlowLaneClient = null;
export var setDefaultSlowLaneClient = function setDefaultSlowLaneClient(client) {
  defaultSlowLaneClient = client;
};
export var getStoredContextVector = function getStoredContextVector() {
  var _defaultSlowLaneClien, _defaultSlowLaneClien2;
  return (_defaultSlowLaneClien = (_defaultSlowLaneClien2 = defaultSlowLaneClient) === null || _defaultSlowLaneClien2 === void 0 ? void 0 : _defaultSlowLaneClien2.getContextVector()) !== null && _defaultSlowLaneClien !== void 0 ? _defaultSlowLaneClien : null;
};
export var getStoredLmLogits = function getStoredLmLogits() {
  var _defaultSlowLaneClien3, _defaultSlowLaneClien4;
  return (_defaultSlowLaneClien3 = (_defaultSlowLaneClien4 = defaultSlowLaneClient) === null || _defaultSlowLaneClien4 === void 0 ? void 0 : _defaultSlowLaneClien4.getLmLogits()) !== null && _defaultSlowLaneClien3 !== void 0 ? _defaultSlowLaneClien3 : null;
};