using Manager.DTOs; using Manager.Helpers; using ManagerService.Data; using ManagerService.Data.SubSection; using ManagerService.DTOs; using ManagerService.Services; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; using Mqtt.Client.AspNetCore.Services; using Newtonsoft.Json; using NSwag.Annotations; using System; using System.Collections.Generic; using System.Linq; using System.Reflection.Emit; using System.Text.Json; namespace ManagerService.Controllers { [Authorize] // TODO Add ROLES (Roles = "Admin") [ApiController, Route("api/[controller]")] [OpenApiTag("Section quiz", Description = "Section quiz management")] public class SectionQuizController : ControllerBase { private readonly MyInfoMateDbContext _myInfoMateDbContext; private readonly ILogger _logger; private readonly IConfiguration _configuration; IHexIdGeneratorService idService = new HexIdGeneratorService(); public SectionQuizController(IConfiguration configuration, ILogger logger, MyInfoMateDbContext myInfoMateDbContext) { _logger = logger; _configuration = configuration; _myInfoMateDbContext = myInfoMateDbContext; } /// /// Get all quiz questions from section /// /// Section id [AllowAnonymous] [ProducesResponseType(typeof(List), 200)] [ProducesResponseType(typeof(string), 404)] [ProducesResponseType(typeof(string), 500)] [HttpGet("{sectionId}/questions")] public ObjectResult GetAllQuizQuestionFromSection(string sectionId) { try { SectionQuiz sectionQuiz = _myInfoMateDbContext.Sections.OfType().Include(sq => sq.QuizQuestions).ThenInclude(qq => qq.Resource).FirstOrDefault(sq => sq.Id == sectionId); List questionDTOs = new List(); foreach (var question in sectionQuiz.QuizQuestions) { questionDTOs.Add(new QuestionDTO() { id = question.Id, label = question.Label, responses = question.Responses, imageBackgroundResourceId = question.ResourceId, imageBackgroundResourceType = question.Resource.Type, imageBackgroundResourceUrl = question.Resource.Url, order = question.Order }); } return new OkObjectResult(questionDTOs); } catch (KeyNotFoundException ex) { return new NotFoundObjectResult(ex.Message) { }; } catch (Exception ex) { return new ObjectResult(ex.Message) { StatusCode = 500 }; } } /// /// Create new question /// /// Section Id /// question [ProducesResponseType(typeof(QuizQuestion), 200)] [ProducesResponseType(typeof(string), 400)] [ProducesResponseType(typeof(string), 409)] [ProducesResponseType(typeof(string), 500)] [HttpPost("{sectionId}/questions")] public ObjectResult Create(string sectionId, [FromBody] QuestionDTO questionDTO) { try { if (sectionId == null) throw new ArgumentNullException("Section param is null"); if (questionDTO == null) throw new ArgumentNullException("Question is null"); var existingSection = _myInfoMateDbContext.Sections.OfType().Include(sq => sq.QuizQuestions).ThenInclude(qq => qq.Resource).FirstOrDefault(sq => sq.Id == sectionId); if (existingSection == null) throw new KeyNotFoundException("Section quiz does not exist"); // TODO verification ? QuizQuestion quizQuestion = new QuizQuestion(); quizQuestion.Label = questionDTO.label; quizQuestion.Responses = questionDTO.responses; quizQuestion.ResourceId = questionDTO.imageBackgroundResourceId; quizQuestion.Order = questionDTO.order; existingSection.QuizQuestions.Add(quizQuestion); _myInfoMateDbContext.SaveChanges(); return new OkObjectResult(quizQuestion); } catch (ArgumentNullException ex) { return new BadRequestObjectResult(ex.Message) { }; } catch (InvalidOperationException ex) { return new ConflictObjectResult(ex.Message) { }; } catch (Exception ex) { return new ObjectResult(ex.Message) { StatusCode = 500 }; } } /// /// Update a quiz question /// /// QuizQuestion to update [ProducesResponseType(typeof(QuestionDTO), 200)] [ProducesResponseType(typeof(string), 400)] [ProducesResponseType(typeof(string), 404)] [ProducesResponseType(typeof(string), 500)] [HttpPut] public ObjectResult Update([FromBody] QuestionDTO questionDTO) { try { if (questionDTO == null) throw new ArgumentNullException("Question param is null"); var existingQuestion = _myInfoMateDbContext.QuizQuestions.FirstOrDefault(qq => qq.Id == questionDTO.id); if (existingQuestion == null) throw new KeyNotFoundException("Question quiz does not exist"); existingQuestion.Label = questionDTO.label; existingQuestion.Responses = questionDTO.responses; existingQuestion.Order = questionDTO.order; existingQuestion.ResourceId = questionDTO.imageBackgroundResourceId; _myInfoMateDbContext.SaveChanges(); return new OkObjectResult(questionDTO); } catch (ArgumentNullException ex) { return new BadRequestObjectResult(ex.Message) { }; } catch (KeyNotFoundException ex) { return new NotFoundObjectResult(ex.Message) { }; } catch (Exception ex) { return new ObjectResult(ex.Message) { StatusCode = 500 }; } } /// /// Update sections order /// /// New sections order /*[ProducesResponseType(typeof(string), 200)] [ProducesResponseType(typeof(string), 400)] [ProducesResponseType(typeof(string), 404)] [ProducesResponseType(typeof(string), 500)] [HttpPut("order")] public ObjectResult UpdateOrder([FromBody] List updatedSectionsOrder) { // TODO REWRITE LOGIC.. try { if (updatedSectionsOrder == null) throw new ArgumentNullException("Sections param is null"); foreach (var section in updatedSectionsOrder) { var sectionDB = _myInfoMateDbContext.Sections.FirstOrDefault(s => s.Id == section.id); if (sectionDB == null) throw new KeyNotFoundException($"Section {section.label} with id {section.id} does not exist"); } foreach (var updatedSection in updatedSectionsOrder) { var section = _myInfoMateDbContext.Sections.FirstOrDefault(s => s.Id == updatedSection.id); //OldSection section = _sectionService.GetById(updatedSection.id); section.Order = updatedSection.order.GetValueOrDefault(); _myInfoMateDbContext.SaveChanges(); //_sectionService.Update(section.Id, section); } if (updatedSectionsOrder.Count > 0) { MqttClientService.PublishMessage($"config/{updatedSectionsOrder[0].configurationId}", JsonConvert.SerializeObject(new PlayerMessageDTO() { configChanged = true })); } return new ObjectResult("Sections order has been successfully modified") { StatusCode = 200 }; } catch (ArgumentNullException ex) { return new BadRequestObjectResult(ex.Message) { }; } catch (KeyNotFoundException ex) { return new NotFoundObjectResult(ex.Message) { }; } catch (Exception ex) { return new ObjectResult(ex.Message) { StatusCode = 500 }; } }*/ /// /// Delete a quiz question /// /// Id of quizQuestion to delete [ProducesResponseType(typeof(string), 202)] [ProducesResponseType(typeof(string), 404)] [ProducesResponseType(typeof(string), 500)] [HttpDelete("questions/delete/{quizQuestionId}")] public ObjectResult Delete(int quizQuestionId) { try { var quizQuestion = _myInfoMateDbContext.QuizQuestions.FirstOrDefault(qq => qq.Id == quizQuestionId); if (quizQuestion == null) throw new KeyNotFoundException("QuizQuestion does not exist"); _myInfoMateDbContext.Remove(quizQuestion); _myInfoMateDbContext.SaveChanges(); return new ObjectResult("The quiz question has been deleted") { StatusCode = 202 }; } catch (ArgumentNullException ex) { return new BadRequestObjectResult(ex.Message) { }; } catch (KeyNotFoundException ex) { return new NotFoundObjectResult(ex.Message) { }; } catch (Exception ex) { return new ObjectResult(ex.Message) { StatusCode = 500 }; } } } }