using Intrepid.Diagnostics;
using Intrepid.GameManagers;
using Intrepid.Gameplay.Messages.Events;
using Intrepid.Integration.Input;
using Intrepid.Integration.Persistence;
using Intrepid.Integration.Persistence.DTOs;
using Intrepid.Integration.Persistence.Events;
using Intrepid.SaveSystem;
using Intrepid.Structures;
using Intrepid.Utilities;
using UnityEngine;

namespace Intrepid.Gameplay.Entities.Player.Sentinel.StateMachine.States
{
    public class SentinelStateSavingStation : SentinelState
    {
        [GroupInjections, SerializeField] private GameDataPersistenceService gameDataPersistenceService;
        [GroupInjections, SerializeField] private AnimationClip savingStation;
        [GroupInjections, SerializeField, Range(0, 3)] private float minSavingStationDuration = 1f;

        private Timer Timer { get; } = new();
        
        public override SentinelStateType GetStateKey()
        {
            return SentinelStateType.SavingStation;
        }

        protected override void Subscriptions()
        {
            Subscribe<SavingGameDataBeginEvent>(e =>
            {
                DLogger.LogDebug($"Saving started");
            });
            Subscribe<SavingGameDataEndEvent>(e =>
            {
                DLogger.LogDebug($"Saving ended");
                Timer.Start();
            });
        }

        public override void RunOnFirstFrameOnly()
        {
            InputService.Instance.ChangeInputSchema(InputSchema.None);
            base.RunOnFirstFrameOnly();
        }

        protected override void RunOnEnter(ParameterStore ps)
        {
            var e = ps.Get<SaveStationActionExecutedEvent>("SaveStationActionExecutedEvent");
            Brain.Entity.DesiredVelocity = Vector2.zero;
            Brain.Entity.Position = e.DeploymentPoint;
            Brain.Entity.ChangeOrientation(Vector2.down);
            Brain.Entity.ModelAnimation.Play(savingStation);
            Timer.Stop();
            gameDataPersistenceService.SaveCurrentGameData(new SavingCallbacksAggregator<GameDataSaveFileDTO>(
                gameData =>
                {
                    gameData.data.SentinelData.LatestSaveStation = new SaveStationDTO
                    {
                        StageId = e.StageTag.StageId,
                        DeploymentPosition = e.DeploymentPoint.ToVector3DTO(),
                    };
                },
                _ => { }));
        }

        protected override void RunOnExit()
        {
            Timer.Stop();
        }

        public override void RunOnUpdate()
        {
            if (Timer.IsNotRunning) return;
            Timer.Update(Timer.ScaledTime);
            if (Timer.Check(minSavingStationDuration))
            {
                Timer.Stop();
                InputService.Instance.ChangeInputSchema(InputSchema.Sentinel);
                Brain.ChangeState(SentinelStateType.Idle);
            }
        }
    }
}