using Intrepid.Core.GameState;
using Intrepid.Diagnostics;
using Intrepid.GameManagers;
using Intrepid.Integration.Input;
using Intrepid.Integration.Persistence;
using Intrepid.Theatre.BackStage;
using Intrepid.Theatre.Curtain;
using Intrepid.Utilities;
using UnityEngine;
using Cursor = UnityEngine.Cursor;

namespace Intrepid.Core
{
    [DefaultExecutionOrder(GonConstants.ExecutionOrder.ASAP)]
    public class GameManager : BaseGameManager
    {
        [GroupInjections, SerializeField] private SingletonScriptableObjectManifest manifest;
        [GroupInjections, SerializeField] private InputManager inputManager;
        [GroupInjections, SerializeField] private ConfigurationPersistenceService configurationPersistenceService;
        [GroupInjections, SerializeField] private GameDataPersistenceService gameDataPersistenceService;
        [GroupInjections, SerializeField] private GameStateMachine gameStateMachine;
        
        public static GameManager Instance => (GameManager)Proxy.Instance.GameManager;

        private GameStateMachine GameStateMachine => gameStateMachine;

        public ConfigurationPersistenceService ConfigurationPersistenceService => configurationPersistenceService;
        public GameDataPersistenceService GameDataPersistenceService => gameDataPersistenceService;
        
        public override void BootStrap()
        {
            manifest.Prewarm();
            base.BootStrap();
            ConfigurationPersistenceService.Load();
            // Cursor.lockState = CursorLockMode.Locked;
            Cursor.visible = false;
            InputService.Instance.ChangeInputSchema(InputSchema.None);
            DLogger.LogDebug($"resolution {InternalWidth} x {InternalHeight}");
        }
        
        public void ChangeGameStateTo(
            GameState.GameState gameState,
            CurtainTypeTag curtainType,
            BackStageProcessorAggregator processorAggregator)
        {
            if (GameStateMachine is null)
            {
                // this comment should not block, only inform
                DLogger.LogDebug("[WARN] there is no possible to change state, running tests...");
                return;
            }
            GameStateMachine.ChangeTo(gameState, curtainType, processorAggregator);
        }
    }
}