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

namespace RealEstateTransactions.Repositories.Implementations
{
    public class BuyerRepository : IBuyerRepository
    {
        private readonly IConnectionString _connectionString;

        private readonly ILogger<BuyerRepository> _logger;

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

        public void CreateBuyer(Buyer buyer)
        {
            _logger.LogInformation("Добавление объекта");
            _logger.LogDebug("Объект: {json}", JsonConvert.SerializeObject(buyer));
            try
            {
                using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
                var insertQuery = @"
INSERT INTO Buyer (Full_name, Passport_series, Passport_number)
VALUES (@Full_name, @Passport_series, @Passport_number)";
                connection.Execute(insertQuery, buyer);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Ошибка при добавлении объекта");
                throw;
            }
        }

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

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

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

        public void UpdateBuyer(Buyer buyer)
        {
            _logger.LogInformation("Редактирование объекта");
            _logger.LogDebug("Объект: {json}", JsonConvert.SerializeObject(buyer));
            try
            {
                using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
                var updateQuery = @"
UPDATE Buyer
SET
    Full_name = @Full_name,
    Passport_series = @Passport_series,
    Passport_number = @Passport_number
WHERE Id = @Id";
                connection.Execute(updateQuery, buyer);
            }
            catch (Exception ex)
            {
                _logger.LogDebug(ex, "Ошибка при редактировании объекта");
                throw;
            }
        }
    }
}