using System.Numerics;
using Managing.Core;
using Nethereum.Contracts.Standards.ERC20;
using Nethereum.Contracts.Standards.ERC20.ContractDefinition;
using Nethereum.Hex.HexTypes;
using Nethereum.Util;
using Nethereum.Web3;

namespace Managing.Infrastructure.Evm;

public static class EvmBase
{
    public static async Task<bool> ApproveToken(Web3 web3, string publicAddress, string contractAddress, string spender,
        BigInteger amount = default)
    {
        var input = new ApproveFunction
        {
            Spender = spender,
            Value = UnitConversion.Convert.ToWei(amount),
            FromAddress = publicAddress
        };
        var txHandler = web3.Eth
            .GetContractTransactionHandler<ApproveFunction>();

        var result = await txHandler.SendRequestAndWaitForReceiptAsync(contractAddress, input);
        return result.Status == new HexBigInteger(1);
    }

    public static async Task<BigInteger> GetAllowance(Web3 web3, string publicAddress, string contractAddress)
    {
        var input = new AllowanceFunction
        {
            Owner = publicAddress,
            Spender = contractAddress
        };

        var contract = new ERC20ContractService(web3.Eth, contractAddress);
        var allowance = await contract.AllowanceQueryAsync(input);
        return allowance;
    }

    public static async Task<DateTime> GetBlockDate(Web3 web3, HexBigInteger blockNumber)
    {
        var block = await web3.Eth.Blocks.GetBlockWithTransactionsByNumber.SendRequestAsync(blockNumber);
        var date = DateHelpers.GetFromUnixTimestamp((int)block.Timestamp.Value);
        return date;
    }

    public static async Task<BigInteger> GetGasPrice(Web3 web3)
    {
        var gasPrice = await web3.Eth.GasPrice.SendRequestAsync();
        return gasPrice.Value;
    }
}