import { Room, Client } from 'colyseus';
import { Schema, type, ArraySchema } from '@colyseus/schema';

class Player extends Schema {
  @type('string') id: string;
  @type('string') username: string;
}

class MatchmakingState extends Schema {
  @type([Player]) waitingPlayers = new ArraySchema<Player>();
  @type('number') playerCount: number = 0;
}

export class MatchmakingRoom extends Room<MatchmakingState> {
  maxClients = 1000;
  private waitingPlayers: Map<string, { client: Client; username: string }> = new Map();

  onCreate(options: any) {
    console.log('Matchmaking room created');
    this.setState(new MatchmakingState());
  }

  onJoin(client: Client, options: any) {
    const username = options.username || `Player_${client.sessionId.slice(0, 6)}`;
    
    console.log(`${username} joined matchmaking (Total: ${this.clients.length})`);
    
    this.waitingPlayers.set(client.sessionId, { client, username });
    
    // Add to state
    const player = new Player();
    player.id = client.sessionId;
    player.username = username;
    this.state.waitingPlayers.push(player);
    this.state.playerCount = this.waitingPlayers.size;

    // Try to find a match
    this.tryMatchmaking();
  }

  onLeave(client: Client, consented: boolean) {
    console.log(`${client.sessionId} left matchmaking`);
    this.waitingPlayers.delete(client.sessionId);
    
    // Remove from state
    const index = this.state.waitingPlayers.findIndex((p) => p.id === client.sessionId);
    if (index !== -1) {
      this.state.waitingPlayers.removeAt(index);
    }
    this.state.playerCount = this.waitingPlayers.size;
  }

  private tryMatchmaking() {
    if (this.waitingPlayers.size < 2) return;

    // Get first two waiting players
    const players = Array.from(this.waitingPlayers.entries()).slice(0, 2);
    const [player1Id, player1Data] = players[0];
    const [player2Id, player2Data] = players[1];

    console.log(`🎮 Match found: ${player1Data.username} vs ${player2Data.username}`);

    // Remove from waiting list
    this.waitingPlayers.delete(player1Id);
    this.waitingPlayers.delete(player2Id);

    // Remove from state
    this.state.waitingPlayers = new ArraySchema(
      ...this.state.waitingPlayers.filter((p) => p.id !== player1Id && p.id !== player2Id)
    );
    this.state.playerCount = this.waitingPlayers.size;

    // Notify both players that a match was found
    const matchData = {
      matchId: `match_${Date.now()}`,
      player1: { id: player1Id, username: player1Data.username },
      player2: { id: player2Id, username: player2Data.username },
    };

    player1Data.client.send('match_found', matchData);
    player2Data.client.send('match_found', matchData);

    // Continue matching if more players
    setTimeout(() => this.tryMatchmaking(), 100);
  }

  onDispose() {
    console.log('Matchmaking room disposed');
  }
}
