using Application.Endpoints;
using Application.Endpoints.MedicalHistories.FileManagement;
using Application.Endpoints.MedicalHistories.ManageAuthorization;
using Application.Services.Database;
using Application.Services.Database.MongoDB;
using Microsoft.AspNetCore.Mvc;

namespace API.Controllers;

[ApiController]
[Route("api/[controller]")]
public class MedicalHistoryController : ControllerBase
{
    private readonly IMedicalHistoryRepository _medicalHistoryRepository;
    private readonly IMedicalHistoryMongoDbService _medicalHistoryMongoDbService;
    private readonly IPatientRepository _patientRepository;
    private readonly IDoctorRepository _doctorRepository;

    public MedicalHistoryController(IMedicalHistoryRepository medicalHistoryRepository,
        IPatientRepository patientRepository, IMedicalHistoryMongoDbService mongoDbService,
        IDoctorRepository doctorRepository)
    {
        _medicalHistoryRepository = medicalHistoryRepository;
        _patientRepository = patientRepository;
        _medicalHistoryMongoDbService = mongoDbService;
        _doctorRepository = doctorRepository;
    }

    [HttpGet("{id}")]
    public async Task<ActionResult<BaseResponse>> GetAsync(Guid id)
    {
        var handler = new MedicalHistoryFileManagementHandler(_medicalHistoryRepository, _patientRepository,
            _medicalHistoryMongoDbService);
        var response = await handler.HandleGet(id);
        return StatusCode(response.StatusCode, response);
    }

    [HttpGet]
    public async Task<ActionResult<BaseResponse>> GetAllDoctors()
    {
        var handler = new MedicalHistoryFileManagementHandler(_medicalHistoryRepository, _patientRepository,
            _medicalHistoryMongoDbService);
        var response = await handler.HandleGetAll();
        return StatusCode(response.StatusCode, response);
    }

    [HttpPost]
    public async Task<ActionResult<BaseResponse>> PostAsync(MedicalHistoryCreateDto medicalHistoryCreateDto)
    {
        var handler = new MedicalHistoryFileManagementHandler(_medicalHistoryRepository, _patientRepository,
            _medicalHistoryMongoDbService);
        var response = await handler.HandleCreate(medicalHistoryCreateDto);
        return StatusCode(response.StatusCode, response);
    }

    [HttpPut]
    public async Task<ActionResult<BaseResponse>> UpdateAsync(MedicalHistoryUpdateDto medicalHistoryUpdateDto)
    {
        var handler = new MedicalHistoryFileManagementHandler(_medicalHistoryRepository, _patientRepository,
            _medicalHistoryMongoDbService);
        var response = await handler.HandleUpdate(medicalHistoryUpdateDto).ConfigureAwait(false);
        return StatusCode(response.StatusCode, response);
    }

    [HttpDelete("{id}")]
    public async Task<ActionResult<BaseResponse>> DeleteAsync(Guid id)
    {
        var handler = new MedicalHistoryFileManagementHandler(_medicalHistoryRepository, _patientRepository,
            _medicalHistoryMongoDbService);
        var response = await handler.HandleDelete(id);
        return StatusCode(response.StatusCode, response);
    }


    [HttpPut("grant_access")]
    public async Task<ActionResult<BaseResponse>> GrantAccessToMedicalHistory(
        MedicalHistoryManageAuthorizationDoctorDto infoDto)
    {
        var handler = new MedicalHistoryManageAuthorizationHandler(_medicalHistoryRepository,
            _medicalHistoryMongoDbService, _doctorRepository);
        var response = await handler.HandleGrantDoctorAccess(infoDto);
        return StatusCode(response.StatusCode, response);
    }
    
    [HttpPut("revoke_access")]
    public async Task<ActionResult<BaseResponse>> RevokeAccessToMedicalHistory(
        MedicalHistoryManageAuthorizationDoctorDto infoDto)
    {
        var handler = new MedicalHistoryManageAuthorizationHandler(_medicalHistoryRepository,
            _medicalHistoryMongoDbService, _doctorRepository);
        var response = await handler.HandleRevokeDoctorAccess(infoDto);
        return StatusCode(response.StatusCode, response);
    }
}