using ESuite.UI.E2E.Helpers;
using ESuite.UI.E2E.Helpers.Mail;
using ESuite.UI.E2E.Models;
using ESuite.UI.E2E.Pages;
using OpenQA.Selenium;

namespace ESuite.UI.E2E.StepDefinitions
{
    [Binding]
    public class UserCreationAndEditingStepDefinitions
    {
        private readonly IWebDriver driver;
        private readonly EditUsersPage editUsersPage;
        private readonly UserAuthenticationStepDefinitions userAuthenticationStepDefinitions;
        private readonly Mailer mailer;
        private readonly ScenarioContext _scenarioContext;
        private readonly APIHelper apiHelper;
        private readonly ConfigHelper configHelper;
        private readonly AutomationTestManagerHelper automationTestManagerHelper;


        public UserCreationAndEditingStepDefinitions(ScenarioContext scenarioContext)
        {
            driver = WebDriverHelper.GetWebDriver();
            editUsersPage = new EditUsersPage(driver);
            mailer = new Mailer();
            _scenarioContext = scenarioContext;
            apiHelper = new APIHelper(_scenarioContext);
            configHelper = new ConfigHelper();
            userAuthenticationStepDefinitions = new(_scenarioContext);
            automationTestManagerHelper = new(_scenarioContext);

        }

        [Given(@"I create a new user")]
        public void GivenICreateANewUser(Table dataTable)
        {
            BasicPage.ClickOnDropdownMenuItem("Users");

            var users = dataTable.CreateSet<UsersData>();

            foreach (var user in users)
            {
                _scenarioContext["UserName"] = $"{user.FirstName} {user.MiddleNames} {user.LastName}";
                _scenarioContext["UserEmail"] = Mailer.CustomizeUserEmail(user.Mail!, _scenarioContext["GUID"].ToString()!);

                I.Click(BasicPage.AddButton);
                I.FillField(AddUsersPage.MailField, _scenarioContext["UserEmail"].ToString()!);
                I.FillField(AddUsersPage.FirstNameField, user.FirstName!);
                I.FillField(AddUsersPage.MiddleNamesField, user.MiddleNames!);
                I.FillField(AddUsersPage.LastNameField, user.LastName!);
                I.SelectOption(BasicPage.SelectorByLabel("Domain"), user.Domain!);
                I.Click(BasicPage.SaveAndCloseButton);
                AutomationTestManagerHelper.SaveTimingForAction(_scenarioContext);
                I.WaitTillInvisible(BasicPage.SaveAndCloseButton);
                BasicPage.SearchObjectNameInTableViaSearchInputField(_scenarioContext["GUID"].ToString()!, AddUsersPage.EmailSearchField);
            }
        }

        [Given(@"I create a new user through an API call")]
        public void GivenICreateANewUserThroughAPICall(Table dataTable)
        {
            Task.Run(async () =>
            {
                var users = dataTable.CreateSet<UsersData>();
                int userCount = 1;


                foreach (var user in users)
                {
                    string email = Mailer.CustomizeUserEmail(user.Mail!, _scenarioContext["GUID"].ToString()!);

                    if (userCount > 1)
                    {
                        _scenarioContext[$"UserName{userCount}"] = $"{user.FirstName} {user.MiddleNames} {user.LastName}";
                        _scenarioContext[$"UserEmail{userCount}"] = email;
                    }
                    else
                    {
                        _scenarioContext["UserName"] = $"{user.FirstName} {user.MiddleNames} {user.LastName}";
                        _scenarioContext["UserEmail"] = email;
                    }

                    var domains = await apiHelper.GetDomains(configHelper.APIUrl);
                    var data = domains["data"]!.ElementAt(0);
                    int domainId = (int)data["id"]!;

                    await apiHelper.CreateNewUser(
                        configHelper.APIUrl,
                        user.FirstName!,
                        user.MiddleNames!,
                        user.LastName!,
                        email,
                        domainId
                    );

                    userCount++;
                }
            });
        }

        [When(@"I edit an existing user")]
        public void GivenIEditAnExistingUser(Table dataTable)
        {
            BasicPage.ClickOnDropdownUserMenuItem("Account");

            var editUsers = dataTable.CreateSet<UsersData>();

            foreach (var editUser in editUsers)
            {
                _scenarioContext["FirstName"] = editUser.EditedFirstName + _scenarioContext["GUID"];
                _scenarioContext["MiddleNames"] = editUser.EditedMiddleNames;
                _scenarioContext["LastName"] = editUser.EditedLastName;
                _scenarioContext["UserName"] = $"{_scenarioContext["FirstName"]} {editUser.EditedMiddleNames} {editUser.EditedLastName}";
                _scenarioContext["UserNameEdited"] = $"{_scenarioContext["FirstName"]}, {editUser.EditedLastName}, {editUser.EditedLastName}, {"<Redacted>"}";

                I.FillField(editUsersPage.FirstNameField, _scenarioContext["FirstName"].ToString()!);
                I.FillField(editUsersPage.MiddleNamesField, editUser.EditedMiddleNames!);
                I.FillField(editUsersPage.LastNameField, editUser.EditedLastName!);
                if (!string.IsNullOrEmpty(editUser.Password))
                {
                    _scenarioContext["Password"] = editUser.Password + _scenarioContext["GUIDPostfix"];

                    userAuthenticationStepDefinitions.EnterNewPasswordAndConfirmIt();
                }
                if (editUsersPage.MFACheckbox != null && string.Equals(editUser.MFA ?? "", "true", StringComparison.CurrentCultureIgnoreCase) && !(I.WaitForElementToBeChecked(editUsersPage.MFACheckbox, 1)))
                {
                    I.Click(editUsersPage.MFACheckbox);
                }
                else if (editUsersPage.MFACheckbox != null && string.Equals(editUser.MFA ?? "", "false", StringComparison.CurrentCultureIgnoreCase) && (I.WaitForElementToBeChecked(editUsersPage.MFACheckbox, 1)))
                {
                    I.Click(editUsersPage.MFACheckbox);
                }
                I.Click(BasicPage.SaveButton);
                AutomationTestManagerHelper.SaveTimingForAction(_scenarioContext);
            }
        }

        [Then(@"I check edited data on edit user page")]
        public void ThenICheckEditedDataOnEditUserPage()
        {
            BasicPage.ClickOnDropdownMenuItem("Users");
            BasicPage.SearchObjectNameInTableViaSearchInputField(_scenarioContext["UserEmail"].ToString()!, AddUsersPage.EmailSearchField);
            I.Click(BasicPage.EditObjectButton(_scenarioContext["UserEmail"].ToString()!));
            I.WaitForElementWithAttributeValue(AddUsersPage.FirstNameField, "value", _scenarioContext["FirstName"].ToString()!);
            I.WaitForElementWithAttributeValue(AddUsersPage.MiddleNamesField, "value", _scenarioContext["MiddleNames"].ToString()!);
            I.WaitForElementWithAttributeValue(AddUsersPage.LastNameField, "value", _scenarioContext["LastName"].ToString()!);
        }
    }
}

