using DoomDeathmatch.Component.UI;
using DoomDeathmatch.Scene.Play;
using Engine.Scene;
using OpenTK.Mathematics;

namespace DoomDeathmatch.Scene;

public static class MainScene
{
  public static Engine.Scene.Scene Create(Engine.Engine parEngine)
  {
    var scene = new Engine.Scene.Scene();

    var (cameraObject, camera) = UiUtil.CreateOrthographicCamera(scene);

    var (uiContainerObject, uiContainer) =
      UiUtil.CreateBackgroundUi(scene, new UiContainerComponent { Camera = camera });

    var (logoObject, logoUi) = UiUtil.CreateLogoUi(parEngine, scene, uiContainer);
    logoUi.Offset = new Vector2(0, 3f);
    scene.AddChild(uiContainerObject, logoObject);

    var menuController = new MenuControllerComponent();
    var menuControllerObject = GameObjectUtil.CreateGameObject(scene, [
      menuController
    ]);

    var mainMenu = CreateMainMenu(parEngine, scene, uiContainer, menuController);
    menuController.AddMenuItem("main", mainMenu);

    var leadersMenu = CreateLeadersMenu(parEngine, scene, uiContainer, menuController);
    leadersMenu.IsEnabled = false;
    menuController.AddMenuItem("leaders", leadersMenu);

    var rulesMenu = CreateRulesMenu(parEngine, scene, uiContainer, menuController);
    rulesMenu.IsEnabled = false;
    menuController.AddMenuItem("rules", rulesMenu);

    scene.AddChild(uiContainerObject, mainMenu);
    scene.AddChild(uiContainerObject, leadersMenu);
    scene.AddChild(uiContainerObject, rulesMenu);

    return scene;
  }

  private static GameObject CreateMainMenu(Engine.Engine parEngine, Engine.Scene.Scene parScene,
    UiContainerComponent parUiContainer, MenuControllerComponent parMenuController)
  {
    var parentObject = GameObjectUtil.CreateGameObject(parScene);

    var (playUiObject, playUi, _) =
      UiUtil.CreateTextUi(parScene, parUiContainer, UiUtil.GetDoomFont(parEngine), "Играть");

    var (leadersUiObject, leadersUi, _) =
      UiUtil.CreateTextUi(parScene, parUiContainer, UiUtil.GetDoomFont(parEngine), "Лидеры");

    var (rulesUiObject, rulesUi, _) =
      UiUtil.CreateTextUi(parScene, parUiContainer, UiUtil.GetDoomFont(parEngine), "Правила");

    var (exitUiObject, exitUi, _) =
      UiUtil.CreateTextUi(parScene, parUiContainer, UiUtil.GetDoomFont(parEngine), "Выход");

    var (stackObject, stack) = UiUtil.CreateStackUi(parScene,
      new StackComponent
      {
        Offset = new Vector2(0, -1f), Container = parUiContainer, Children = { playUi, leadersUi, rulesUi, exitUi }
      });
    stackObject.Transform.Size.Xy = new Vector2(1f, 6f);

    playUi.OnClick += _ => parEngine.SceneManager.TransitionTo(() => PlayScene.Create(parEngine));
    leadersUi.OnClick += _ => parMenuController.SelectMenuItem("leaders");
    rulesUi.OnClick += _ => parMenuController.SelectMenuItem("rules");
    exitUi.OnClick += _ => parEngine.Close();

    var (selectorObject, selector) = UiUtil.CreateSelectorUi(parScene,
      new SelectorComponent { Children = { playUi, leadersUi, rulesUi, exitUi } });

    parScene.AddChild(parentObject, selectorObject);
    parScene.AddChild(parentObject, stackObject);

    parScene.AddChild(stackObject, playUiObject);
    parScene.AddChild(stackObject, leadersUiObject);
    parScene.AddChild(stackObject, rulesUiObject);
    parScene.AddChild(stackObject, exitUiObject);

    return parentObject;
  }

  private static GameObject CreateLeadersMenu(Engine.Engine parEngine, Engine.Scene.Scene parScene,
    UiContainerComponent parUiContainer, MenuControllerComponent parMenuController)
  {
    var parentObject = GameObjectUtil.CreateGameObject(parScene);

    var (backUiObject, backUi, _) = UiUtil.CreateTextUi(parScene, parUiContainer,
      UiUtil.GetDoomFont(parEngine), "Назад");
    backUi.OnClick += _ => parMenuController.SelectMenuItem("main");

    var (stackObject, stack) = UiUtil.CreateStackUi(parScene,
      new StackComponent { Offset = new Vector2(0, -1f), Container = parUiContainer, Children = { backUi } });
    stackObject.Transform.Size.Xy = new Vector2(1f, 6f);

    var (selectorObject, selector) = UiUtil.CreateSelectorUi(parScene, new SelectorComponent { Children = { backUi } });

    parScene.AddChild(parentObject, selectorObject);
    parScene.AddChild(parentObject, stackObject);
    parScene.AddChild(stackObject, backUiObject);

    return parentObject;
  }

  private static GameObject CreateRulesMenu(Engine.Engine parEngine, Engine.Scene.Scene parScene,
    UiContainerComponent parUiContainer, MenuControllerComponent parMenuController)
  {
    var parentObject = GameObjectUtil.CreateGameObject(parScene);

    var (backUiObject, backUi, _) = UiUtil.CreateTextUi(parScene, parUiContainer,
      UiUtil.GetDoomFont(parEngine), "Назад");
    backUi.OnClick += _ => parMenuController.SelectMenuItem("main");

    var (rulesObject, rulesUi, _) = UiUtil.CreateTextUi(parScene, parUiContainer,
      UiUtil.GetDoomFont(parEngine), "Правила");

    var (stackObject, stack) = UiUtil.CreateStackUi(parScene,
      new StackComponent { Offset = new Vector2(0, -1f), Container = parUiContainer, Children = { rulesUi, backUi } });
    stackObject.Transform.Size.Xy = new Vector2(1f, 6f);

    var (selectorObject, selector) = UiUtil.CreateSelectorUi(parScene, new SelectorComponent { Children = { backUi } });

    parScene.AddChild(parentObject, selectorObject);

    parScene.AddChild(parentObject, stackObject);

    parScene.AddChild(stackObject, rulesObject);
    parScene.AddChild(stackObject, backUiObject);

    return parentObject;
  }
}