using Knoks.Api.Client.Invoker;
using Knoks.Test.Integrations.Api.Tools;
using System.Linq;
using System.Threading.Tasks;
using Xunit;
using static Knoks.Test.Integrations.Api.Tools.ApiMocker;

namespace Knoks.Test.Integrations.Api
{
    public class BackOfficeControllerTest : ApiTestClient
    {
        [Fact(DisplayName = "Add FreeTokensCredit Account Transaction")]
        async Task AddFreeTokensCreditAccountTransaction()
        {
            await ApiClient.AuthorizeApiConsumer();

            var operatorRes = (await ApiClient.InvokeCreateOperator(GetCreateOperatorArgs(true))).Object;

            var createUserArgs = GetCreateUserArgs();
            var user = (await ApiClient.InvokeCreateUser(createUserArgs)).Object;

            await ApiClient.AuthorizeApiUser(createUserArgs.Email, createUserArgs.Password);
            var userAccounts = (await ApiClient.InvokeUserAccounts()).Object;

            Assert.Equal(user.FirstName, userAccounts.User.FirstName);
            Assert.NotEmpty(userAccounts.Accounts);

            var transRes = (await ApiClient.InvokeFreeTokensCreditTransaction(GetAddAccountTransactionArgs(user.UserId, userAccounts.Accounts.FirstOrDefault().AccountId, operatorRes.OperatorId))).Object;

            Assert.NotEqual(0, transRes.TransId);
        }

        [Fact(DisplayName = "Add Deposit Account Transaction")]
        async Task AddDepositAccountTransaction()
        {
            await ApiClient.AuthorizeApiConsumer();

            var operatorRes = (await ApiClient.InvokeCreateOperator(GetCreateOperatorArgs(true))).Object;

            var createUserArgs = GetCreateUserArgs();
            var user = (await ApiClient.InvokeCreateUser(createUserArgs)).Object;

            await ApiClient.AuthorizeApiUser(createUserArgs.Email, createUserArgs.Password);
            var userAccounts = (await ApiClient.InvokeUserAccounts()).Object;

            Assert.Equal(user.FirstName, userAccounts.User.FirstName);
            Assert.NotEmpty(userAccounts.Accounts);

            var transRes = (await ApiClient.InvokeDeposit(GetAddAccountTransactionArgs(user.UserId, userAccounts.Accounts.FirstOrDefault().AccountId, operatorRes.OperatorId))).Object;

            Assert.NotEqual(0, transRes.TransId);
        }
        
        [Fact(DisplayName = "Add Withdraw Account Transaction")]
        async Task AddWithdrawAccountTransaction()
        {
            await ApiClient.AuthorizeApiConsumer();

            var operatorRes = (await ApiClient.InvokeCreateOperator(GetCreateOperatorArgs(true))).Object;

            var createUserArgs = GetCreateUserArgs();
            var user = (await ApiClient.InvokeCreateUser(createUserArgs)).Object;

            await ApiClient.AuthorizeApiUser(createUserArgs.Email, createUserArgs.Password);
            var userAccounts = (await ApiClient.InvokeUserAccounts()).Object;

            Assert.Equal(user.FirstName, userAccounts.User.FirstName);
            Assert.NotEmpty(userAccounts.Accounts);

            var transRes = (await ApiClient.InvokeWithdraw(GetAddAccountTransactionArgs(user.UserId, userAccounts.Accounts.FirstOrDefault().AccountId, operatorRes.OperatorId))).Object;

            Assert.NotEqual(0, transRes.TransId);
        }

        [Fact(DisplayName = "Add PublishKnok Account Transaction")]
        async Task AddPublishKnokAccountTransaction()
        {
            await ApiClient.AuthorizeApiConsumer();

            var operatorRes = (await ApiClient.InvokeCreateOperator(GetCreateOperatorArgs(true))).Object;

            var createUserArgs = GetCreateUserArgs();
            var user = (await ApiClient.InvokeCreateUser(createUserArgs)).Object;

            await ApiClient.AuthorizeApiUser(createUserArgs.Email, createUserArgs.Password);
            var userAccounts = (await ApiClient.InvokeUserAccounts()).Object;

            Assert.Equal(user.FirstName, userAccounts.User.FirstName);
            Assert.NotEmpty(userAccounts.Accounts);

            var transRes = (await ApiClient.InvokePublishKnok(GetAddAccountTransactionArgs(user.UserId, userAccounts.Accounts.FirstOrDefault().AccountId, operatorRes.OperatorId))).Object;

            Assert.NotEqual(0, transRes.TransId);
        }

