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 GlossaryObjectsStepDefinitions
    {
        private readonly IWebDriver driver;
        private readonly ScenarioContext _scenarioContext;
        private readonly AutomationTestManagerHelper automationTestManagerHelper;

        public GlossaryObjectsStepDefinitions(ScenarioContext scenarioContext)
        {
            driver = WebDriverHelper.GetWebDriver();
            _scenarioContext = scenarioContext;
            automationTestManagerHelper = new(_scenarioContext);
        }

        [When(@"^I (create|edit) a FormTemplate$")]
        [Given(@"^I (create|edit) a FormTemplate$")]
        public void WhenICreateAFormTemplate(string action, Table dataTable)
        {
            BasicPage.ClickOnDropdownMenuItem("Forms");

            var forms = dataTable.CreateSet<FormTemplateData>();

            if (action == "create")
            {
                I.Click(BasicPage.AddButton);
                foreach (var form in forms)
                {
                    FillFormTemplate(form);
                }
            }
            else if (action == "edit")
            {
                BasicPage.SearchObjectNameInTableViaSearchInputField(_scenarioContext["FormName"].ToString()!);
                I.Click(BasicPage.EditObjectButton(_scenarioContext["FormName"].ToString()!));
                foreach (var form in forms)
                {
                    FillFormTemplate(form);
                }
            }

            I.Click(BasicPage.SaveAndCloseButton);
            AutomationTestManagerHelper.SaveTimingForAction(_scenarioContext);
            I.WaitTillInvisible(BasicPage.SaveAndCloseButton);
            BasicPage.ClickOnDropdownMenuItem("Forms");
            BasicPage.SearchObjectNameInTableViaSearchInputField(_scenarioContext["FormName"].ToString()!);

        }

        [When(@"I create a Glossary")]
        [Given(@"I create a Glossary")]
        public void ThenICreateAGlossaryWithSequenceCustomField(Table dataTable)
        {
            var glossaries = dataTable.CreateSet<GlossariesData>();
            BasicPage.ClickOnDropdownMenuItem("Glossaries");

            I.Click(BasicPage.AddButton);
            foreach (var glossary in glossaries)
            {
                switch (glossary.Add)
                {
                    case "customField":
                        I.Click(AddGlossariesPage.CustomFieldsSelector);
                        I.SelectOption(AddGlossariesPage.CustomFieldsSelector, _scenarioContext["CustomFieldName"]!);
                        break;
                    case "form":
                        I.Click(AddGlossariesPage.CustomFieldsSelector);
                        I.SelectOption(AddGlossariesPage.CustomFieldsSelector, _scenarioContext["CustomFieldName"]!);
                        break;
                    default:
                        break;
                }

                if (!string.IsNullOrEmpty(glossary.Name))
                {
                    _scenarioContext["GlossaryName"] = glossary.Name + _scenarioContext["GUIDPostfix"];

                    I.Click(BasicPage.NameField);
                    I.FillField(BasicPage.NameField, _scenarioContext["GlossaryName"].ToString()!);
                }

                if (!string.IsNullOrEmpty(glossary.Add))
                {

                    I.Click(AddGlossariesPage.PlusButton);
                    I.WaitTillInvisible(AddGlossariesPage.PlusButton);
                }
            }

            I.Click(BasicPage.SaveAndCloseButton);
            AutomationTestManagerHelper.SaveTimingForAction(_scenarioContext);
            I.WaitTillInvisible(BasicPage.SaveAndCloseButton);
            BasicPage.ClickOnDropdownMenuItem("Glossaries");
            I.WaitForVisible(AddGlossariesPage.SearchGlossaryNameInTable(_scenarioContext["GlossaryName"].ToString()));
        }

        [Then(@"I create a Glossary Item")]
        [Given(@"I create a Glossary Item")]
        public void ThenICreateAGlossaryItem(Table dataTable)
        {
            BasicPage.ClickOnDropdownMenuItem("Glossaries");

            var items = dataTable.CreateSet<GlossaryItemData>();
            List<string> glossaryList = [];

            foreach (var item in items)
            {
                _scenarioContext["GlossaryItemName"] = item.Name + Guid.NewGuid();
                I.Click(By.LinkText(_scenarioContext["GlossaryName"].ToString()!));
                I.Click(BasicPage.AddButton);
                I.WaitTillInvisible(BasicPage.LoadingMessage);

                if (_scenarioContext.TryGetValue("FormName", out object? value))
                {
                    try
                    {
                        I.FillField(BasicPage.NameField, _scenarioContext["CustomFieldName"].ToString()!);
                        I.SelectOption(
                            BasicPage.SelectorByLabel(_scenarioContext["CustomFieldName"].ToString()), value!);
                    }
                    catch (Exception)
                    {
                        I.RefreshPage(driver);
                        I.WaitTillInvisible(BasicPage.LoadingMessage);
                        I.FillField(BasicPage.NameField, _scenarioContext["CustomFieldName"].ToString()!);
                        I.SelectOption(
                            BasicPage.SelectorByLabel(_scenarioContext["CustomFieldName"].ToString()), value!);
                    }
                }
                else if (!string.IsNullOrEmpty(item.CustomField))
                {
                    I.SelectOption(AddGlossaryItemPage.AddSelector, _scenarioContext["CustomFieldName"]!);
                }

                I.FillField(BasicPage.NameField, _scenarioContext["GlossaryItemName"].ToString()!);
                I.Click(BasicPage.SaveAndCloseButton);
                AutomationTestManagerHelper.SaveTimingForAction(_scenarioContext);
                I.WaitTillInvisible(BasicPage.SaveAndCloseButton);
                I.WaitForVisible(AddGlossariesPage.SearchGlossaryNameInTable(_scenarioContext["GlossaryItemName"].ToString()));
                glossaryList.Add(_scenarioContext["GlossaryItemName"].ToString()!);
            }
            _scenarioContext["GlossaryList"] = glossaryList;
        }

        [Then(@"I check if version of FormTemplate was changed")]
        [Then(@"I check if version of FormTemplate version is correct")]
        public void ThenICheckIfVersionOfFormTemplateWasChanged(Table dataTable)
        {
            BasicPage.ClickOnDropdownMenuItem("Forms");
            BasicPage.SearchObjectNameInTableViaSearchInputField(_scenarioContext["FormName"].ToString()!);

            var versions = dataTable.CreateSet<FormTemplateData>();

            foreach (var version in versions)
            {
                int actualVersion = AddFormTemplatePage.GetFormVersionTemplateByName(_scenarioContext["FormName"].ToString()!);

                _scenarioContext["FormVersion"] = version.Version;

                Assert.AreEqual((int)_scenarioContext["FormVersion"], actualVersion);
            }
        }

        [AfterScenario("deleteform", Order = 5)]
        [When(@"I delete existing Form Template")]
        [Then(@"I delete existing Form Template")]
        public void DeleteFormTemplate()
        {
            automationTestManagerHelper.DeleteFormTemplate();
        }

        private void FillFormTemplate(FormTemplateData form)
        {
            if (!string.IsNullOrEmpty(form.Name)) _scenarioContext["FormName"] = form.Name + _scenarioContext["GUIDPostfix"];
            if (!string.IsNullOrEmpty(form.ChildFormName)) _scenarioContext["ChildFormName"] = $"{_scenarioContext["FormName"]}";
            if (!string.IsNullOrEmpty(form.Name)) I.FillField(BasicPage.NameField, _scenarioContext["FormName"].ToString()!);
            if (form.NeedTable == true) AddFormTemplatePage.CreateTableViaGrid(form.TotalNumberOfRows, form.TotalNumberOfColumns);
            if (!string.IsNullOrEmpty(form.Text)) AddFormTemplatePage.FillFieldTextInForm(form.Text, form.RowNumber, form.ColumnNumber);
            switch (form.CustomFields)
            {
                case "customFieldNameFromScenarioContext":
                    AddFormTemplatePage.ChooseCustomField(_scenarioContext["CustomFieldName"].ToString(), form.RowNumber, form.ColumnNumber);
                    break;
                case "Glossary":
                    AddFormTemplatePage.ChooseCustomField(_scenarioContext["CustomFieldNameGlossary"].ToString(), form.RowNumber, form.ColumnNumber);
                    break;
                case "Domain":
                    AddFormTemplatePage.ChooseCustomField(_scenarioContext["CustomFieldNameDomain"].ToString(), form.RowNumber, form.ColumnNumber);
                    break;
                case "Text":
                    AddFormTemplatePage.ChooseCustomField(_scenarioContext["CustomFieldNameText"].ToString(), form.RowNumber, form.ColumnNumber);
                    break;
                case "Sequence":
                    AddFormTemplatePage.ChooseCustomField(_scenarioContext["CustomFieldNameSequence"].ToString(), form.RowNumber, form.ColumnNumber);
                    break;
                case "Form Template":
                    AddFormTemplatePage.ChooseCustomField(_scenarioContext["CustomFieldNameFormTemplate"].ToString(), form.RowNumber, form.ColumnNumber);
                    break;
                case "Number":
                    AddFormTemplatePage.ChooseCustomField(_scenarioContext["CustomFieldNameNumber"].ToString(), form.RowNumber, form.ColumnNumber);
                    break;
                default:
                    break;
            }
        }
    }
}