import { io, Socket } from "socket.io-client";

class WebSocketService {
  private socket: Socket | null = null;
  private reconnectAttempts = 0;
  private maxReconnectAttempts = 5;

  connect(url?: string) {
    // Use relative path for proxy support, or explicit URL if provided
    const defaultUrl =
      process.env.NEXT_PUBLIC_WATCH_FINISHED_API || window.location.origin;
    const wsUrl = url || defaultUrl;

    if (this.socket?.connected) {
      return this.socket;
    }

    this.socket = io(wsUrl, {
      path: "/socket.io",
      transports: ["websocket", "polling"]
    });

    this.socket.on("connect", () => {
      console.log("Connected to WebSocket server");
      this.reconnectAttempts = 0;
    });

    this.socket.on("disconnect", () => {
      console.log("Disconnected from WebSocket server");
    });

    this.socket.on("connect_error", (error) => {
      console.error("WebSocket connection error:", error);
      this.handleReconnect();
    });

    // Listen for various events
    this.socket.on("taskUpdate", (data) => {
      console.log("Task update:", data);
      // Dispatch custom event for React components
      window.dispatchEvent(new CustomEvent("taskUpdate", { detail: data }));
    });

    this.socket.on("fileUpdate", (data) => {
      console.log("File update:", data);
      window.dispatchEvent(new CustomEvent("fileUpdate", { detail: data }));
    });

    this.socket.on("watcherUpdate", (data) => {
      console.log("Watcher update:", data);
      window.dispatchEvent(new CustomEvent("watcherUpdate", { detail: data }));
    });

    return this.socket;
  }

  disconnect() {
    if (this.socket) {
      this.socket.disconnect();
      this.socket = null;
    }
  }

  joinRoom(room: string) {
    if (this.socket) {
      this.socket.emit("join", { room });
    }
  }

  leaveRoom(room: string) {
    if (this.socket) {
      this.socket.emit("leave", { room });
    }
  }

  private handleReconnect() {
    if (this.reconnectAttempts < this.maxReconnectAttempts) {
      this.reconnectAttempts++;
      setTimeout(() => {
        console.log(
          `Attempting to reconnect... (${this.reconnectAttempts}/${this.maxReconnectAttempts})`
        );
        this.socket?.connect();
      }, 2000 * this.reconnectAttempts); // Exponential backoff
    }
  }

  get isConnected() {
    return this.socket?.connected || false;
  }
}

export const wsService = new WebSocketService();