        [Fact(DisplayName = "Add KnokerWinsToken Account Transaction")]
        async Task AddKnokerWinsTokenAccountTransaction()
        {
            await ApiClient.AuthorizeApiConsumer();

            var operatorRes = (await ApiClient.InvokeCreateOperator(GetCreateOperatorArgs(true))).Object;

            var createUserArgs = GetCreateUserArgs();
            var user = (await ApiClient.InvokeCreateUser(createUserArgs)).Object;

            await ApiClient.AuthorizeApiUser(createUserArgs.Email, createUserArgs.Password);
            var userAccounts = (await ApiClient.InvokeUserAccounts()).Object;

            Assert.Equal(user.FirstName, userAccounts.User.FirstName);
            Assert.NotEmpty(userAccounts.Accounts);

            var transRes = (await ApiClient.InvokeKnokerWinsToken(GetAddAccountTransactionArgs(user.UserId, userAccounts.Accounts.FirstOrDefault().AccountId, operatorRes.OperatorId))).Object;

            Assert.NotEqual(0, transRes.TransId);
        }

        [Fact(DisplayName = "Add PlatformWinsToken Account Transaction")]
        async Task AddPlatformWinsTokenAccountTransaction()
        {
            await ApiClient.AuthorizeApiConsumer();

            var operatorRes = (await ApiClient.InvokeCreateOperator(GetCreateOperatorArgs(true))).Object;

            var createUserArgs = GetCreateUserArgs();
            var user = (await ApiClient.InvokeCreateUser(createUserArgs)).Object;

            await ApiClient.AuthorizeApiUser(createUserArgs.Email, createUserArgs.Password);
            var userAccounts = (await ApiClient.InvokeUserAccounts()).Object;

            Assert.Equal(user.FirstName, userAccounts.User.FirstName);
            Assert.NotEmpty(userAccounts.Accounts);

            var transRes = (await ApiClient.InvokePlatformWinsToken(GetAddAccountTransactionArgs(user.UserId, userAccounts.Accounts.FirstOrDefault().AccountId, operatorRes.OperatorId))).Object;

            Assert.NotEqual(0, transRes.TransId);
        }

        [Fact(DisplayName = "Add UserBuyExposure Account Transaction")]
        async Task AddUserBuyExposureAccountTransaction()
        {
            await ApiClient.AuthorizeApiConsumer();

            var operatorRes = (await ApiClient.InvokeCreateOperator(GetCreateOperatorArgs(true))).Object;

            var createUserArgs = GetCreateUserArgs();
            var user = (await ApiClient.InvokeCreateUser(createUserArgs)).Object;

            await ApiClient.AuthorizeApiUser(createUserArgs.Email, createUserArgs.Password);
            var userAccounts = (await ApiClient.InvokeUserAccounts()).Object;

            Assert.Equal(user.FirstName, userAccounts.User.FirstName);
            Assert.NotEmpty(userAccounts.Accounts);

            var transRes = (await ApiClient.InvokeUserBuyExposure(GetAddAccountTransactionArgs(user.UserId, userAccounts.Accounts.FirstOrDefault().AccountId, operatorRes.OperatorId))).Object;

            Assert.NotEqual(0, transRes.TransId);
        }

        [Fact(DisplayName = "Add UserBuyKnok Account Transaction")]
        async Task AddUserBuyKnokAccountTransaction()
        {
            await ApiClient.AuthorizeApiConsumer();

            var operatorRes = (await ApiClient.InvokeCreateOperator(GetCreateOperatorArgs(true))).Object;

            var createUserArgs = GetCreateUserArgs();
            var user = (await ApiClient.InvokeCreateUser(createUserArgs)).Object;

            await ApiClient.AuthorizeApiUser(createUserArgs.Email, createUserArgs.Password);
            var userAccounts = (await ApiClient.InvokeUserAccounts()).Object;

            Assert.Equal(user.FirstName, userAccounts.User.FirstName);
            Assert.NotEmpty(userAccounts.Accounts);

            var transRes = (await ApiClient.InvokeUserBuyKnok(GetAddAccountTransactionArgs(user.UserId, userAccounts.Accounts.FirstOrDefault().AccountId, operatorRes.OperatorId))).Object;

            Assert.NotEqual(0, transRes.TransId);
        }

