using adas_core.Application.Exceptions;
using adas_core.Application.Services.Interfaces;
using adas_core.Authentication.Attributes;
using adas_core.Authentication.Interfaces;
using adas_core.Domain.Enums;
using adas_core.Domain.Models.Masters;
using Microsoft.AspNetCore.Mvc;

namespace adas_core.Controllers;

//gpt generate xml docummentation including summary, params, return, exceptions and without remarks
/// <summary>
/// Provides API endpoints for managing box-related operations, including units, patients, and insulation lists.
/// </summary>
[Route("Box")]
[ApiController]
public class BoxController : ControllerBase
{
    private readonly IUnitService _unitService;
    private readonly IPatientService _patientService;
    private readonly IMasterListService<InsulationList> _isulationListService;
    private readonly IPointOfCareService _pointOfCareService;
    private readonly IUserService _userService;

    /// <summary>
    /// Initializes a new instance of the <see cref="BoxController"/> class.
    /// </summary>
    /// <param name="unitService">The service used to manage unit-related operations.</param>
    /// <param name="patientService">The service used to manage patient-related operations.</param>
    /// <param name="isulationListService">The master list service used to manage insulation list operations.</param>
    /// <param name="pointOfCareService">The service used to manage point of care operations.</param>
    /// <param name="userService">The service used to manage user-related operations.</param>
    /// <exception cref="ArgumentNullException">Thrown when any of the provided service dependencies is <c>null</c>.</exception>
    public BoxController(IUnitService unitService, IPatientService patientService, IMasterListService<InsulationList> isulationListService, IPointOfCareService pointOfCareService, IUserService userService)
    {
        _unitService = unitService;
        _patientService = patientService;
        _isulationListService = isulationListService;
        _pointOfCareService = pointOfCareService;
        _userService = userService;
    }

    /// <summary>
    /// Switches the data for a given box number based on the specified action type.
    /// For the "Isolation" action, it randomly selects an option from the unit's insulation list and updates the patient's master list with the new option; the "Mobility" action is not yet implemented.
    /// </summary>
    /// <param name="boxNumber">The box number used to locate the associated unit and point of care.</param>
    /// <param name="elementSwitjAction">The action that determines which observation list to switch (e.g., "Isolation", "Mobility").</param>
    /// <returns>An <see cref="IActionResult"/> indicating the result of the operation.</returns>
    /// <exception cref="UnauthorizedException">Thrown when the current user identity name is not available in the HTTP context.</exception>
    [HttpGet("{boxNumber}/{elementSwitjAction}/switch-data")]
    [AuthorizeRoles(PermissionEnum.RolesType.AuthSome)]
    public async Task<IActionResult> SwitchData(string boxNumber, string elementSwitjAction)
    {
        // Necesito buscar el por el boxNumber la unidad a la que pertenece 
        // Encontrar la lista que actua sobre la observacion que quiero cambiar en base al action
        // Enviar un valor aleatorio diferente del que este en uso
        var userNameContext = HttpContext.User.Identity?.Name ??
                              throw new UnauthorizedException(HttpEnum.ErrorMessage.UnauthorizedNoPermission);
        var user = await _userService.GetUserByUserName(userNameContext);
        var unit = await _unitService.FindByUnitNameOrPocName(null, boxNumber);
        switch (elementSwitjAction)
        {
            case "Isolation":
                var list = await _isulationListService.GetMasterListById(unit!.InsulationListId!.Value, null);
                var option = list!.Options[Random.Shared.Next(list.Options.Count)];
                var poc = await _pointOfCareService.FindByBedAndUnitId(boxNumber, unit.Id);
                var data = await _pointOfCareService.GetInfo(poc!.Id, null, true);
                var options = new List<OptionList>
                    {
                        new()
                        {
                            Id = option.Id,
                            Name = option.Name,
                            Color = option.Color,
                            BgColor = option.BgColor,
                        }
                    };
                await _patientService.UpdatePatientMasterList(data!.Patient!.Id, MasterListType.InsulationList, options, user, options);


                break;
            case "Mobility":
                break;
        }
        return Ok();
    }
}