using ESuite.UI.E2E.Pages;
using OpenQA.Selenium;
using OtpNet;


namespace ESuite.UI.E2E.Helpers
{
    public static class AuthenticationHelper
    {
        private readonly static IWebDriver driver = WebDriverHelper.GetWebDriver();

        public static void LoginWithCredentials(string username, string password, string baseUrl)
        {
            LoginPage loginPage = new(driver);

            I.NavigateToURL($"{baseUrl}/login");

            loginPage.EnterUserEmail(username);
            I.Click(loginPage.NextButton);
            loginPage.EnterPassword(password);
            I.Click(loginPage.LoginButton);
        }

        public static void LoginWithCredentials2FA(string username, string password, string baseUrl, ScenarioContext scenarioContext)
        {
            LoginPage loginPage = new(driver);

            I.NavigateToURL($"{baseUrl}/login");
            I.WaitForElementVisibleAndClickable(loginPage.EmailInput);
            loginPage.EnterUserEmail(username);
            I.Click(loginPage.NextButton);
            I.WaitForElementVisibleAndClickable(loginPage.PasswordInput);
            loginPage.EnterPassword(password);
            I.Click(loginPage.LoginButton);
            I.WaitForElementVisibleAndClickable(LoginPage.SecurityCodeInput);
            
            LoginPage.Enter2FACode(scenarioContext);
            I.Click(loginPage.LoginButton);
        }

        public static void Logout(string baseUrl)
        {
            _ = new LoginPage(driver);
            var url = $"{baseUrl}/logout";

            try
            {
                I.NavigateToURL(url);
            }
            catch (WebDriverException)
            {
                if (driver.Url == url)
                    return;
            }
        }

        public static string GenerateOTP(string secretKey, ScenarioContext scenarioContext)
        {
            var otpKeyStr = secretKey;
            var otpKeyBytes = Base32Encoding.ToBytes(otpKeyStr);
            var totp = new Totp(otpKeyBytes);
            var codeExpiresIn = totp.RemainingSeconds();
            var twoFactorCode = totp.ComputeTotp();
            if (codeExpiresIn < 3)
            {
                I.DebounceDelay(codeExpiresIn + 5000);
                twoFactorCode = totp.ComputeTotp();
                if (twoFactorCode != null)
                {
                    scenarioContext["SecurityCode"] = $"{twoFactorCode}";
                    return twoFactorCode;
                }
                else
                {
                    throw new Exception("Error while generating OTP code.");
                }

            }
            else
            {
                scenarioContext["SecurityCode"] = $"{twoFactorCode}";
                return twoFactorCode;
            }

        }
    }
}