        [Fact(DisplayName = "Add UserRefundToken Account Transaction")]
        async Task AddUserRefundTokenAccountTransaction()
        {
            await ApiClient.AuthorizeApiConsumer();

            var operatorRes = (await ApiClient.InvokeCreateOperator(GetCreateOperatorArgs(true))).Object;

            var createUserArgs = GetCreateUserArgs();
            var user = (await ApiClient.InvokeCreateUser(createUserArgs)).Object;

            await ApiClient.AuthorizeApiUser(createUserArgs.Email, createUserArgs.Password);
            var userAccounts = (await ApiClient.InvokeUserAccounts()).Object;

            Assert.Equal(user.FirstName, userAccounts.User.FirstName);
            Assert.NotEmpty(userAccounts.Accounts);

            var transRes = (await ApiClient.InvokeUserRefundToken(GetAddAccountTransactionArgs(user.UserId, userAccounts.Accounts.FirstOrDefault().AccountId, operatorRes.OperatorId))).Object;

            Assert.NotEqual(0, transRes.TransId);
        }

        [Fact(DisplayName = "Add UserBuySideBet Account Transaction")]
        async Task AddUserBuySideBetAccountTransaction()
        {
            await ApiClient.AuthorizeApiConsumer();

            var operatorRes = (await ApiClient.InvokeCreateOperator(GetCreateOperatorArgs(true))).Object;

            var createUserArgs = GetCreateUserArgs();
            var user = (await ApiClient.InvokeCreateUser(createUserArgs)).Object;

            await ApiClient.AuthorizeApiUser(createUserArgs.Email, createUserArgs.Password);
            var userAccounts = (await ApiClient.InvokeUserAccounts()).Object;

            Assert.Equal(user.FirstName, userAccounts.User.FirstName);
            Assert.NotEmpty(userAccounts.Accounts);

            var transRes = (await ApiClient.InvokeUserBuySideBet(GetAddAccountTransactionArgs(user.UserId, userAccounts.Accounts.FirstOrDefault().AccountId, operatorRes.OperatorId))).Object;

            Assert.NotEqual(0, transRes.TransId);
        }

        [Fact(DisplayName = "Add UserWinsSideBet Account Transaction")]
        async Task AddUserWinsSideBetAccountTransaction()
        {
            await ApiClient.AuthorizeApiConsumer();

            var operatorRes = (await ApiClient.InvokeCreateOperator(GetCreateOperatorArgs(true))).Object;

            var createUserArgs = GetCreateUserArgs();
            var user = (await ApiClient.InvokeCreateUser(createUserArgs)).Object;

            await ApiClient.AuthorizeApiUser(createUserArgs.Email, createUserArgs.Password);
            var userAccounts = (await ApiClient.InvokeUserAccounts()).Object;

            Assert.Equal(user.FirstName, userAccounts.User.FirstName);
            Assert.NotEmpty(userAccounts.Accounts);

            var transRes = (await ApiClient.InvokeUserWinsSideBet(GetAddAccountTransactionArgs(user.UserId, userAccounts.Accounts.FirstOrDefault().AccountId, operatorRes.OperatorId))).Object;

            Assert.NotEqual(0, transRes.TransId);
        }

        [Fact(DisplayName = "Add PlatformLooseSideBet Account Transaction")]
        async Task AddPlatformLooseSideBetAccountTransaction()
        {
            await ApiClient.AuthorizeApiConsumer();

            var operatorRes = (await ApiClient.InvokeCreateOperator(GetCreateOperatorArgs(true))).Object;

            var createUserArgs = GetCreateUserArgs();
            var user = (await ApiClient.InvokeCreateUser(createUserArgs)).Object;

            await ApiClient.AuthorizeApiUser(createUserArgs.Email, createUserArgs.Password);
            var userAccounts = (await ApiClient.InvokeUserAccounts()).Object;

            Assert.Equal(user.FirstName, userAccounts.User.FirstName);
            Assert.NotEmpty(userAccounts.Accounts);

            var transRes = (await ApiClient.InvokePlatformLooseSideBet(GetAddAccountTransactionArgs(user.UserId, userAccounts.Accounts.FirstOrDefault().AccountId, operatorRes.OperatorId))).Object;

            Assert.NotEqual(0, transRes.TransId);
        }

