using adas_core.Application.Exceptions;
using adas_core.Application.Services.Interfaces;
using adas_core.Authentication.Attributes;
using adas_core.Domain.Enums;
using adas_core.Domain.Models;
using adas_core.Domain.Models.DTO;
using adas_core.Domain.Models.Filter;
using adas_core.Domain.Models.MongoModels;
using adas_core.Logging;
using Microsoft.AspNetCore.Mvc;
using MongoDB.Bson;

namespace adas_core.Controllers;

[Route("pumps")]
public class PumpController : ControllerBase
{
    private readonly IHistoricalConfigChangesService _historicalConfigChangesService;
    private readonly IPumpService _pumpService;


    public PumpController(IPumpService pumpService, IHistoricalConfigChangesService historicalConfigChangesService)
    {
        LogExecutionContext.TrySetTraceIdentifier(Guid.NewGuid().ToString(), true);

        _pumpService = pumpService;
        _historicalConfigChangesService = historicalConfigChangesService;
    }

    [HttpPost("request")]
    [AuthorizeRoles(PermissionEnum.RolesType.AuthSome)]
    [PermissionAuthorize("Source", "DisplayId")]
    public IActionResult ProcessRequest([FromBody] PumpDto pumpDto)
    {
        var request = new ApiRequest
        {
            TraceId = Guid.NewGuid().ToString(),
            Type = "AlarisPump",
            PatientNumber = pumpDto.PatientNumber,
            Location = pumpDto.Location,
            PumpObservations = pumpDto.PumpObservations,
            MessageTime = pumpDto.MessageTime,
            WaitResult = pumpDto.WaitResult
        };


        if (request.WaitResult) _pumpService.SaveRequest(request);

        else _pumpService.SaveRequestAsync(request);
        return Ok();
    }

    [HttpGet]
    [AuthorizeRoles(PermissionEnum.RolesType.AuthSome)]
    [PermissionAuthorize("Source", "DisplayId")]
    public async Task<IActionResult> GetAllPumpConfig()
    {
        return Ok(await _pumpService.GetAllPumpConfig());
    }

    [HttpGet("{id}")]
    [AuthorizeRoles(PermissionEnum.RolesType.AuthSome)]
    [PermissionAuthorize("Source", "DisplayId")]
    public async Task<IActionResult> GetPumpConfigById(string id)
    {
        return Ok(await _pumpService.GetPumpConfigsById(id));
    }

    [HttpPut]
    [AuthorizeRoles(PermissionEnum.RolesType.AuthSome)]
    [PermissionAuthorize("Source", "DisplayId")]
    public async Task<IActionResult> UpdatePumpConfig([FromBody] ConfigPumps configPumps)
    {
        if (configPumps == null) throw new BadRequestException(HttpEnum.ErrorMessage.BadRequestMissingParameters);
        var oldConfig = await _pumpService.GetPumpConfigsById(configPumps.Id);

        var result = await _pumpService.UpdatePumpConfig(configPumps);
        await LogHistoricalConfigChanged(result, oldConfig);
        return Ok(result);
    }

    [HttpPost]
    [AuthorizeRoles(PermissionEnum.RolesType.AuthSome)]
    [PermissionAuthorize("Source", "DisplayId")]
    public async Task<IActionResult> InsertPumpConfig([FromBody] ConfigPumps config)
    {
        if (config == null) throw new BadRequestException(HttpEnum.ErrorMessage.BadRequestMissingParameters);
        var result = await _pumpService.InsertPumpConfig(config);
        await LogHistoricalConfigChanged(config, null);
        return Ok(result);
    }

    [HttpDelete("{id}")]
    [AuthorizeRoles(PermissionEnum.RolesType.AuthSome)]
    [PermissionAuthorize("Source", "DisplayId")]
    public async Task<IActionResult> DeletePumpConfig(string id)
    {
        var config = await _pumpService.GetPumpConfigsById(id);
        var result = await _pumpService.DeletePumpConfig(config!);

        await LogHistoricalConfigChanged(null, config);
        return Ok(result);
    }

    [HttpPost("paginated")]
    [AuthorizeRoles(PermissionEnum.RolesType.AuthSome)]
    [PermissionAuthorize("Source", "DisplayId")]
    public async Task<IActionResult> PaginatedPump([FromBody] PaginationFilter config)
    {
        if (config == null) throw new BadRequestException(HttpEnum.ErrorMessage.BadRequestMissingParameters);
        var result = await _pumpService.GetPaginatedPump(config);
        return Ok(result);
    }


    private async Task LogHistoricalConfigChanged(ConfigPumps? newConfigO, ConfigPumps? oldConfig)
    {
        var user = HttpContext.User.Identity?.Name ?? HttpContext.Connection.RemoteIpAddress?.ToString();
        await _historicalConfigChangesService.LogConfigChanged(user!, DisplayConfigEnums.ConfigTypes.PumpCfg,
            newConfigO?.ToJson() ?? string.Empty, oldConfig?.ToJson() ?? string.Empty);
    }
}