using Dapper;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Npgsql;
using ProjectItCompany.Entities;
using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Unity;

namespace ProjectItCompany.Repositories.Implementations;

public class ContractRepository : IContractRepository
{
    private readonly IConnectionString _connectionString;
    private readonly ILogger<ContractRepository> _logger;

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

    public void CreateContract(Entities.Contract contract)
    {
        _logger.LogInformation("Добавление объекта");
        _logger.LogDebug("Объект: {json}", JsonConvert.SerializeObject(contract));
        try
        {
            using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
            connection.Open();
            using var transaction = connection.BeginTransaction();
            var queryInsert = @"INSERT INTO contract (Date, ProjectId)
                                VALUES (@Date, @ProjectId);
                                SELECT MAX(Id) FROM Contracts";
            var feedReplenishmentId = connection.QueryFirst<int>(queryInsert, contract, transaction);
            var querySubInsert = @"INSERT INTO customerOnProject (ContractId, CostomerId, Description)
                                    VALUES (@ContractId,@CostomerId, @Description)";
            foreach (var elem in contract.CustomerId)
            {
                connection.Execute(querySubInsert, new
                {
                    elem.ContractId,
                    elem.Description,
                    elem.CustomerId
                }, transaction);
            }
            transaction.Commit();
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Ошибка при добавлении объекта");
            throw;
        }
    }

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

    public IEnumerable<Entities.Contract> ReadContract(DateTime? dateForm = null, DateTime? dateTo = null, decimal? typeProject = null, int? customerId = null)
    {
        _logger.LogInformation("Получение всех объектов");
        try
        {
            using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
            var querySelect = @"SELECT * FROM contract";
            var contracts = connection.Query<Entities.Contract>(querySelect);
            _logger.LogDebug("Полученные объекты: {json}", JsonConvert.SerializeObject(contracts));
            return contracts;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Ошибка при чтении объектов");
            throw;
        }
    }
}
