import * as BABYLON from '@babylonjs/core';

export class Player {
  private mesh: BABYLON.Mesh;
  private camera: BABYLON.UniversalCamera;
  private scene: BABYLON.Scene;
  private isLocalPlayer: boolean;
  public currentWeapon: string = 'pistol';
  public health: number = 100;
  public position: BABYLON.Vector3;
  public rotation: BABYLON.Vector3;
  private velocity: BABYLON.Vector3 = BABYLON.Vector3.Zero();
  private keys: Map<string, boolean> = new Map();

  constructor(camera: BABYLON.UniversalCamera, scene: BABYLON.Scene, playerData: any, isLocal: boolean) {
    this.camera = camera;
    this.scene = scene;
    this.isLocalPlayer = isLocal;
    this.position = new BABYLON.Vector3(playerData.x || 0, playerData.y || 1.6, playerData.z || 0);
    this.rotation = BABYLON.Vector3.Zero();

    // Create player mesh (capsule-like shape for remote players)
    if (!isLocal) {
      const mesh = BABYLON.MeshBuilder.CreateCapsule('player_' + playerData.id, { radius: 0.3, height: 1.8 }, scene);
      mesh.position = this.position;
      
      const material = new BABYLON.StandardMaterial('playerMat_' + playerData.id, scene);
      material.emissiveColor = new BABYLON.Color3(0, 0.5, 1);
      mesh.material = material;
      mesh.checkCollisions = true;

      this.mesh = mesh;
    } else {
      // Local player uses camera
      this.mesh = camera as any; // Hack: treat camera as mesh for consistency
    }

    // Setup keyboard controls for local player
    if (isLocal) {
      this.setupControls();
    }
  }

  private setupControls() {
    window.addEventListener('keydown', (e) => {
      this.keys.set(e.key.toLowerCase(), true);
    });

    window.addEventListener('keyup', (e) => {
      this.keys.set(e.key.toLowerCase(), false);
    });

    // Mouse click for shooting
    window.addEventListener('mousedown', (e) => {
      if (e.button === 0) { // Left click
        this.keys.set('shoot', true);
      }
    });

    window.addEventListener('mouseup', (e) => {
      if (e.button === 0) {
        this.keys.set('shoot', false);
      }
    });
  }

  update(camera: BABYLON.UniversalCamera) {
    if (!this.isLocalPlayer) return;

    // Handle movement
    const moveDirection = BABYLON.Vector3.Zero();
    const speed = 0.15;

    if (this.keys.get('w')) moveDirection.z += 1;
    if (this.keys.get('a')) moveDirection.x -= 1;
    if (this.keys.get('s')) moveDirection.z -= 1;
    if (this.keys.get('d')) moveDirection.x += 1;

    if (moveDirection.length() > 0) {
      moveDirection.normalize();
      
      // Rotate movement by camera angle
      const forward = BABYLON.Vector3.Forward();
      const right = BABYLON.Vector3.Right();
      const cameraForward = BABYLON.Vector3.TransformCoordinates(forward, BABYLON.Matrix.RotationY(camera.rotation.y));
      const cameraRight = BABYLON.Vector3.TransformCoordinates(right, BABYLON.Matrix.RotationY(camera.rotation.y));

      const finalDirection = cameraRight.scale(moveDirection.x).add(cameraForward.scale(moveDirection.z));
      
      camera.position.x += finalDirection.x * speed;
      camera.position.z += finalDirection.z * speed;
    }

    // Update stored position
    this.position = camera.position;
    this.rotation = camera.rotation;
  }

  setRemoteState(state: any) {
    if (this.isLocalPlayer || !this.mesh) return;

    this.position = new BABYLON.Vector3(state.x, state.y, state.z);
    this.mesh.position = this.position;
    this.mesh.rotation = new BABYLON.Vector3(state.rotationX, state.rotationY, 0);
    this.health = state.health;
    this.currentWeapon = state.weapon;

    if (!state.isAlive && this.health <= 0) {
      this.mesh.dispose();
    }
  }

  takeDamage(amount: number) {
    this.health -= amount;
    if (this.health < 0) this.health = 0;
  }

  getState() {
    return {
      x: this.position.x,
      y: this.position.y,
      z: this.position.z,
      rotationX: this.rotation.x,
      rotationY: this.rotation.y,
      weapon: this.currentWeapon,
      health: this.health,
    };
  }

  getMesh(): BABYLON.Mesh {
    return this.mesh;
  }

  switchWeapon(weaponName: string) {
    this.currentWeapon = weaponName;
  }
}
