// FILE: _St/IG_StYellow/side_ws.js | ROLE: Side와 WS8771 통신
(() => {
  "use strict";

  const teAiwkLocalWsUrl = "ws://127.0.0.1:8771";
  const teAiwkLocalWsToken = "auto_enter_local_SEC_20260623";
  const teAiwkSetupZipUrl = "http://aiwk.yjm.kr/down/_St.zip";
  let teAiwkWsKnownConnected = false;

  function reportHealth(connected, detail) {
    try {
      chrome.runtime.sendMessage(Object.assign({ type: "IGBLUE_RTC_HEALTH_HINT", connected: !!connected }, detail || {}), () => { chrome.runtime.lastError; });
    } catch (_) {}
  }

  function isWsFailure(res) {
    if (!res || res.ok) return false;
    const code = String(res.error_code || res.error || "").toUpperCase();
    return /AIWK|WEBSOCKET|WS_|TIMEOUT|CONNECTION|REFUSED|EMPTY_RESPONSE|BAD_JSON|UNKNOWN_ACT|BAD_TOKEN/.test(code);
  }

  function makeQuietOffline(errorCode, errorText) {
    return {
      ok: 0,
      error_code: errorCode || "AIWK_LOCAL_WS_WAITING",
      error: errorText || "WS waiting",
      state: "ws_waiting",
      offline: true,
      expected_offline: true
    };
  }

  function request(act, data, opts) {
    opts = opts && typeof opts === "object" ? opts : {};
    const timeoutMs = Number(opts.timeoutMs || opts.timeout_ms || 4500) || 4500;
    const from = opts.from && typeof opts.from === "object" ? opts.from : {};
    const token = opts.token || teAiwkLocalWsToken;
    const url = opts.url || teAiwkLocalWsUrl;
    return new Promise((resolve) => {
      let ws = null, done = false;
      const finish = (res) => {
        if (done) return;
        done = true;
        try { if (ws) ws.close(); } catch (_) {}
        res = res || makeQuietOffline("EMPTY_RESPONSE", "empty response");
        if (res && res.ok) {
          teAiwkWsKnownConnected = true;
          reportHealth(true, { error_code: "", message: "WS 연결됨", state: res.state || "connected" });
        } else if (res && res.expected_offline) {
          teAiwkWsKnownConnected = false;
          reportHealth(false, res);
        }
        resolve(res);
      };
      const timer = setTimeout(() => finish(makeQuietOffline("AIWK_LOCAL_WS_TIMEOUT", "ws timeout")), timeoutMs);
      try {
        ws = new WebSocket(url);
        ws.onopen = () => {
          const id = "igblue_" + Date.now() + "_" + Math.floor(Math.random() * 100000);
          ws.send(JSON.stringify({ v: 1, id, act, token, from, data: data || {} }));
        };
        ws.onmessage = (ev) => {
          clearTimeout(timer);
          try { finish(JSON.parse(ev.data)); }
          catch (err) { finish({ ok: 0, error_code: "AIWK_BAD_JSON", error: String(err && err.message || err), state: "ws_bad_json" }); }
        };
        ws.onerror = () => { clearTimeout(timer); finish(makeQuietOffline("AIWK_LOCAL_WS_WAITING", "ws not connected")); };
        ws.onclose = () => {};
      } catch (err) {
        clearTimeout(timer);
        finish(makeQuietOffline("AIWK_WS_CREATE_FAILED", String(err && err.message || err)));
      }
    });
  }

  window.IGBLUE_SIDE_WS = {
    version: "v96",
    url: teAiwkLocalWsUrl,
    token: teAiwkLocalWsToken,
    setupZipUrl: teAiwkSetupZipUrl,
    isWsFailure,
    request
  };
})();
