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

namespace LDBproject.Repositories.Implementations;

public class UpdateR : IUpdateRep
{
    private readonly IConnectionString _connectionString;
    private readonly ILogger<UpdateR> _logger;

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

    public UpdateC GetUpdateByID(int id)
    {
        _logger.LogInformation("< Getting UPDATE by id >");
        _logger.LogDebug("Object ID: {id}", id);
        try
        {
            using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
            var querySelect = @"SELECT * FROM Updates WHERE ID = @ID";
            return connection.QueryFirstOrDefault<UpdateC>(querySelect, new { ID = id });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "< Error while getting UPDATE by id >");
            throw;
        }
    }

    public void AddUpdate(UpdateC update)
    {
        _logger.LogInformation("< New card UPDATE added >");
        _logger.LogDebug("Object: {json}", JsonConvert.SerializeObject(update));
        try
        {
            using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
            var queryInsert = @"INSERT INTO Updates (CardID, LibrarianID, LastUpdate, UpdBoundary, Note)
                    VALUES (@CardID, @LibrarianID, @LastUpdate, @UpdBoundary, @Note)";
            connection.Execute(queryInsert, update);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "< Error while adding card UPDATE >");
            throw;
        }
    }

    public void RemoveUpd(int Id)
    {
        _logger.LogInformation("< Deleting card UPDATE by id >");
        _logger.LogDebug("Object ID: {id}", Id);

        try
        {
            using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
            var queryDelete = @"DELETE FROM Updates WHERE ID = @ID";
            connection.Execute(queryDelete, new { ID = Id });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "< Error while deleting card UPDATE >");
            throw;
        }
    }

    public IEnumerable<UpdateC> GetUpdateList()
    {
        _logger.LogInformation("< Getting all UPDATES >");
        try
        {
            using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
            var querySelectAll = @"SELECT * FROM Updates";
            var upds = connection.Query<UpdateC>(querySelectAll);
            _logger.LogDebug("Aimed objects: {json}", JsonConvert.SerializeObject(upds));
            return upds;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "< Error while getting all UPDATES >");
            throw;
        }
    }
}