import {
  OnGatewayConnection,
  OnGatewayDisconnect,
  WebSocketGateway,
  WebSocketServer,
} from '@nestjs/websockets';

import { Server, Socket } from 'socket.io';

@WebSocketGateway({
  cors: {
    origin: '*',
  },
})
export class NotificationGateway
  implements OnGatewayConnection, OnGatewayDisconnect
{
  @WebSocketServer()
  server: Server;

  private memberSockets = new Map<string, string>();
  private ownerSockets = new Map<string, string>();

  handleConnection(client: Socket) {
    const memberId = client.handshake.auth.memberId as string;
    const ownerId = client.handshake.auth.ownerId as string;

    // console.log('🔥 SOCKET CONNECTED', {
    //   socketId: client.id,
    //   memberId,
    //   ownerId,
    // });

    if (memberId) {
      this.memberSockets.set(memberId, client.id);

      // console.log('✅ Member connected', {
      //   memberId,
      //   socketId: client.id,
      // });
    }

    if (ownerId) {
      this.ownerSockets.set(ownerId, client.id);

      // console.log('✅ Owner connected', {
      //   ownerId,
      //   socketId: client.id,
      // });
    }
  }

  handleDisconnect(client: Socket) {
    for (const [memberId, socketId] of this.memberSockets.entries()) {
      if (socketId === client.id) {
        this.memberSockets.delete(memberId);

        console.log('❌ Member disconnected', {
          memberId,
        });

        break;
      }
    }

    for (const [ownerId, socketId] of this.ownerSockets.entries()) {
      if (socketId === client.id) {
        this.ownerSockets.delete(ownerId);

        console.log('❌ Owner disconnected', {
          ownerId,
        });

        break;
      }
    }
  }

  sendToUser(memberId: string, data: any) {
    const socketId = this.memberSockets.get(memberId);

    console.log('📤 sendToUser', {
      memberId,
      socketId,
      hasSocket: !!socketId,
    });

    if (!socketId) {
      return;
    }

    this.server.to(socketId).emit('notification', data);
  }

  sendToOwner(ownerId: string, data: any) {
    const socketId = this.ownerSockets.get(ownerId);

    console.log('📤 sendToOwner', {
      ownerId,
      socketId,
      hasSocket: !!socketId,
    });

    if (!socketId) {
      return;
    }

    this.server.to(socketId).emit('notification', data);
  }

  sendToUsers(memberIds: string[], data: any) {
    memberIds.forEach((id) => {
      this.sendToUser(id, data);
    });
  }
}
