using ProjectPatientAccounting.Entities;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Npgsql;
using Dapper;

namespace ProjectPatientAccounting.Repositories.Implementations;
public class PatientDiagnosisRepository : IPatientDiagnosisRepository
{
    private readonly IConnectionString _connectionString;
    private readonly ILogger<PatientDiagnosisRepository> _logger;

    public PatientDiagnosisRepository(IConnectionString connectionString, ILogger<PatientDiagnosisRepository> logger)
    {
        _connectionString = connectionString;
        _logger = logger;
    }

    public void CreateDiagnosis(PatientDiagnosis diagnosis)
    {
        _logger.LogInformation("Добавление объекта");
        _logger.LogDebug("Объект: {json}", JsonConvert.SerializeObject(diagnosis));

        try
        {
            using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
            var queryInsert = @"
            INSERT INTO PatientDiagnosises (Name, DiagnosisCode, PatientDiagnosisStatus)
               VALUES (@Name, @DiagnosisCode, @PatientDiagnosisStatus)";
            connection.Execute(queryInsert, diagnosis);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Ошибка при добавлении объекта");
            throw;
        }
    }

    public void DeleteDiagnosis(int id)
    {
        _logger.LogInformation("Удаление объекта");
        _logger.LogDebug("Объект: {id}", id);
        try
        {
            using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
            var queryDelete = @"
                DELETE FROM PatientDiagnosises
                WHERE Id=@id";
            connection.Execute(queryDelete, new { id });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Ошибка при удалении объекта");
            throw;
        }
    }

    public PatientDiagnosis ReadDiagnosisById(int id)
    {
        _logger.LogInformation("Получение объекта по идентификатору");
        _logger.LogDebug("Объект: {id}", id);
        try
        {
            using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
            var querySelect = @"
                SELECT * FROM PatientDiagnosises
                WHERE Id=@id";
            var diagnosis = connection.QueryFirst<PatientDiagnosis>(querySelect, new { id });
            _logger.LogDebug("Найденный объект: {json}", JsonConvert.SerializeObject(diagnosis));
            return diagnosis;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Ошибка при поиске объекта");
            throw;
        }
    }

    public IEnumerable<PatientDiagnosis> ReadDiagnosises()
    {
        _logger.LogInformation("Получение всех объектов");
        try
        {
            using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
            var querySelect = "SELECT * FROM PatientDiagnosises";
            var diagnosises = connection.Query<PatientDiagnosis>(querySelect);
            _logger.LogDebug("Полученные объекты: {json}",
            JsonConvert.SerializeObject(diagnosises));
            return diagnosises;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Ошибка при чтении объектов");
            throw;
        }
    }

    public void UpdateDiagnosis(PatientDiagnosis diagnosis)
    {
        _logger.LogInformation("Редактирование объекта");
        _logger.LogDebug("Объект: {json}", JsonConvert.SerializeObject(diagnosis));
        try
        {
            using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
            var queryUpdate = @"
                UPDATE PatientDiagnosises
                SET
                Name=@Name,
                DiagnosisCode=@DiagnosisCode,
                PatientDiagnosisStatus=@PatientDiagnosisStatus
                WHERE Id=@Id";
            connection.Execute(queryUpdate, diagnosis);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Ошибка при редактировании объекта");
            throw;
        }
    }
}
