using ESuite.UI.E2E.Helpers;
using ESuite.UI.E2E.Models;
using ESuite.UI.E2E.Pages;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;

namespace ESuite.UI.E2E.StepDefinitions
{
    [Binding]
    public class SSOManagerManagementStepDefinitions
    {
        private readonly IWebDriver driver;
        private readonly BasicPage basicPage;
        private readonly ScenarioContext _scenarioContext;
        private readonly AddSsoProvider _addSsoProvider;
        private readonly AutomationTestManagerHelper automationTestManagerHelper;

        public SSOManagerManagementStepDefinitions(ScenarioContext scenarioContext)
        {
            driver = WebDriverHelper.GetWebDriver();
            basicPage = new BasicPage(driver);
            _scenarioContext = scenarioContext;
            _addSsoProvider = new AddSsoProvider(driver);
            automationTestManagerHelper = new(_scenarioContext);
        }

        [BeforeScenario("createssoprovider", Order = 100)]
        public void CreateSSoProvider()
        {
            automationTestManagerHelper.CreateSsoProvider();
        }

        [AfterScenario("deletessoprovider", Order = 1)]
        public void DeleteSsoCreated()
        {
            automationTestManagerHelper.DeleteSsoProvider();
        }

        [Given(@"I create a new SSO Provider")]
        public void GivenICreateANewSSOProvider(Table dataTable)
        {
            BasicPage.ClickOnDropdownMenuItem("Sso Manager");
            var ssoProviders = dataTable.CreateSet<SsoData>();
            foreach (var ssoProvider in ssoProviders)
            {
                _scenarioContext["SSOProviderName"] = ssoProvider.Name + _scenarioContext["GUID"];
                _scenarioContext["SSOProviderCreated"] = $"{ssoProvider.AuthorisationEndpoint}, {ssoProvider.IsPublic}, {_scenarioContext["SSOProviderName"]}, {ssoProvider.TokenEndpoint}, {ssoProvider.ValidIssuer}";
                I.Click(BasicPage.AddButton);
                I.FillField(AddSsoProvider.NameField, _scenarioContext["SSOProviderName"].ToString()!);
                I.FillField(AddSsoProvider.ClientIDField, ssoProvider.ClientID!);
                I.FillField(AddSsoProvider.ClientSecretField, ssoProvider.ClientSecret!);
                I.FillField(AddSsoProvider.ValidIssuerField, ssoProvider.ValidIssuer!);
                I.FillField(AddSsoProvider.AuthorisationEndpointField, ssoProvider.AuthorisationEndpoint!);
                I.FillField(AddSsoProvider.TokenEndpointField, ssoProvider.TokenEndpoint!);

                if (!ssoProvider.IsPublic!.Equals("true"))
                {
                    if (I.WaitForElementToBeChecked(AddSsoProvider.IsPublicCheckBox))
                    {
                        I.Click(AddSsoProvider.IsPublicCheckBox);
                    }
                }

                I.Click(BasicPage.SaveAndCloseButton);
                AutomationTestManagerHelper.SaveTimingForAction(_scenarioContext);
                I.WaitTillInvisible(BasicPage.SaveAndCloseButton);
            }
            I.WaitForVisible(BasicPage.ToastWithMessage("New Sso Provider added"));
            I.Click(BasicPage.DropdownTab("Home"));
        }

        [Then(@"^new SSO Provider is (present|not present) on the list$")]
        public void ThenNewSSOProviderIsPresentOnTheList(string presence)
        {
            BasicPage.ClickOnDropdownMenuItem("Sso Manager");
            switch (presence)
            {
                case "present":
                    BasicPage.SearchObjectNameInTableViaSearchInputField(_scenarioContext["GUID"].ToString()!, AddSsoProvider.DisplayNameSearchField);
                    break;
                case "not present":
                    BasicPage.SearchDeletedObjectNameInTableViaSearchInputField(_scenarioContext["GUID"].ToString()!);
                    break;
            }
        }

