import {
  WebSocketGateway,
  WebSocketServer,
  OnGatewayInit,
  OnGatewayConnection,
  OnGatewayDisconnect,
} from '@nestjs/websockets';
import { Server, Socket } from 'socket.io';
import { Logger, Injectable } from '@nestjs/common';
import { BackupTarget } from '@/domain/enums';

@Injectable()
@WebSocketGateway({
  namespace: '/snapshots',
  cors: {
    origin: '*',
    credentials: true,
  },
  transports: ['websocket', 'polling'],
})
export class SnapshotGateway
  implements OnGatewayInit, OnGatewayConnection, OnGatewayDisconnect
{
  @WebSocketServer()
  server: Server;

  private readonly logger = new Logger(SnapshotGateway.name);
  private connectedClients = 0;

  afterInit() {
    this.logger.log('Snapshot WebSocket Gateway initialized');
  }

  handleConnection(client: Socket) {
    this.connectedClients++;
    this.logger.log(`Client connected: ${client.id}, total: ${this.connectedClients}`);
  }

  handleDisconnect(client: Socket) {
    this.connectedClients--;
    this.logger.log(`Client disconnected: ${client.id}, total: ${this.connectedClients}`);
  }

  emitTaskStarted(taskId: string, targets: BackupTarget[]): void {
    if (this.server && this.connectedClients > 0) {
      this.server.emit('snapshot:started', { taskId, targets });
    }
  }

  emitProgress(taskId: string, target: string, percent: number, message: string): void {
    if (this.server && this.connectedClients > 0) {
      this.server.emit('snapshot:progress', { taskId, target, percent, message });
    }
  }

  emitTargetComplete(taskId: string, target: string, fileSize: number): void {
    if (this.server && this.connectedClients > 0) {
      this.server.emit('snapshot:target-complete', {
        taskId,
        target,
        fileSize: fileSize.toString(),
      });
    }
  }

  emitComplete(taskId: string, totalSize: number, duration: number): void {
    if (this.server && this.connectedClients > 0) {
      this.server.emit('snapshot:complete', {
        taskId,
        totalSize: totalSize.toString(),
        duration,
      });
    }
  }

  emitError(taskId: string, target: string | undefined, error: string): void {
    if (this.server && this.connectedClients > 0) {
      this.server.emit('snapshot:error', { taskId, target, error });
    }
  }
}
