/**
 * Realtime ASR websocket client.
 * Browser audio is sent only to the Speakr backend proxy.
 */

function getBackendAsrWebSocketUrl(mode) {
  const protocol = window.location.protocol === "https:" ? "wss:" : "ws:";
  const basePath = "/tool/speakr/ws/asr/live";
  return `${protocol}//${window.location.host}${basePath}?mode=${encodeURIComponent(mode || "online")}`;
}

function WebSocketConnectMethod(config) {
  //定义socket连接方法类

  var speechSokt;
  var connKeeperID;

  var msgHandle = config.msgHandle;
  var stateHandle = config.stateHandle;
  let modeType = "offline";

  // 发送队列和流量控制
  var sendQueue = [];
  var isSending = false;
  var maxQueueSize = 1000; // 最大队列长度，防止内存溢出
  var queueWarningThreshold = 500; // 队列警告阈值
  var lastDisconnWarnTime = 0; // WebSocket未连接警告节流
  var gracefulStopResolver = null;
  var gracefulStopTimer = null;
  function trimQueueIfNeeded() {
    if (sendQueue.length <= maxQueueSize) {
      return false;
    }

    const dropCount = sendQueue.length - maxQueueSize;
    console.warn(
      `⚠️ 发送队列超过最大限制 (${maxQueueSize})，丢弃最旧的 ${dropCount} 个数据包`
    );
    sendQueue = sendQueue.slice(-maxQueueSize);
    return true;
  }

  function enqueueData(data) {
    sendQueue.push(data);
    trimQueueIfNeeded();

    if (sendQueue.length > queueWarningThreshold) {
      console.warn(`⚠️ WebSocket发送队列堆积: ${sendQueue.length} 个数据包待发送`);
    }
  }

  this.wsStart = function (e) {
    if (speechSokt) {
      speechSokt.close();
    }
    if (e === "offline" || (e && e !== "online")) {
      modeType = "offline";
    } else {
      modeType = "online";
    }
    var Uri = getBackendAsrWebSocketUrl(modeType);
    if (Uri.match(/wss:\S*|ws:\S*/)) {
      console.log("Uri" + Uri);
    } else {
      alert("请检查wss地址正确性");
      return 0;
    }

    if ("WebSocket" in window) {
      speechSokt = new WebSocket(Uri); // 定义socket连接对象
      speechSokt.onopen = function (e) {
        onOpen(e);
      }; // 定义响应函数
      speechSokt.onclose = function (e) {
        console.log("onclose ws!");
        onClose(e);
      };
      speechSokt.onmessage = function (e) {
        onMessage(e);
      };
      speechSokt.onerror = function (e) {
        onError(e);
      };
      return 1;
    } else {
      alert("当前浏览器不支持 WebSocket");
      return 0;
    }
  };

  // 定义停止与发送函数
  function resolveGracefulStop() {
    if (gracefulStopTimer) {
      clearTimeout(gracefulStopTimer);
      gracefulStopTimer = null;
    }
    if (gracefulStopResolver) {
      gracefulStopResolver();
      gracefulStopResolver = null;
    }
  }

  function closeSocketNow() {
    if (speechSokt != undefined) {
      try {
        speechSokt.close();
      } catch (e) {
        console.warn("Failed to close WebSocket", e);
      }
      speechSokt = undefined;
    }
    sendQueue = [];
    isSending = false;
  }

  this.wsStop = function () {
    if (speechSokt != undefined) {
      console.log("stop ws!");
      try {
        if (speechSokt.readyState === 1) {
          speechSokt.send(JSON.stringify({ type: "stop", is_speaking: false }));
        }
      } catch (e) {
        console.warn("Failed to send WebSocket stop frame", e);
      }
    }
    resolveGracefulStop();
    closeSocketNow();
  };

  this.wsFinish = function (timeoutMs = 3000) {
    if (speechSokt == undefined || speechSokt.readyState >= 2) {
      resolveGracefulStop();
      return Promise.resolve();
    }

    sendQueue = [];
    isSending = false;

    return new Promise((resolve) => {
      gracefulStopResolver = resolve;
      gracefulStopTimer = setTimeout(() => {
        // Give the server ownership of the close. Timeout only unblocks UI.
        resolveGracefulStop();
      }, timeoutMs);

      try {
        if (speechSokt.readyState === 1) {
          speechSokt.send(JSON.stringify({ type: "stop", is_speaking: false }));
        }
      } catch (e) {
        console.warn("Failed to send WebSocket finish frame", e);
        resolveGracefulStop();
      }
    });
  };

  // 处理发送队列
  function processQueue() {
    if (
      isSending ||
      sendQueue.length === 0 ||
      !speechSokt ||
      speechSokt.readyState !== 1
    ) {
      return;
    }

    isSending = true;
    const data = sendQueue.shift();

    try {
      speechSokt.send(data);
      isSending = false;

      // 队列警告
      if (sendQueue.length > queueWarningThreshold) {
        console.warn(`⚠️ WebSocket发送队列堆积: ${sendQueue.length} 个数据包待发送`);
      }

      // 继续处理队列
      if (sendQueue.length > 0) {
        // 使用 setTimeout 避免阻塞
        setTimeout(() => processQueue(), 0);
      }
    } catch (e) {
      console.error("❌ WebSocket发送失败，数据已放回队列:", e);
      sendQueue.unshift(data); // 放回队列头部
      isSending = false;
      trimQueueIfNeeded();
    }
  }

  this.wsSend = function (oneData) {
    if (speechSokt == undefined) {
      // WebSocket未初始化，缓存数据
      enqueueData(oneData);
      return true;
    }

    if (speechSokt.readyState === 1) {
      // WebSocket已打开
      if (sendQueue.length > 0) {
        // 队列中有数据，先加入队列
        enqueueData(oneData);
        processQueue();
        return true;
      } else {
        // 队列为空，尝试直接发送
        try {
          speechSokt.send(oneData);
          return true;
        } catch (e) {
          console.error("❌ WebSocket直接发送失败，加入队列:", e);
          enqueueData(oneData);
          processQueue();
          return true;
        }
      }
    } else if (speechSokt.readyState === 0) {
      // WebSocket正在连接，缓存数据
      enqueueData(oneData);
      return true;
    } else {
      // WebSocket已关闭或关闭中，丢弃数据并警告（节流 5 秒）
      var now = Date.now();
      if (now - lastDisconnWarnTime > 5000) {
        console.warn("⚠️ WebSocket未连接，数据无法发送 (state:", speechSokt.readyState, ")");
        lastDisconnWarnTime = now;
      }
      return false;
    }
  };

  // 获取队列状态（用于调试）
  this.getQueueStatus = function () {
    return {
      length: sendQueue.length,
      isSending: isSending,
      readyState: speechSokt ? speechSokt.readyState : -1
    };
  };


  // SOCEKT连接中的消息与状态响应
  function onOpen(e) {
    console.log(e, "e");
    console.log("WebSocket connected to backend ASR proxy");
    stateHandle(0);

    if (sendQueue.length > 0) {
      console.log(`Processing ${sendQueue.length} queued audio chunks`);
      processQueue();
    }
  }

  function onClose(e) {
    resolveGracefulStop();
    speechSokt = undefined;
    stateHandle(1);
  }

  function onMessage(e) {
    msgHandle(e);
    try {
      const payload = JSON.parse(e.data);
      if (payload && payload.type === "state" && payload.state === "closed") {
        resolveGracefulStop();
      }
    } catch (_) {}
  }

  function onError(e) {
    // info_div.innerHTML="连接"+e;
    console.log(e);
    stateHandle(2);
  }
}
