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

namespace adas_core.Controllers;

[Route("point-of-cares")]
[ApiController]
public class PointOfCareController(IPointOfCareService pointOfCareService)
    : ControllerBase
{
    /// <summary>
    ///     GetByCodeSysAndCode all PoC list
    /// </summary>
    /// <returns>
    ///     List<Unit />
    /// </returns>
    [HttpGet]
    [AuthorizeRoles(PermissionEnum.RolesType.AuthSome)]
    [PermissionAuthorize("Source", "DisplayId")]
    public async Task<IActionResult> List()
    {
        return Ok(await pointOfCareService.GetAll());
    }

    /// <summary>
    ///     GetByCodeSysAndCode all Viirtual PoC list
    /// </summary>
    /// <returns>
    ///     List<Unit />
    /// </returns>
    [HttpGet("get-all-virtual")]
    [AuthorizeRoles(PermissionEnum.RolesType.AuthSome)]
    public IActionResult VirtualPocList()
    {
        var virtualPocNames = Enum.GetNames(typeof(VirtualPointOfCare)).ToList();
        return Ok(virtualPocNames);
    }

    [HttpPost("paginated")]
    [AuthorizeRoles(PermissionEnum.RolesType.AuthSome)]
    [PermissionAuthorize("Source", "DisplayId")]
    public async Task<IActionResult> GetPaginatedPoCs([FromBody] PaginationFilter request)
    {
        if (request == null) throw new BadRequestException(HttpEnum.ErrorMessage.BadRequestMissingParameters);

        var pocs = await pointOfCareService.GetPaginatedPoCs(request);
        return Ok(pocs);
    }

    [HttpPost]
    [AuthorizeRoles(PermissionEnum.RolesType.AuthSome)]
    [PermissionAuthorize("Source", "DisplayId")]
    public async Task<IActionResult> CreateNewPointOfCare([FromBody] PointOfCare pointOfCare)
    {
        var result = await pointOfCareService.InsertPointOfCare(pointOfCare);
        return Ok(result);
    }


    [HttpPut("{id}/{status}/status")]
    [AuthorizeRoles(PermissionEnum.RolesType.AuthSome)]
    [PermissionAuthorize("Source", "DisplayId")]
    public async Task<IActionResult> SetPointOfCareStatus(string id, string status)
    {
        if (!Enum.TryParse(status, out StatusEnum.PointOfCare pocStatus) || !ObjectId.TryParse(id, out var pocId))
            throw new BadRequestException(HttpEnum.ErrorMessage.BadRequestInvalidFormat);
        await pointOfCareService.SetPointOfCareStatus(pocId, pocStatus);

        return Ok();
    }

    [HttpGet("{id}/unit-id")]
    [AuthorizeRoles(PermissionEnum.RolesType.AuthSome)]
    [PermissionAuthorize("Source", "DisplayId")]
    public async Task<IActionResult> GetAllPoCByUnitId(string id)
    {
        if (!ObjectId.TryParse(id, out var unitId))
            throw new BadRequestException(HttpEnum.ErrorMessage.BadRequestInvalidFormat);

        var result = await pointOfCareService.FindAllByUnitId(unitId);
        return Ok(result?.ToList());
    }

    [HttpGet("{unitId}/unit-id/{status}/status")]
    [AuthorizeRoles(PermissionEnum.RolesType.AuthSome)]
    [PermissionAuthorize("Source", "DisplayId")]
    public async Task<IActionResult> GetPoCByUnitIdAndStatus(string unitId, string status)
    {
        if (!ObjectId.TryParse(unitId, out var unitIdParsed) ||
            !Enum.TryParse(status, out StatusEnum.PointOfCare pocStatus))
            throw new BadRequestException(HttpEnum.ErrorMessage.BadRequestInvalidFormat);

        var result = await pointOfCareService.FindByUnitAndStatus(unitIdParsed, pocStatus);
        return Ok(result);
    }

    [HttpPut]
    [AuthorizeRoles(PermissionEnum.RolesType.AuthSome)]
    [PermissionAuthorize("Source", "DisplayId")]
    public async Task<IActionResult> UpdatePoC([FromBody] PointOfCare poc)
    {
        var result= await pointOfCareService.Update(poc);
        return Ok(result);
    }

    [HttpPut("{id}/config")]
    [AuthorizeRoles(PermissionEnum.RolesType.AuthSome)]
    [PermissionAuthorize("Source", "DisplayId")]
    public async Task<IActionResult> UpdatePoCConfiguration(string id, [FromBody] PointOfCareConfiguration pocConfig)
    {
        if (!ObjectId.TryParse(id, out var pocId))
            throw new BadRequestException(HttpEnum.ErrorMessage.BadRequestInvalidFormat);
        await pointOfCareService.UpdateConfiguration(pocId, pocConfig);
        return Ok();
    }

    [HttpPut("relay")]
    [AuthorizeRoles(PermissionEnum.RolesType.AuthSome)]
    [PermissionAuthorize("Source", "DisplayId")]
    public async Task<IActionResult> UpdatePoCRelay([FromBody] PointOfCare poc)
    {
        await pointOfCareService.UpdateRelayConfig(poc);
        return Ok();
    }

    [HttpPut("{id}/unit")]
    [AuthorizeRoles(PermissionEnum.RolesType.AuthSome)]
    [PermissionAuthorize("Source", "DisplayId")]
    public async Task<IActionResult> UpdatePoCConfiguration([FromBody] Unit unit, string id)
    {
        if (!ObjectId.TryParse(id, out var pocId))
            throw new BadRequestException(HttpEnum.ErrorMessage.BadRequestInvalidFormat);
        await pointOfCareService.UpdateUnit(pocId, unit);
        return Ok();
    }

    [HttpDelete("{id}")]
    [AuthorizeRoles(PermissionEnum.RolesType.AuthSome)]
    [PermissionAuthorize("Source", "DisplayId")]
    public async Task<IActionResult> DeletePoC(string id)
    {
        if (!ObjectId.TryParse(id, out var pocId))
            throw new BadRequestException(HttpEnum.ErrorMessage.BadRequestInvalidFormat);
        await pointOfCareService.Delete(pocId);
        return Ok();
    }
}