using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Npgsql;
using ProjectLibrary.Entities;
using ProjectLibrary.Entities.Enums;
using ProjectLibrary.Repositories;
using Dapper;
using ProjectLibrary.Repositores;

namespace ProjectLibrary.Repositories.Implementations
{
    public class BookRepository : IBookRepository
    {
        private readonly IConnectionString _connectionString;
        private readonly ILogger<BookRepository> _logger;

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

        // Добавление книги
        public void CreateBook(Book book)
        {
            _logger.LogInformation("Добавление книги");
            _logger.LogDebug("Книга: {json}", JsonConvert.SerializeObject(book));
            try
            {
                using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
                var queryInsert = @"
                    INSERT INTO Book (Author, Name, TypeBookID)
                    VALUES (@Author, @Name, @TypeBookID)";
                connection.Execute(queryInsert, book);
                _logger.LogInformation("Книга успешно добавлена");
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Ошибка при добавлении книги");
                throw;
            }
        }

        // Обновление информации о книге
        public void UpdateBook(Book book)
        {
            _logger.LogInformation("Редактирование книги");
            _logger.LogDebug("Книга: {json}", JsonConvert.SerializeObject(book));
            try
            {
                using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
                var queryUpdate = @"
                    UPDATE Book
                    SET
                        Author = @Author,
                        Name = @Name,
                        TypeBookID = @TypeBookID
                    WHERE ID = @ID";
                connection.Execute(queryUpdate, book);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Ошибка при редактировании книги");
                throw;
            }
        }

        // Удаление книги
        public void DeleteBook(int id)
        {
            _logger.LogInformation("Удаление книги с Id={id}", id);
            try
            {
                using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
                var queryDelete = @"
                    DELETE FROM Book
                    WHERE ID = @id";
                var affectedRows = connection.Execute(queryDelete, new { id });

                if (affectedRows > 0)
                {
                    _logger.LogInformation("Книга с Id={id} успешно удалена", id);
                }
                else
                {
                    _logger.LogWarning("Книга с Id={id} не найдена для удаления", id);
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Ошибка при удалении книги с Id={id}", id);
                throw;
            }
        }

        // Получение книги по ID
        public Book ReadBookById(int id)
        {
            _logger.LogInformation("Получение книги по Id={id}", id);
            try
            {
                using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
                var querySelect = @"
                    SELECT * FROM Book
                    WHERE ID = @id";
                var book = connection.QueryFirstOrDefault<Book>(querySelect, new { id });

                if (book != null)
                {
                    _logger.LogDebug("Найдена книга: {json}", JsonConvert.SerializeObject(book));
                }
                else
                {
                    _logger.LogWarning("Книга с Id={id} не найдена", id);
                }

                return book;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Ошибка при получении книги с Id={id}", id);
                throw;
            }
        }

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