using System;

namespace Barotrauma.Networking
{
    partial class RespawnManager
    {
        private DateTime lastShuttleLeavingWarningTime;

        public int PendingRespawnCount

        {
            get; private set;
        }

        public int RequiredRespawnCount
        {
            get; private set;
        }

        public bool ForceSpawnInMainSub
        {
            get; private set;
        }

        public DateTime ReturnTime { get; private set; }
        public DateTime RespawnTime { get; private set; }
        public State CurrentState { get; private set; }
        public bool ReturnCountdownStarted { get; private set; }
        public bool RespawnCountdownStarted { get; private set; }

        public static void ShowDeathPromptIfNeeded(float delay = 1.0f)
        {
            if (UseDeathPrompt)
            {
                DeathPrompt.Create(delay);
            }
        }

        partial void UpdateTransportingProjSpecific(TeamSpecificState teamSpecificState, float deltaTime)
        {
            if (GameMain.Client?.Character == null || 
                GameMain.Client.Character.Submarine is not { IsRespawnShuttle: true } ||
                GameMain.Client.Character.TeamID != teamSpecificState.TeamID) 
            {
                return; 
            }
            if (!teamSpecificState.ReturnCountdownStarted) { return; }

            //show a warning when there's 20 seconds until the shuttle leaves
            if ((teamSpecificState.ReturnTime - DateTime.Now).TotalSeconds < 20.0f && 
                (DateTime.Now - lastShuttleLeavingWarningTime).TotalSeconds > 30.0f)
            {
                lastShuttleLeavingWarningTime = DateTime.Now;
                GameMain.Client.AddChatMessage("ServerMessage.ShuttleLeaving", ChatMessageType.Server);
            }
        }

        public void ClientEventRead(IReadMessage msg, float sendingTime)
        {
            var myTeamId = (CharacterTeamType)msg.ReadByte();
            foreach (var teamSpecificState in teamSpecificStates.Values)
            {
                var teamId = (CharacterTeamType)msg.ReadByte();

                bool respawnPromptPending = false;
                bool clientHasChosenNewBotViaShuttle = false;
                var newState = (State)msg.ReadRangedInteger(0, Enum.GetNames(typeof(State)).Length);
                switch (newState)
                {
                    case State.Transporting:
                        teamSpecificState.ReturnCountdownStarted = msg.ReadBoolean();
                        maxTransportTime        = msg.ReadSingle();
                        float transportTimeLeft = msg.ReadSingle();
                        teamSpecificState.ReturnTime = DateTime.Now + new TimeSpan(0, 0, 0, 0, milliseconds: (int)(transportTimeLeft * 1000.0f));
                        teamSpecificState.RespawnCountdownStarted = false;
                        SetShuttleBodyType(teamSpecificState.TeamID, FarseerPhysics.BodyType.Dynamic);
                        break;
                    case State.Waiting:
                        teamSpecificState.PendingRespawnCount = msg.ReadUInt16();
                        teamSpecificState.RequiredRespawnCount = msg.ReadUInt16();
                        respawnPromptPending = msg.ReadBoolean();
                        clientHasChosenNewBotViaShuttle = msg.ReadBoolean();
                        teamSpecificState.RespawnCountdownStarted = msg.ReadBoolean();
                        ResetShuttle(teamSpecificState);
                        float newRespawnTime = msg.ReadSingle();
                        teamSpecificState.RespawnTime = DateTime.Now + new TimeSpan(0, 0, 0, 0, milliseconds: (int)(newRespawnTime * 1000.0f));
                        SetShuttleBodyType(teamSpecificState.TeamID, FarseerPhysics.BodyType.Static);
                        break;
                    case State.Returning:
                        teamSpecificState.RespawnCountdownStarted = false;
                        break;
                }
                teamSpecificState.CurrentState = newState;

                if (respawnPromptPending && !clientHasChosenNewBotViaShuttle)
                {
                    GameMain.Client.HasSpawned = true;
                    DeathPrompt.Create(delay: 1.0f);
                }

                if (teamId == myTeamId)
                {
                    PendingRespawnCount = teamSpecificState.PendingRespawnCount;
                    RequiredRespawnCount = teamSpecificState.RequiredRespawnCount;
                    ReturnTime = teamSpecificState.ReturnTime;
                    RespawnTime = teamSpecificState.RespawnTime;
                    CurrentState = teamSpecificState.CurrentState;
                    ReturnCountdownStarted = teamSpecificState.ReturnCountdownStarted;
                    RespawnCountdownStarted = teamSpecificState.RespawnCountdownStarted;
                }
            }
            
            msg.ReadPadBits();
        }
    }
}
