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

namespace RealEstateTransactions.Repositories.Implementations
{
    public class ServicesRepository : IServicesRepository
    {
        private readonly IConnectionString _connectionString;

        private readonly ILogger<ServicesRepository> _logger;

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

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

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

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

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

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