using Application.Services.Database;
using Application.Services.HashingAlgorithms;

namespace Application.Endpoints.Doctors.Profile;

public class DoctorProfileHandler
{
    private readonly IDoctorRepository _database;
    private readonly IHashingAlgorithms _hashingAlgorithms;

    public DoctorProfileHandler(IDoctorRepository database, IHashingAlgorithms hashingAlgorithms)
    {
        _database = database;
        _hashingAlgorithms = hashingAlgorithms;
    }

    public async Task<BaseResponse> HandleGet(Guid id)
    {
        var doctor = await _database.GetByIdAsync(id).ConfigureAwait(false);
        if (doctor != null)
            return new BaseResponse
            {
                StatusCode = HttpStatusCodes.OK,
                Message = $"Retrieved doctor with id: {id}",
                Data = doctor
            };

        return new BaseResponse
        {
            StatusCode = HttpStatusCodes.NotFound,
            Message = $"Doctor with id: {id} not found",
            Data = null
        };
    }

    public async Task<BaseResponse> HandleGetAll()
    {
        var doctors = await _database.GetAllAsync().ConfigureAwait(false);
        if (doctors.Any())
            return new BaseResponse
            {
                StatusCode = HttpStatusCodes.OK,
                Message = "Retrieved doctors",
                Data = doctors.ToList()
            };

        return new BaseResponse
        {
            StatusCode = HttpStatusCodes.NoContent,
            Message = "Doctors not found",
            Data = null
        };
    }

    public async Task<BaseResponse> HandleUpdate(DoctorProfileUpdateDto doctorProfileUpdateDto)
    {
        var validation = new DoctorProfileValidation(_database);
        var validationResult = await validation.ValidateAsync(doctorProfileUpdateDto);

        if (!validationResult.IsValid)
        {
            var firstError = validationResult.Errors.FirstOrDefault();
            var errorCode = int.TryParse(firstError.ErrorCode, out var code) ? code : -1;
            var errorMessage = firstError.ErrorMessage;

            return new BaseResponse
            {
                StatusCode = errorCode,
                Message = errorMessage,
                Data = null
            };
        }

        var doctorToUpdate = await _database.GetByIdAsync(doctorProfileUpdateDto.Id);
        doctorToUpdate.SetEmail(doctorProfileUpdateDto.Email);
        doctorToUpdate.SetPassword(_hashingAlgorithms.SHA256Algorithm(doctorProfileUpdateDto.Password));
        doctorToUpdate.SetName(doctorProfileUpdateDto.Name);
        doctorToUpdate.SetDescription(doctorProfileUpdateDto.Description);

        await _database.UpdateAsync(doctorToUpdate);

        return new BaseResponse
        {
            StatusCode = HttpStatusCodes.NoContent,
            Message = null,
            Data = null
        };
    }

    public async Task<BaseResponse> HandleDelete(Guid id)
    {
        var doctorToDelete = await _database.GetByIdAsync(id);
        if (doctorToDelete == null)
            return new BaseResponse
            {
                StatusCode = HttpStatusCodes.NotFound,
                Message = "Doctor was not found.",
                Data = null
            };

        await _database.DeleteAsync(doctorToDelete);

        return new BaseResponse
        {
            StatusCode = HttpStatusCodes.NoContent,
            Message = null,
            Data = null
        };
    }
}