        [When(@"I edit existing SSO Provider")]
        public void WhenIEditExistingSSOProvider(Table dataTable)
        {
            var editSsoProviders = dataTable.CreateSet<SsoData>();
            BasicPage.ClickOnDropdownMenuItem("Sso Manager");
            I.WaitForElementVisibleAndClickable(BasicPage.SearchInput);
            BasicPage.SearchObjectNameInTableViaSearchInputField(_scenarioContext["SSOProviderName"].ToString()!);
            I.Click(BasicPage.EditObjectButton(_scenarioContext["SSOProviderName"].ToString()!));

            foreach (var editSsoProvider in editSsoProviders)
            {
                _scenarioContext["SSOProviderName"] = editSsoProvider.Name + _scenarioContext["GUIDPostfix"];
                _scenarioContext["ClientID"] = editSsoProvider.ClientID;
                _scenarioContext["ClientSecret"] = editSsoProvider.ClientSecret;
                _scenarioContext["ValidIssuer"] = editSsoProvider.ValidIssuer;
                _scenarioContext["AuthorisationEndpoint"] = editSsoProvider.AuthorisationEndpoint;
                _scenarioContext["TokenEndpoint"] = editSsoProvider.TokenEndpoint;
                _scenarioContext["IsPublic"] = editSsoProvider.IsPublic;
                string clientIdHidden = "<Redacted>", clientSecretHidden = "<Redacted>";
                _scenarioContext["SSOProviderEdited"] = $"{editSsoProvider.AuthorisationEndpoint}, {clientIdHidden}, {clientSecretHidden}, {editSsoProvider.IsPublic}, {_scenarioContext["SSOProviderName"]}, {editSsoProvider.TokenEndpoint}, {editSsoProvider.ValidIssuer}";

                I.FillField(AddSsoProvider.NameField, _scenarioContext["SSOProviderName"].ToString()!);
                I.FillField(AddSsoProvider.ClientIDField, editSsoProvider.ClientID!);
                I.FillField(AddSsoProvider.ClientSecretField, editSsoProvider.ClientSecret!);
                I.FillField(AddSsoProvider.ValidIssuerField, editSsoProvider.ValidIssuer!);
                I.FillField(AddSsoProvider.AuthorisationEndpointField, editSsoProvider.AuthorisationEndpoint!);
                I.FillField(AddSsoProvider.TokenEndpointField, editSsoProvider.TokenEndpoint!);
                if (!editSsoProvider.IsPublic!.Equals("true"))
                {
                    if (I.WaitForElementToBeChecked(AddSsoProvider.IsPublicCheckBox))
                    {
                        I.Click(AddSsoProvider.IsPublicCheckBox);
                    }
                }

                I.Click(BasicPage.SaveAndCloseButton);
                AutomationTestManagerHelper.SaveTimingForAction(_scenarioContext);
                I.WaitTillInvisible(BasicPage.SaveAndCloseButton);
            }

            I.WaitForVisible(BasicPage.ToastWithMessage("Sso Provider edited"));
            I.Click(BasicPage.DropdownTab("Home"));
        }

        [Then(@"I check edited data on SSO Provider page")]
        public void ThenICheckEditedDataOnSSOProviderPage()
        {
            BasicPage.ClickOnDropdownMenuItem("Sso Manager");
            BasicPage.SearchObjectNameInTableViaSearchInputField(_scenarioContext["SSOProviderName"].ToString()!, AddSsoProvider.DisplayNameSearchField);
            I.Click(BasicPage.EditObjectButton(_scenarioContext["SSOProviderName"].ToString()!));
            I.WaitForElementWithAttributeValue(AddSsoProvider.NameField, "value", _scenarioContext["SSOProviderName"].ToString()!);
            I.WaitForElementWithAttributeValue(AddSsoProvider.ClientIDField, "value", _scenarioContext["ClientID"].ToString()!);
            I.WaitForElementWithAttributeValue(AddSsoProvider.ClientSecretField, "value", _scenarioContext["ClientSecret"].ToString()!);
            I.WaitForElementWithAttributeValue(AddSsoProvider.ValidIssuerField, "value", _scenarioContext["ValidIssuer"].ToString()!);
            I.WaitForElementWithAttributeValue(AddSsoProvider.AuthorisationEndpointField, "value", _scenarioContext["AuthorisationEndpoint"].ToString()!);
            I.WaitForElementWithAttributeValue(AddSsoProvider.TokenEndpointField, "value", _scenarioContext["TokenEndpoint"].ToString()!);
            if (_scenarioContext["IsPublic"].ToString()!.Equals("true"))
            {
                Assert.IsTrue(I.WaitForElementToBeChecked(AddSsoProvider.IsPublicCheckBox, 1));
            }
            else
            {
                Assert.IsFalse(I.WaitForElementToBeChecked(AddSsoProvider.IsPublicCheckBox, 1));
            }
        }

        [When(@"I delete existing SSO Provider")]
        public void WhenIDeleteExistingSSOProvider()
        {
            BasicPage.ClickOnDropdownMenuItem("Sso Manager");
            I.WaitForElementVisibleAndClickable(BasicPage.SearchInput);
            BasicPage.SearchObjectNameInTableViaSearchInputField(_scenarioContext["SSOProviderName"].ToString()!);
            I.Click(BasicPage.DeleteObjectButton(_scenarioContext["SSOProviderName"].ToString()!));
            I.WaitTillInvisible(BasicPage.DeleteObjectButton(_scenarioContext["SSOProviderName"].ToString()!));
            I.Click(BasicPage.ConfirmDeletionButton);
            AutomationTestManagerHelper.SaveTimingForAction(_scenarioContext);
        }
    }
}
