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.MongoModels;
using adas_core.Logging;
using Microsoft.AspNetCore.Mvc;
using MongoDB.Bson;

namespace adas_core.Controllers;

[Route("discharges")]
[ApiController]
public class DischargeController : ControllerBase
{
    private readonly IDischargeService _dischargeService;
    private readonly IPatientService _patientService;

    public DischargeController(IDischargeService dischargeService, IPatientService patientService)
    {
        LogExecutionContext.TrySetTraceIdentifier(Guid.NewGuid().ToString(), true);

        _dischargeService = dischargeService;
        _patientService = patientService;
    }

    [HttpGet]
    [AuthorizeRoles(PermissionEnum.RolesType.AuthSome)]
    [PermissionAuthorize("Source", "DisplayId")]
    public async Task<IActionResult> GetAllDischarges()
    {
        var discharges = await _dischargeService.GetDischargesAsync();
        return Ok(discharges);
    }

    [HttpGet("{id}")]
    [AuthorizeRoles(PermissionEnum.RolesType.AuthSome)]
    [PermissionAuthorize("Source", "DisplayId")]
    public async Task<IActionResult> GetDischargebyId(string id)
    {
        if (!ObjectId.TryParse(id, out var dischargeId))
            throw new BadRequestException(HttpEnum.ErrorMessage.BadRequestInvalidFormat);
        var discharge = await _dischargeService.GetDischargeByIdAsync(dischargeId);
        return Ok(discharge);
    }

    [HttpPost("patient")]
    [AuthorizeRoles(PermissionEnum.RolesType.AuthSome)]
    [PermissionAuthorize("Source", "DisplayId")]
    public async Task<IActionResult> DischargePatient([FromBody] Discharge discharge)
    {
        if (discharge == null) throw new BadRequestException(HttpEnum.ErrorMessage.BadRequestMissingParameters);
        var patient = await _patientService.FindById(discharge.PatientId);
        discharge.Patient = patient;

        await _dischargeService.InsertDischarge(discharge);
        return Ok();
    }

    [HttpPut]
    [AuthorizeRoles(PermissionEnum.RolesType.AuthSome)]
    [PermissionAuthorize("Source", "DisplayId")]
    public async Task<IActionResult> UpdateDischarge([FromBody] Discharge discharge)
    {
        if (discharge == null) throw new BadRequestException(HttpEnum.ErrorMessage.BadRequestMissingParameters);
        var c = await _dischargeService.GetDischargeByIdAsync(discharge.Id);
        if (discharge.UnitId == null && c?.UnitId != null) discharge.UnitId = c.UnitId;
        await _dischargeService.UpdateDischargeAsync(discharge);

        return Ok();
    }

    [HttpPost]
    [AuthorizeRoles(PermissionEnum.RolesType.AuthSome)]
    [PermissionAuthorize("Source", "DisplayId")]
    public async Task<IActionResult> InsertDischarge([FromBody] Discharge discharge)
    {
        if (discharge == null) throw new BadRequestException(HttpEnum.ErrorMessage.BadRequestMissingParameters);
        var dis = await _dischargeService.InsertDischarge(discharge);

        return Ok(dis);
    }

    [HttpDelete("{id}")]
    [AuthorizeRoles(PermissionEnum.RolesType.AuthSome)]
    [PermissionAuthorize("Source", "DisplayId")]
    public async Task<IActionResult> DeleteDischargeById(string id)
    {
        if (!ObjectId.TryParse(id, out var dischargeId))
            throw new BadRequestException(HttpEnum.ErrorMessage.BadRequestInvalidFormat);
        var discharge = await _dischargeService.GetDischargeByIdAsync(dischargeId);
        var patient = await _patientService.FindById(discharge!.PatientId);
        discharge.Patient = patient;
        if ("Altable".Equals(patient!.Altable?.OptionType))
        {
            await _dischargeService.DeleteDischargeAsync(discharge);
            return Ok();
        }

        throw new ConflictException(HttpEnum.ErrorMessage.ConflictOperationIncompleted);
    }
}