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

export const socketEventConnected = "connected";
export const socketEventDisconnected = "disconnected";
export const socketEventCreateConnection = "create-connection";
export const socketEventCloseConnection = "leave-connection";
export const socketEventGetAllMessages = "getAllMessages";
export const socketEventSendMessage = "send-message";
export const socketEventGetMessage = "get_message";

class SocketService {
  private socket: Socket | null = null;
  private messageCallbacks: Map<string, (message: any) => void> = new Map();

  connect(url: string, userId: string, token?: string) {
    console.log("[SocketService] Connecting to:", url, "with user:", userId);
    
    if (this.socket?.connected) {
      console.log("[SocketService] Already connected");
      return this.socket;
    }

    if (!token) {
      console.warn("[SocketService] ⚠️ No token provided — connection may be unauthorized!");
    }

    this.socket = io(url, {
      extraHeaders: {
        token: token || "",
        language: "en",
      },
      reconnection: true,
      reconnectionAttempts: 10,
      reconnectionDelay: 2000,
    });

    this.socket.on(socketEventConnected, () => {
      console.log("[SocketService] ✅ Connected:", this.socket?.id);
    });

    this.socket.on(socketEventDisconnected, () => {
      console.log("[SocketService] ❌ Disconnected");
    });

    this.socket.on("connect_error", (err) => {
      console.error("[SocketService] ❗ Connection error:", err.message);
    });

    this.socket.on("exception", (error) => {
      console.error("[SocketService] Socket exception:", error);
    });

    this.socket.on("error", (err) => {
      console.error("[SocketService] Socket error:", err);
    });

    return this.socket;
  }

  isConnected() {
    const connected = this.socket?.connected || false;
    console.log("[SocketService] isConnected:", connected);
    return connected;
  }

  // ✅ Listen for create-connection response
  onConnectionCreated(callback: (data: any) => void) {
    if (!this.socket) {
      console.warn("[SocketService] onConnectionCreated called without socket");
      return () => {};
    }
    
    console.log("[SocketService] 👂 Connection listener registered");
    this.socket.on(socketEventCreateConnection, callback);
    
    return () => {
      console.log("[SocketService] 🧹 Connection listener removed");
      this.socket?.off(socketEventCreateConnection, callback);
    };
  }

  // ✅ Emit create-connection request
  createConnection(orderId: string, restaurantId: string, driverId: string) {
    if (!this.socket) {
      console.warn("[SocketService] createConnection called without socket");
      return;
    }
    
    const payload = {
      order_id: orderId,
      receiver_id: driverId,
      receiver_type: "driver"
    };
    
    console.log("[SocketService] 🔗 Creating connection:", payload);
    this.socket.emit(socketEventCreateConnection, payload);
  }

  closeConnection(orderId: string) {
    if (!this.socket) {
      console.warn("[SocketService] closeConnection called without socket");
      return;
    }
    console.log("[SocketService] 🔒 Closing connection:", { orderId });
    this.socket.emit(socketEventCloseConnection, { orderId });
  }

  // ✅ Get all messages - listen for response
  getAllMessages(orderId: string, connectionId: string, callback: (messages: any[]) => void) {
    if (!this.socket) {
      console.warn("[SocketService] getAllMessages called without socket");
      return;
    }

    const listener = (data: any) => {
      console.log("[SocketService] getAllMessages response:", data);

      let normalizedMessages: any[] = [];
      if (Array.isArray(data?.data)) normalizedMessages = data.data;
      else if (Array.isArray(data?.messages)) normalizedMessages = data.messages;
      else if (Array.isArray(data?.allMessages)) normalizedMessages = data.allMessages;

      callback(normalizedMessages);
      this.socket?.off(socketEventGetAllMessages, listener);
    };

    this.socket.on(socketEventGetAllMessages, listener);

    const payload = {
      order_id: orderId,
      connection_id: connectionId
    };

    console.log("[SocketService] Emitting getAllMessages with:", payload);
    this.socket.emit(socketEventGetAllMessages, payload);
  }

  sendMessage(data: any) {
    if (!this.socket) {
      console.warn("[SocketService] sendMessage called without socket");
      return;
    }
    console.log("[SocketService] 📨 Sending message:", data);
    this.socket.emit(socketEventSendMessage, data);
  }

  onMessage(callback: (message: any) => void) {
    if (!this.socket) {
      console.warn("[SocketService] onMessage called without socket");
      return () => {};
    }

    const id = Math.random().toString(36);
    console.log("[SocketService] 👂 Message listener registered:", id);
    
    this.socket.on(socketEventGetMessage, callback);
    this.messageCallbacks.set(id, callback);

    return () => {
      console.log("[SocketService] 🧹 Message listener removed:", id);
      this.socket?.off(socketEventGetMessage, callback);
      this.messageCallbacks.delete(id);
    };
  }

  disconnect() {
    if (this.socket) {
      console.log("[SocketService] 🔌 Disconnecting...");
      this.socket.disconnect();
      this.socket = null;
      this.messageCallbacks.clear();
    }
  }

  getSocket() {
    return this.socket;
  }
}

export default new SocketService();