using ProjectLibrary.Entities;
using ProjectLibrary.Repositories;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Npgsql;
using Dapper;
using System;
using System.Collections.Generic;
using System.Linq;
using ProjectLibrary.Entites;
using ProjectLibrary.Repositores;

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

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

        // Создание новой записи о продлении билета
        public void CreateTicketExtension(TicketExtensions ticketExtension)
        {
            _logger.LogInformation("Добавление нового продления билета для читателя с ID={ReaderID}", ticketExtension.ReaderID);
            _logger.LogDebug("Данные продления: {json}", JsonConvert.SerializeObject(ticketExtension));
            try
            {
                using var connection = new NpgsqlConnection(_connectionString.ConnectionString);

                var queryInsert = @"
                    INSERT INTO Ticket_Extensions (ReaderID, LastUpdateDate, NextUpdateDate)
                    VALUES (@ReaderID, @LastUpdateDate, @NextUpdateDate)";
                connection.Execute(queryInsert, ticketExtension);

                _logger.LogInformation("Продление билета успешно добавлено для читателя с ID={ReaderID}", ticketExtension.ReaderID);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Ошибка при добавлении продления билета");
                throw;
            }
        }

        // Обновление информации о продлении билета
        public void UpdateTicketExtension(TicketExtensions ticketExtension)
        {
            _logger.LogInformation("Редактирование продления билета для читателя с ID={ReaderID}", ticketExtension.ReaderID);
            _logger.LogDebug("Данные продления: {json}", JsonConvert.SerializeObject(ticketExtension));
            try
            {
                using var connection = new NpgsqlConnection(_connectionString.ConnectionString);

                var queryUpdate = @"
                    UPDATE Ticket_Extensions
                    SET LastUpdateDate = @LastUpdateDate, NextUpdateDate = @NextUpdateDate
                    WHERE ReaderID = @ReaderID";
                var affectedRows = connection.Execute(queryUpdate, ticketExtension);

                if (affectedRows > 0)
                {
                    _logger.LogInformation("Продление билета успешно обновлено для читателя с ID={ReaderID}", ticketExtension.ReaderID);
                }
                else
                {
                    _logger.LogWarning("Продление билета для читателя с ID={ReaderID} не найдено для обновления", ticketExtension.ReaderID);
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Ошибка при редактировании продления билета");
                throw;
            }
        }

        // Получение продления билета по ID читателя
        public TicketExtensions ReadTicketExtensionById(int readerId)
        {
            _logger.LogInformation("Получение продления билета для читателя с ID={readerId}", readerId);
            try
            {
                using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
                var querySelect = "SELECT * FROM Ticket_Extensions WHERE ReaderID = @readerId";
                var ticketExtension = connection.QueryFirstOrDefault<TicketExtensions>(querySelect, new { readerId });

                if (ticketExtension != null)
                {
                    _logger.LogDebug("Найдено продление билета: {json}", JsonConvert.SerializeObject(ticketExtension));
                }
                else
                {
                    _logger.LogWarning("Продление билета для читателя с ID={readerId} не найдено", readerId);
                }

                return ticketExtension;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Ошибка при получении продления билета с ID={readerId}", readerId);
                throw;
            }
        }

        // Получение всех продлений билетов
        public List<TicketExtensions> ReadTicketExtensions()
        {
            _logger.LogInformation("Получение всех продлений билетов");
            try
            {
                using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
                var querySelect = @"SELECT te.*, r.Name as ReaderName
                                    FROM Ticket_Extensions te
                                    INNER JOIN Reader r ON r.Id = te.ReaderId";
                var ticketExtensions = connection.Query<TicketExtensions>(querySelect).ToList();

                _logger.LogDebug("Полученные продления билетов: {json}", JsonConvert.SerializeObject(ticketExtensions));
                return ticketExtensions;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Ошибка при получении списка продлений билетов");
                throw;
            }
        }
    }
}