using System;
using System.Threading;
using Content.Server.Interfaces.Chat;
using Content.Server.Interfaces.GameTicking;
using Robust.Shared.IoC;
using Robust.Shared.Localization;
using Timer = Robust.Shared.Timers.Timer;

namespace Content.Server.GameTicking.GameRules
{
    public sealed class RuleMaxTimeRestart : GameRule
    {
        [Dependency] private readonly IGameTicker _gameTicker = default!;
        [Dependency] private readonly IChatManager _chatManager = default!;

        private CancellationTokenSource _timerCancel = new();

        public TimeSpan RoundMaxTime { get; set; } = TimeSpan.FromMinutes(5);
        public TimeSpan RoundEndDelay { get; set; } = TimeSpan.FromSeconds(10);

        public override void Added()
        {
            base.Added();

            _gameTicker.OnRunLevelChanged += RunLevelChanged;
        }

        public override void Removed()
        {
            base.Removed();

            _gameTicker.OnRunLevelChanged -= RunLevelChanged;
            StopTimer();
        }

        public void RestartTimer()
        {
            _timerCancel.Cancel();
            _timerCancel = new CancellationTokenSource();
            Timer.Spawn(RoundMaxTime, TimerFired, _timerCancel.Token);
        }

        public void StopTimer()
        {
            _timerCancel.Cancel();
        }

        private void TimerFired()
        {
            _gameTicker.EndRound(Loc.GetString("Time has run out!"));

            _chatManager.DispatchServerAnnouncement(Loc.GetString("Restarting in {0} seconds.", (int) RoundEndDelay.TotalSeconds));

            Timer.Spawn(RoundEndDelay, () => _gameTicker.RestartRound());
        }

        private void RunLevelChanged(GameRunLevelChangedEventArgs args)
        {
            switch (args.NewRunLevel)
            {
                case GameRunLevel.InRound:
                    RestartTimer();
                    break;
                case GameRunLevel.PreRoundLobby:
                case GameRunLevel.PostRound:
                    StopTimer();
                    break;
            }
        }
    }
}
