import {
  ConnectedSocket,
  MessageBody, OnGatewayConnection,
  OnGatewayDisconnect,
  SubscribeMessage,
  WebSocketGateway,
  WebSocketServer, WsResponse
} from "@nestjs/websockets";
import { Server, Socket } from 'socket.io';
import { Injectable, Logger } from "@nestjs/common";
import { from, map, Observable } from 'rxjs';


export const enum ClientNotificationType {
  StateChanged = 'state_changed',
  PhotosUpdated = 'photos_updated',
  ValidAnswerReceived = 'answer_received',
  WrongAnswerReceived = 'wrong_answer_received',
  UserAdded = 'user_added',
  UserPropertyChanged = 'user_property_changed',
  CardsChanged = 'cards_changed',
  CardPlayed = 'card_played',
  ScoreChanged = 'score_changed',
  GameQueueItem = 'game_queue',
  QueueCompleted = 'queue_completed',
  GamePaused = 'game_paused',
  GameResumed = 'game_resumed',
  Notification = 'notification',
  FeatureFlagChanged = 'feature_flag_changed',
  BeginVersus = 'begin_versus',
  EndVersus = 'end_versus',
  QuestionChanged = 'question_changed'
}

@WebSocketGateway({ cors: true, transports: ['websocket']})
@Injectable()
export class SocketGateway implements OnGatewayConnection, OnGatewayDisconnect{
  private readonly logger = new Logger(SocketGateway.name);
  @WebSocketServer()
  server: Server;
  clients: Socket[] = [];
  @SubscribeMessage('events')
  findAll(@MessageBody() data: any): Observable<WsResponse<number>> {
    return from([1, 2, 3]).pipe(
      map((item) => ({ event: 'events', data: item })),
    );
  }

  @SubscribeMessage('identity')
  async identity(@MessageBody() data: number): Promise<number> {
    return data;
  }

  @SubscribeMessage('events')
  handleEvent(
    @MessageBody() data: string,
    @ConnectedSocket() client: Socket,
  ): string {
    return data;
  }

  handleConnection(client: Socket, ...args: any[]): any {
    this.logger.warn('new user connected... ');
    this.clients.push(client);
  }

  handleDisconnect(client: Socket): any {
    this.clients = this.clients.filter((c) => c.id !== client.id);
  }


  notifyAllClients(event: ClientNotificationType, payload: any) {
    this.server.emit("events", { event, data: payload});
    // this.logger.warn(`send notification to all clients ${event}`);
    // this.clients.forEach((c) => {
    //   c.emit('events', { event, data: payload});
    // });
  }
}
