using Microsoft.AspNetCore.Mvc;

namespace ScoreboardApi.Controllers
{
    using ScoreboardApi.Extensions;
    using ScoreboardApi.Objects;

    [Route("api/[controller]")]
    [ApiController]
    public class ScoreController : ControllerBase
    {
        private readonly IGameManager gameManager;

        public ScoreController(IGameManager gameManager)
        {
            this.gameManager = gameManager;
        }

        /// <summary>
        /// Get the current match score
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public ActionResult GetCurrentScore() =>
            Ok(gameManager.GetScore());

        /// <summary>
        /// Abbreviated match summary for displays
        /// </summary>
        /// <returns>Simple Match summary indicating the match state, and the points for each team</returns>
        [HttpGet]
        [Route("summary")]
        public ActionResult GetScoreSummary()
        {
            var game = gameManager.GetScore();

            return Ok(
                new
                {
                    Home = game.Home.Points,
                    Away = game.Away.Points,
                    State = game.State
                });
        }

        /// <summary>
        /// Start a New Game
        /// </summary>
        /// <param name="request">
        ///   Details about the game to start
        /// </param>
        [HttpPost]
        public ActionResult StartNewGame([FromBody] StartGameRequest request)
        {
            if (request.Home == null || request.Away == null)
            {
                return BadRequest();
            }

            if (request.KickOffTime == default)
            {
                request.KickOffTime = DateTimeOffset.Now;
            }

            gameManager.StartNew(request.Home, request.Away, request.KickOffTime);
            return Ok();
        }

        /// <summary>
        /// Add new event to the given team.
        /// </summary>
        /// <param name="newEvent">The new event to add. Event Category indicates who the event belongs to.</param>
        [HttpPatch]
        [Route("event")]
        public ActionResult AddEvent([FromBody] Event newEvent)
        {
            if (!Enum.IsDefined(newEvent.EventType))
            {
                return BadRequest($"{nameof(EventType)} supplied is invalid.");
            }
            if(gameManager.GetScore().State == GameState.TimeOff && !newEvent.EventType.IsMatchEvent())
            {
                return BadRequest($"{newEvent.EventType} is not valid when Time is Off");
            }

            if (newEvent.EventType.IsMatchEvent())
            {
                newEvent.Category = EventCategory.Match;
            }
            else if (!Enum.IsDefined(newEvent.Category))
            {
                return BadRequest($"{nameof(EventCategory)} supplied is invalid.");
            }

            if (newEvent.TimeStamp == default)
            {
                newEvent.TimeStamp = DateTimeOffset.Now;
            }

            gameManager.AddEvent(newEvent);
            return Ok();
        }

        /// <summary>
        /// End the current game
        /// </summary>
        [HttpPatch]
        [Route("endGame")]
        public void EndGame()
        {
            gameManager.Finish();
        }

        /// <summary>
        /// Reset the system, remove all current data.
        /// </summary>
        [HttpDelete]
        public void ResetGame()
        {
            gameManager.ResetGame();
        }

        /// <summary>
        /// Remove the given event from the collection
        /// </summary>
        /// <param name="eventId"></param>
        [HttpDelete]
        [Route("event/{eventId}")]
        public void DeleteEvent(int eventId)
        {
            gameManager.DeleteEvent(eventId);
        }
    }
}