/**
 * Copyright FunASR (https://github.com/alibaba-damo-academy/FunASR). All Rights
 * Reserved. MIT License  (https://opensource.org/licenses/MIT)
 */
/* 2021-2023 by zhaoming,mali aihealthx.com */
let isfilemode = false;
let configwords = "";
let wssBaseUrl={};


//------------------- WebSocket 配置初始化 start------------------
async function init() {
  // 在这里请求接口
  wssBaseUrl = await getBaseUrlFromApi();

  console.log(wssBaseUrl, "获取baseUrl");
}

// 示例：请求接口获取 baseUrl
async function getBaseUrlFromApi() {
  try {
    const response = await fetch(
      `getUserConfig`,
      {
        method: "GET",
      }
    );

    if (!response.ok) {
      throw new Error("请求失败");
    }

    const data = await response.json();
    configwords = data
    return configwords;
  } catch (error) {
    console.error("获取 configwords 出错:", error);
  }
}

// 初始化程序入口
init();
console.log("进入ws");

//--------------------WebSocket 配置初始化 end------------------

//------------------- FunASR WebSocket 连接器 start------------------
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未连接警告节流
  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();
    }
    //------------------- FunASR 连接模式选择 start------------------
    // app.js 中 rec 和 rec2 可能连接同一个 /websocket_offline 地址。
    // online/offline 的区别不靠 URL，而靠 onOpen() 握手 JSON 中的 mode 字段：
    // wsStart() 不传参数 => mode:"online"; wsStart(url) 传参 => mode:"offline"。
    var Uri = e ? e : `wss://${wssBaseUrl.FUNASR_WEBSOCKET_IP}/websocket_offline`;
    if (e) {
      modeType = "offline";
    } else {
      modeType = "online";
    }
    //--------------------FunASR 连接模式选择 end------------------
    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!");
        //speechSokt.close();
        onClose(e);
      };
      speechSokt.onmessage = function (e) {
        onMessage(e);
      };
      speechSokt.onerror = function (e) {
        onError(e);
      };
      return 1;
    } else {
      alert("当前浏览器不支持 WebSocket");
      return 0;
    }
  };

  // 定义停止与发送函数
  this.wsStop = function () {
    if (speechSokt != undefined) {
      console.log("stop ws!");
      speechSokt.close();
    }
    // 清空发送队列
    sendQueue = [];
    isSending = false;
  };

  // 处理发送队列
  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
    };
  };

 async function getBaseHot(params) {
  try {
    const response = await fetch(`/tool/speakr/api/hotwords`, {
      method: "GET",
    });
    if (!response.ok) {
      // 请求失败时返回空
      console.warn("getBaseHot 请求失败，使用默认 hotwords");
      return "{}";
    }

    const data = await response.json();

    const resultObj = data.hotwords.reduce((obj, item) => {
      obj[item.keyword] = item.weight;
      return obj;
    }, {});

    return JSON.stringify(resultObj);

  } catch (err) {
    // 发生异常时返回空
    console.error("getBaseHot 调用出错：", err);
    return "";
  }
}

  // SOCEKT连接中的消息与状态响应
  async function onOpen(e) {
    console.log(e, "e");

    // 发送json
    var chunk_size = new Array(10, 10, 10);
    var request = {
      chunk_size: chunk_size,
      wav_name: "h5",
      is_speaking: true,
      chunk_interval: 10,
      itn: true, // 是否使用ITN
      // "mode":"2pass",// 模型模式
      // 对应 app.js 的 rec/rec2 双链路：同地址下通过 mode 区分在线预览和离线正式结果。
      mode: modeType,
      hotwords: await getBaseHot(),
    };
    console.log(request, "request");

    if (isfilemode) {
      request.wav_format = file_ext;
      if (file_ext == "wav") {
        request.wav_format = "PCM";
        request.audio_fs = file_sample_rate;
      }
    }

    // var hotwords=getBaseHot();
    // console.log(hotwords);

    // if(hotwords!=null  )
    // {
    // 	request.hotwords=hotwords;
    // }
    // console.log(JSON.stringify(request),'热词');
    speechSokt.send(JSON.stringify(request));
    console.log("连接成功");
    stateHandle(0);

    // 连接成功后，处理队列中积压的数据
    if (sendQueue.length > 0) {
      console.log(`📤 处理连接前积压的 ${sendQueue.length} 个数据包`);
      processQueue();
    }
  }

  function onClose(e) {
    stateHandle(1);
  }

  function onMessage(e) {
    msgHandle(e);
  }

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