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

public class ReceptionRepository : IReceptionRepository
{
    private readonly IConnectionString _connectionString;
    private readonly ILogger<ReceptionRepository> _logger;

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

    public void CreateReception(Reception reception)
    {
        _logger.LogInformation("Добавление объекта");
        _logger.LogDebug("Объект: {json}",
        JsonConvert.SerializeObject(reception));
        try
        {
            using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
            connection.Open();
            using var transaction = connection.BeginTransaction();
            var queryInsert = @"
                INSERT INTO Receptions (PatientId, DoctorId, DiagnosisId, ReceptionDate, NumTicket)
                VALUES (@PatientId, @DoctorId, @DiagnosisId, @ReceptionDate, @NumTicket);
                SELECT MAX(Id) FROM Receptions";
            var receptionId = connection.QueryFirst<int>(queryInsert, reception, transaction);
            var querySubInsert = @"
                INSERT INTO MedicamentReceptions (ReceptionId, MedicamentId, Dosage)
                VALUES (@ReceptionId,@MedicamentId, @Dosage)";
            foreach (var elem in reception.MedicamentReceptions)
            {
                connection.Execute(querySubInsert, new
                {
                    receptionId,
                    elem.MedicamentId,
                    elem.Dosage
                }, transaction);
            }
            transaction.Commit();
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Ошибка при добавлении объекта");
            throw;
        }
    }

    public void DeleteReception(int id)
    {
        _logger.LogInformation("Удаление объекта");
        _logger.LogDebug("Объект: {id}", id);
        try
        {
            using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
            connection.Open();
            using var transaction = connection.BeginTransaction();
            var queryDelete = @"
                DELETE FROM MedicamentReceptions
                WHERE ReceptionId = @id";

            var queryDeleteReceptions = @"
                DELETE FROM Receptions
                WHERE Id=@id";
            connection.Execute(queryDelete, new { id });
            connection.Execute(queryDeleteReceptions, new { id });
            transaction.Commit();
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Ошибка при удалении объекта");
            throw;
        }
    }

    public IEnumerable<Reception> ReadReceptions(DateTime? dateFrom = null, DateTime? dateTo = null, int? patientId = null, int? diagnosisId = null, int? doctorId = null)
    {
        _logger.LogInformation("Получение всех объектов");
        try
        {
            using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
            var querySelect = @"SELECT * FROM Receptions";
            var receptions =
            connection.Query<Reception>(querySelect);
            _logger.LogDebug("Полученные объекты: {json}",
            JsonConvert.SerializeObject(receptions));
            return receptions;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Ошибка при чтении объектов");
            throw;
        }
    }
}
