import { Game } from './game';

export class Network {
  private game: Game;
  private colyseus: any; // Colyseus client
  private matchmakingRoom: any;
  private gameRoom: any;
  private playerId: string = '';
  private updateRate: number = 60; // Updates per second
  private lastUpdateTime: number = 0;

  constructor(game: Game) {
    this.game = game;
    this.initColyseus();
  }

  private async initColyseus() {
    // Dynamic import of Colyseus client
    const { Client } = await import('colyseus.js');
    this.colyseus = new Client('ws://localhost:3000');
  }

  async joinMatchmaking(playerName: string) {
    try {
      this.playerId = Math.random().toString(36).slice(2);
      
      this.matchmakingRoom = await this.colyseus.joinOrCreate('matchmaking', {
        username: playerName,
      });

      console.log('Joined matchmaking room');

      // Listen for match found
      this.matchmakingRoom.onMessage('match_found', (matchData: any) => {
        console.log('Match found!', matchData);
        this.joinGameRoom(matchData);
      });

      this.matchmakingRoom.onLeave(() => {
        console.log('Left matchmaking room');
      });
    } catch (error) {
      console.error('Failed to join matchmaking:', error);
      alert('Failed to connect to server');
    }
  }

  private async joinGameRoom(matchData: any) {
    try {
      if (this.matchmakingRoom) {
        await this.matchmakingRoom.leave();
      }

      this.gameRoom = await this.colyseus.joinOrCreate('game', {
        username: matchData.player1.username === this.game.getLocalPlayer?.()?.getState?.()?.username 
          ? matchData.player1.username 
          : matchData.player2.username,
        mapName: 'arena_01',
      });

      console.log('Joined game room');

      // Start game
      this.game.startMatch(matchData);

      // Listen for remote player updates
      this.gameRoom.onMessage('player_update', (data: any) => {
        this.game.updateRemotePlayer(data.playerId, data.state);
      });

      // Listen for opponent shots
      this.gameRoom.onMessage('shot_fired', (data: any) => {
        console.log('Shot received from opponent');
      });

      // Listen for match end
      this.gameRoom.onMessage('match_ended', (data: any) => {
        console.log('Match ended:', data);
        this.game.endMatch(data.winnerUsername);
      });

      this.gameRoom.onLeave(() => {
        console.log('Left game room');
      });

      // Start sending player updates
      this.startUpdateLoop();
    } catch (error) {
      console.error('Failed to join game:', error);
      alert('Failed to start game');
    }
  }

  private startUpdateLoop() {
    setInterval(() => {
      const localPlayer = this.game.getLocalPlayer();
      if (localPlayer && this.gameRoom) {
        this.sendPlayerUpdate(localPlayer.getState());
      }
    }, 1000 / this.updateRate);
  }

  sendPlayerUpdate(state: any) {
    if (this.gameRoom) {
      this.gameRoom.send('player_update', state);
    }
  }

  sendShot(position: any, direction: any, weapon: string) {
    if (this.gameRoom) {
      this.gameRoom.send('shot_fired', {
        position: { x: position.x, y: position.y, z: position.z },
        direction: { x: direction.x, y: direction.y, z: direction.z },
        weapon,
      });
    }
  }

  sendHitRegistered(targetId: string, damage: number) {
    if (this.gameRoom) {
      this.gameRoom.send('hit_registered', {
        targetId,
        damage,
      });
    }
  }
}
