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

namespace LDBproject.Repositories.Implementations;

internal class LibrarianR : ILibrarianRep
{
    private readonly IConnectionString _connectionString;
    private readonly ILogger<LibrarianR> _logger;

    public LibrarianR(IConnectionString connectionString, ILogger<LibrarianR> logger)
    {
        _connectionString = connectionString ?? throw new ArgumentNullException(nameof(connectionString));
        _logger = logger ?? throw new ArgumentNullException(nameof(logger));
    }

    public LibrarianCard GetCardByID(int id)
    {
        _logger.LogInformation("< Getting EMPLOYEE by id >");
        _logger.LogDebug("Object ID: {id}", id);
        try
        {
            using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
            var querySelect = @"SELECT * FROM LibrarianCards WHERE CardID = @CardID"; // Assumes you have a CardID column
            return connection.QueryFirstOrDefault<LibrarianCard>(querySelect, new { CardID = id });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "< Error while getting EMPLOYEE by ID >");
            throw;
        }
    }

    public void AddCard(LibrarianCard card)
    {
        _logger.LogInformation("< New EMPLOYEE Added >");
        _logger.LogDebug("Object: {json}", JsonConvert.SerializeObject(card));
        try
        {
            using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
            connection.Open();
            var queryInsert = @"INSERT INTO LibrarianCards (FIO, GenreMask) VALUES (@FIO, @GenreMask)";
            connection.Execute(queryInsert, card);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "< Error while adding EMPLOYEE >");
            throw;
        }
    }

    public void ChangeCardInfo(LibrarianCard card)
    {
        _logger.LogInformation("< EMPLOYEE Info Updated >");
        _logger.LogDebug("Object: {json}", JsonConvert.SerializeObject(card));
        try
        {
            using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
            connection.Open();
            var queryUpdate = @"UPDATE LibrarianCards SET FIO = @FIO, GenreMask = @GenreMask WHERE CardID = @CardID"; // Assumes you have a CardID column
            connection.Execute(queryUpdate, card);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "< Error while updating EMPLOYEE info >");
            throw;
        }
    }

    public void DeleteCard(int id)
    {
        _logger.LogInformation("< Removing CARD >");
        _logger.LogDebug("Object ID: {id}", id);
        try
        {
            using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
            var queryDelete = @"DELETE FROM LibrarianCards WHERE CardID = @CardID"; // Assumes you have a CardID column
            connection.Execute(queryDelete, new { CardID = id });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "< Error while deleting EMPLOYEE >");
            throw;
        }
    }

    public IEnumerable<LibrarianCard> GetCards()
    {
        _logger.LogInformation("< Getting all EMPLOYEE >");
        try
        {
            using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
            connection.Open();
            var querySelectAll = "SELECT * FROM LibrarianCards";
            var cards = connection.Query<LibrarianCard>(querySelectAll);
            _logger.LogDebug("Aimed objects: {json}", JsonConvert.SerializeObject(cards));
            return cards;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "< Error while getting EMPLOYEE >");
            throw;
        }
    }
}