        [Fact(DisplayName = "Add UserReceiveToken Account Transaction")]
        async Task AddUserReceiveTokenAccountTransaction()
        {
            await ApiClient.AuthorizeApiConsumer();

            var operatorRes = (await ApiClient.InvokeCreateOperator(GetCreateOperatorArgs(true))).Object;

            var createUserArgs = GetCreateUserArgs();
            var user = (await ApiClient.InvokeCreateUser(createUserArgs)).Object;

            await ApiClient.AuthorizeApiUser(createUserArgs.Email, createUserArgs.Password);
            var userAccounts = (await ApiClient.InvokeUserAccounts()).Object;

            Assert.Equal(user.FirstName, userAccounts.User.FirstName);
            Assert.NotEmpty(userAccounts.Accounts);

            var transRes = (await ApiClient.InvokeUserReceiveToken(GetAddAccountTransactionArgs(user.UserId, userAccounts.Accounts.FirstOrDefault().AccountId, operatorRes.OperatorId))).Object;

            Assert.NotEqual(0, transRes.TransId);
        }

        [Fact(DisplayName = "Add UserUpgradeToGold Account Transaction")]
        async Task AddUserUpgradeToGoldAccountTransaction()
        {
            await ApiClient.AuthorizeApiConsumer();

            var operatorRes = (await ApiClient.InvokeCreateOperator(GetCreateOperatorArgs(true))).Object;

            var createUserArgs = GetCreateUserArgs();
            var user = (await ApiClient.InvokeCreateUser(createUserArgs)).Object;

            await ApiClient.AuthorizeApiUser(createUserArgs.Email, createUserArgs.Password);
            var userAccounts = (await ApiClient.InvokeUserAccounts()).Object;

            Assert.Equal(user.FirstName, userAccounts.User.FirstName);
            Assert.NotEmpty(userAccounts.Accounts);

            var transRes = (await ApiClient.InvokeUserUpgradeToGold(GetAddAccountTransactionArgs(user.UserId, userAccounts.Accounts.FirstOrDefault().AccountId, operatorRes.OperatorId))).Object;

            Assert.NotEqual(0, transRes.TransId);
        }

        [Fact(DisplayName = "Add AffiliateCommision Account Transaction")]
        async Task AddAffiliateCommisionAccountTransaction()
        {
            await ApiClient.AuthorizeApiConsumer();

            var operatorRes = (await ApiClient.InvokeCreateOperator(GetCreateOperatorArgs(true))).Object;

            var createUserArgs = GetCreateUserArgs();
            var user = (await ApiClient.InvokeCreateUser(createUserArgs)).Object;

            await ApiClient.AuthorizeApiUser(createUserArgs.Email, createUserArgs.Password);
            var userAccounts = (await ApiClient.InvokeUserAccounts()).Object;

            Assert.Equal(user.FirstName, userAccounts.User.FirstName);
            Assert.NotEmpty(userAccounts.Accounts);

            var transRes = (await ApiClient.InvokeAffiliateCommision(GetAddAccountTransactionArgs(user.UserId, userAccounts.Accounts.FirstOrDefault().AccountId, operatorRes.OperatorId))).Object;

            Assert.NotEqual(0, transRes.TransId);
        }

        [Fact(DisplayName = "Add FreeTokensReturn Account Transaction")]
        async Task AddFreeTokensReturnAccountTransaction()
        {
            await ApiClient.AuthorizeApiConsumer();

            var operatorRes = (await ApiClient.InvokeCreateOperator(GetCreateOperatorArgs(true))).Object;

            var createUserArgs = GetCreateUserArgs();
            var user = (await ApiClient.InvokeCreateUser(createUserArgs)).Object;

            await ApiClient.AuthorizeApiUser(createUserArgs.Email, createUserArgs.Password);
            var userAccounts = (await ApiClient.InvokeUserAccounts()).Object;

            Assert.Equal(user.FirstName, userAccounts.User.FirstName);
            Assert.NotEmpty(userAccounts.Accounts);

            var transRes = (await ApiClient.InvokeFreeTokensReturn(GetAddAccountTransactionArgs(user.UserId, userAccounts.Accounts.FirstOrDefault().AccountId, operatorRes.OperatorId))).Object;

            Assert.NotEqual(0, transRes.TransId);
        }
    }
}
