import { EventEmitter } from "events";
import WebSocket from "ws";
function getEnv(key, defaultValue) {
  const value = process.env[key];
  if (value === void 0) {
    if (defaultValue !== void 0) return defaultValue;
    throw new Error(`Environment variable ${key} is required`);
  }
  return value;
}
function getOptionalEnv(key) {
  return process.env[key];
}
class WebSocketClient extends EventEmitter {
  ws = null;
  url;
  reconnectTimer = null;
  reconnectAttempts = 0;
  maxReconnectAttempts = 10;
  reconnectDelay = 1e3;
  constructor(url) {
    super();
    this.url = url;
  }
  async connect() {
    return new Promise((resolve) => {
      try {
        const handleError = (error) => {
          clearTimeout(connectionTimeout);
          if (process.env["DEBUG"]) {
            console.log("WebSocket connection failed:", error.message);
          }
          if (this.ws) {
            this.ws.removeAllListeners();
            this.ws.terminate();
            this.ws = null;
          }
          resolve();
        };
        const connectionTimeout = setTimeout(() => {
          if (this.ws) {
            this.ws.removeAllListeners();
            this.ws.terminate();
            this.ws = null;
          }
          console.log("\u26A0\uFE0F  Running in offline mode (no WebSocket server)");
          this.emit("offline");
          resolve();
        }, 1e3);
        try {
          this.ws = new WebSocket(this.url);
        } catch (wsError) {
          handleError(wsError);
          return;
        }
        this.ws.once("error", handleError);
        this.ws.once("open", () => {
          clearTimeout(connectionTimeout);
          this.ws?.removeListener("error", handleError);
          this.ws?.on("error", (error) => {
            if (process.env["DEBUG"]) {
              console.error("WebSocket error during operation:", error);
            }
            this.emit("error", error);
          });
          console.log("\u2705 WebSocket connected");
          this.reconnectAttempts = 0;
          this.emit("connected");
          resolve();
        });
        this.ws.on("message", (data) => {
          this.handleMessage(data);
        });
        this.ws.once("close", () => {
          clearTimeout(connectionTimeout);
          if (this.reconnectAttempts > 0) {
            console.log("WebSocket disconnected");
            this.emit("disconnected");
            this.attemptReconnect();
          }
          resolve();
        });
      } catch (error) {
        console.log("\u26A0\uFE0F  Running in offline mode");
        this.emit("offline");
        resolve();
      }
    });
  }
  handleMessage(data) {
    try {
      const message = JSON.parse(data.toString());
      switch (message.type) {
        case "session:update":
          this.emit("session:update", message.data);
          break;
        case "task:update":
          this.emit("task:update", message.data);
          break;
        case "frame:update":
          this.emit("frame:update", message.data);
          break;
        case "agent:status":
          this.emit("agent:status", message.data);
          break;
        case "pr:update":
          this.emit("pr:update", message.data);
          break;
        case "analytics:update":
          this.emit("analytics:update", message.data);
          break;
        case "notification":
          this.emit("notification", message.data);
          break;
        default:
          this.emit("message", message);
      }
    } catch (error) {
      console.error("Failed to parse WebSocket message:", error);
    }
  }
  attemptReconnect() {
    if (this.reconnectAttempts >= this.maxReconnectAttempts) {
      this.emit("error", new Error("Max reconnection attempts reached"));
      return;
    }
    this.reconnectAttempts++;
    const delay = this.reconnectDelay * Math.pow(2, this.reconnectAttempts - 1);
    console.log(
      `Attempting to reconnect in ${delay}ms (attempt ${this.reconnectAttempts}/${this.maxReconnectAttempts})`
    );
    this.reconnectTimer = setTimeout(() => {
      this.connect().catch((error) => {
        console.error("Reconnection failed:", error);
      });
    }, delay);
  }
  send(type, data) {
    if (this.ws && this.ws.readyState === WebSocket.OPEN) {
      this.ws.send(JSON.stringify({ type, data }));
    } else {
      console.warn("WebSocket is not connected");
    }
  }
  disconnect() {
    if (this.reconnectTimer) {
      clearTimeout(this.reconnectTimer);
      this.reconnectTimer = null;
    }
    if (this.ws) {
      this.ws.close();
      this.ws = null;
    }
  }
  isConnected() {
    return this.ws !== null && this.ws.readyState === WebSocket.OPEN;
  }
}
export {
  WebSocketClient
};
//# sourceMappingURL=websocket-client.js.map
