using DoomDeathmatch.Component.MVC.Score;
using DoomDeathmatch.Component.MVC.Timer;
using DoomDeathmatch.Component.UI;
using DoomDeathmatch.Scene.GameOver;
using DoomDeathmatch.Scene.Play;
using Engine.Input;
using Engine.Util;

namespace DoomDeathmatch.Component.MVC;

public class GameController : Engine.Scene.Component.Component
{
  public bool IsPaused { get; private set; } = false;
  public bool IsGameOver { get; private set; } = false;

  public PlayerController PlayerController { get; private set; } = null!;
  public ScoreController ScoreController { get; private set; } = null!;

  private TimerController _timerController = null!;

  private readonly MenuControllerComponent _menuController;
  private readonly IInputHandler _inputHandler = EngineUtil.InputHandler;

  public GameController(MenuControllerComponent parMenuController)
  {
    _menuController = parMenuController;
  }

  public override void Awake()
  {
    ScoreController = GameObject.GetComponent<ScoreController>()!;
    PlayerController = EngineUtil.SceneManager.CurrentScene!.FindFirstComponent<PlayerController>()!;
    _timerController = GameObject.GetComponent<TimerController>()!;

    ArgumentNullException.ThrowIfNull(ScoreController);
    ArgumentNullException.ThrowIfNull(_timerController);
    ArgumentNullException.ThrowIfNull(PlayerController);

    PlayerController.OnDeath += GameOver;
    _timerController.OnFinished += GameOver;
  }

  public void Unpause()
  {
    EngineUtil.SceneManager.CurrentScene!.TimeScale = 1.0f;
    IsPaused = false;
    _menuController.SelectMenuItem("play");
  }

  public void Pause()
  {
    EngineUtil.SceneManager.CurrentScene!.TimeScale = 0.0f;
    IsPaused = true;
    _menuController.SelectMenuItem("escape");
  }

  public override void Update(double parDeltaTime)
  {
    if (_inputHandler.IsKeyJustPressed(KeyboardButtonCode.Escape))
    {
      if (IsPaused)
      {
        Unpause();
      }
      else
      {
        Pause();
      }
    }
  }

  private void GameOver()
  {
    IsGameOver = true;
    EngineUtil.SceneManager.TransitionTo(() => GameOverScene.Create(ScoreController.Score));
  }
}