using DbConnectionLibrairie;
using DTOs;
using Microsoft.AspNetCore.Mvc;
using OrderCriterias;

namespace WebApi.Controllers
{
    public class FrontController
    {
        // all secondary controllers
        private AdministratorController administratorController;
        private AnswerController answerController;
        private ChapterController chapterController;
        private LobbyController lobbyController;
        private PlayerController playerController;
        private QuestionController questionController;

        public FrontController(
            MyDbContext dbContext,
            Logger<AdministratorController> logAdmin,
            Logger<AnswerController> logAnswer,
            Logger<ChapterController> logChapter,
            Logger<LobbyController> logLobby,
            Logger<PlayerController> logPlayer,
            Logger<QuestionController> logQuestion
        )
        {
            administratorController = new AdministratorController(dbContext, logAdmin);
            answerController = new AnswerController(dbContext, logAnswer);
            chapterController = new ChapterController(dbContext, logChapter);
            lobbyController = new LobbyController(dbContext, logLobby);
            playerController = new PlayerController(dbContext, logPlayer);
            questionController = new QuestionController(dbContext, logQuestion);
        }

        /// <summary>
        /// add an administrator
        /// </summary>
        /// <param name="administrator">the administrator to add</param>
        /// <returns>
        /// status code :
        /// 200 if the administrator is added
        /// 202 if the administrator is added
        /// 208 if the administrator was already in the database
        /// 500 if there was an internal error that doesn't allow to continue
        /// return content :
        /// no content when status code = 200
        /// administrator added when status code = 202
        /// administrator already in the database that equals the one we wanted to add when status code = 208
        /// no content when status code = 500
        /// </returns>
        [HttpPost("add/administrator/")]
        [ProducesResponseType(StatusCodes.Status200OK)]
        [ProducesResponseType(StatusCodes.Status202Accepted)]
        [ProducesResponseType(StatusCodes.Status208AlreadyReported)]
        [ProducesResponseType(StatusCodes.Status500InternalServerError)]
        public async Task<IActionResult> PostAdministrator([FromBody] AdministratorDto administrator)
            => await administratorController.PostAdministrator(administrator);

        /// <summary>
        /// get a part of all administrators
        /// </summary>
        /// <param name="page">the actual page</param>
        /// <param name="count">number of T element in a page</param>
        /// <param name="orderCriteria">the order criteria</param>
        /// <returns>
        /// status code :
        /// 200 if we got a set
        /// 204 if we got an empty set
        /// 400 if we got nothing
        /// 
        /// return content :
        /// a tuple of the number of page and
        /// all T element in the database for
        /// the page nb if status code = 200
        /// the number of page for count element if status code = 204
        /// nothing if status code = 400
        /// </returns>
        [HttpGet("administrators")]
        [ProducesResponseType(StatusCodes.Status200OK)]
        [ProducesResponseType(StatusCodes.Status204NoContent)]
        [ProducesResponseType(StatusCodes.Status400BadRequest)]
        public async Task<IActionResult> GetSomeAdministrators([FromQuery] int page, int count = 10,
            AdministratorOrderCriteria orderCriteria = AdministratorOrderCriteria.ById)
            => await administratorController.GetSomeAdministrators(page, count, orderCriteria);

        /// <summary>
        /// delete an administrator
        /// </summary>
        /// <param name="id">the id of the administrator to delete</param>
        /// <returns>
        /// <returns>
        /// status code :
        /// 200 if the administrator is removed
        /// 204 if the administrator is removed
        /// 400 if the id is incorrect
        /// 500 if there was an internal error that doesn't allow to continue
        /// return content :
        /// aministrator deleted when status code = 200
        /// no content when status code = 204
        /// no content when status code = 400
        /// no content when status code = 500
        /// </returns>
        [HttpDelete("delete/administrator")]
        [ProducesResponseType(StatusCodes.Status200OK)]
        [ProducesResponseType(StatusCodes.Status204NoContent)]
        [ProducesResponseType(StatusCodes.Status400BadRequest)]
        [ProducesResponseType(StatusCodes.Status500InternalServerError)]
        public async Task<IActionResult> DeleteAdministrator([FromQuery] int id)
            => await administratorController.DeleteAdministrator(id);

        /// <summary>
        /// update an administrator
        /// </summary>
        /// <param name="id">id of the administrator to update</param>
        /// <param name="administrator">an administrator who contains all properties to change</param>
        /// <returns>
        /// status code :
        /// 200 if the administrator is modified
        /// 204 if we wanted to modify an administrator who don't exist
        /// 208 if the new username of the administrator is already used
        /// 500 if there was an internal error that doesn't allow to continue
        /// 
        /// return content :
        /// the administrator modified when status code = 200
        /// nothing when status code = 204
        /// the administrator that already have the username when status code = 208
        /// nothing when status code = 500
        /// </returns>
        [HttpPut("update/administrator")]
        [ProducesResponseType(StatusCodes.Status200OK)]
        [ProducesResponseType(StatusCodes.Status204NoContent)]
        [ProducesResponseType(StatusCodes.Status208AlreadyReported)]
        [ProducesResponseType(StatusCodes.Status500InternalServerError)]
        public async Task<IActionResult> PutAdministrator([FromQuery] int id, [FromBody] AdministratorDto administrator)
            => await administratorController.PutAdministrator(id, administrator);


    }
}
