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 CustomFieldsStepDefinitions
    {
        private readonly ScenarioContext _scenarioContext;
        private readonly ConfigHelper configHelper;
        public CustomFieldsStepDefinitions(ScenarioContext scenarioContext)
        {
            _scenarioContext = scenarioContext;
            configHelper = new();
        }

        [Given(@"^I (create|edit) a CustomField$")]
        [When(@"^I (create|edit) a CustomField$")]
        public void WhenICreateACustomFieldWith(string action, Table dataTable)
        {
            BasicPage.ClickOnDropdownMenuItem("Custom Fields");

            var customFields = dataTable.CreateSet<CustomFieldsData>();

            foreach (var customField in customFields)
            {
                if (action == "create")
                {
                    _scenarioContext["CustomFieldName"] = customField.Name + _scenarioContext["GUIDPostfix"];

                    I.Click(BasicPage.AddButton);
                }
                else if (action == "edit")
                {
                    I.WaitForElementVisibleAndClickable(BasicPage.SearchInput);
                    BasicPage.SearchObjectNameInTableViaSearchInputField(_scenarioContext["CustomFieldName"].ToString()!);
                    I.Click(BasicPage.EditObjectButton(_scenarioContext["CustomFieldName"].ToString()!));
                    _scenarioContext["CustomFieldName"] = customField.Name + _scenarioContext["GUIDPostfix"];
                }
                I.WaitForPageToLoad();

                if (!string.IsNullOrEmpty(customField.Name))
                {
                    I.WaitForElementVisibleAndClickable(BasicPage.NameField);
                    I.FillField(BasicPage.NameField, _scenarioContext["CustomFieldName"].ToString()!);
                }
                if (customField.FieldType != null) I.SelectOption(AddCustomFieldsPage.FieldTypeSelector, customField.FieldType!);
                By selector = BasicPage.SelectorByLabel(customField.FieldType);

                //Thread.Sleep(3000);
                switch (customField.FieldType)
                {
                    case "Sequence":
                        I.WaitForVisible(selector);
                        if (customField.Sequence != null) I.SelectOption(selector, _scenarioContext["SequenceName"]!);
                        _scenarioContext["CustomField"] = $"{_scenarioContext["CustomFieldName"]}, {customField.FieldType.Trim()}";
                        _scenarioContext["CustomFieldNameSequence"] = $"{_scenarioContext["CustomFieldName"]}";
                        break;
                    case "Glossary":
                        I.WaitForVisible(selector);
                        if (customField.Glossary != null) I.SelectOption(selector, _scenarioContext["GlossaryName"]!);
                        if (customField.Required != null && customField.Required.Equals("true", StringComparison.CurrentCultureIgnoreCase) && !(I.WaitForElementToBeChecked(AddCustomFieldsPage.CheckBox, 1)))
                        {
                            I.Click(AddCustomFieldsPage.CheckBox);
                            _scenarioContext["CustomFieldRequired"] = $"{customField.Required}";
                        }
                        else if (customField.Required != null && customField.Required.Equals("false", StringComparison.CurrentCultureIgnoreCase) && (I.WaitForElementToBeChecked(AddCustomFieldsPage.CheckBox, 1)))
                        {
                            I.Click(AddCustomFieldsPage.CheckBox);
                            _scenarioContext["CustomFieldRequired"] = $"{customField.Required}";
                        }
                        if (customField.MaxEntries != null)
                        {
                            I.FillField(AddCustomFieldsPage.MaxEntriesField, customField.MaxEntries);
                            _scenarioContext["CustomFieldMaxEntries"] = $"{customField.MaxEntries}";
                        }
                        else if (customField.MaxEntries == null)
                        {
                            I.FillField(AddCustomFieldsPage.MaxEntriesField, "");
                            _scenarioContext["CustomFieldMaxEntries"] = $"{""}";
                        }
                        _scenarioContext["CustomField"] = $"{_scenarioContext["CustomFieldName"]}, {customField.FieldType.Trim()}, {_scenarioContext["CustomFieldMaxEntries"]}";
                        _scenarioContext["CustomFieldNameGlossary"] = $"{_scenarioContext["CustomFieldName"]}";

                        break;
                    case "Form Template":
                        _scenarioContext["CustomField"] = $"{_scenarioContext["CustomFieldName"]}";
                        _scenarioContext["CustomFieldNameFormTemplate"] = $"{_scenarioContext["CustomFieldName"]}";
                        break;
                    case "Number":
                        if (customField.DefaultValue != null)
                        {
                            I.FillField(AddCustomFieldsPage.DefaultValueField, customField.DefaultValue);
                            _scenarioContext["CustomFieldDefaultValue"] = $"{customField.DefaultValue}";
                        }
                        if (customField.MinimumValue != null)
                        {
                            I.FillField(AddCustomFieldsPage.MinValueField, customField.MinimumValue);
                            _scenarioContext["CustomFieldMinimumValue"] = $"{customField.MinimumValue}";
                        }
                        if (customField.MaximumValue != null)
                        {
                            I.FillField(AddCustomFieldsPage.MaxValueField, customField.MaximumValue);
                            _scenarioContext["CustomFieldMaximumValue"] = $"{customField.MaximumValue}";
                        }
                        if (customField.Step != null)
                        {
                            I.FillField(AddCustomFieldsPage.StepField, customField.Step);
                            _scenarioContext["CustomFieldStep"] = $"{customField.Step}";
                        }
                        if (customField.Required != null && customField.Required.Equals("true", StringComparison.CurrentCultureIgnoreCase) && !(I.WaitForElementToBeChecked(AddCustomFieldsPage.CheckBox, 1)))
                        {
                            I.Click(AddCustomFieldsPage.CheckBox);
                            _scenarioContext["CustomFieldRequired"] = $"{customField.Required}";

                        }
                        else if (customField.Required != null && customField.Required.Equals("false", StringComparison.CurrentCultureIgnoreCase) && (I.WaitForElementToBeChecked(AddCustomFieldsPage.CheckBox, 1)))
                        {
                            I.Click(AddCustomFieldsPage.CheckBox);
                            _scenarioContext["CustomFieldRequired"] = $"{customField.Required}";
                        }
                        _scenarioContext["CustomField"] = $"{_scenarioContext["CustomFieldName"]}, {customField.DefaultValue}, {customField.FieldType}, {customField.MinimumValue}, {customField.MaximumValue}, {customField.Step}";
                        _scenarioContext["CustomFieldNameNumber"] = $"{_scenarioContext["CustomFieldName"]}";
                        break;
                    case "Text":
                        if (customField.DefaultValue != null) I.FillField(AddCustomFieldsPage.DefaultValueField, customField.DefaultValue);
                        if (customField.MultiLine != null && customField.MultiLine.Equals("true", StringComparison.CurrentCultureIgnoreCase) && !(I.WaitForElementToBeChecked(AddCustomFieldsPage.CheckBox, 1)))
                        {
                            I.Click(AddCustomFieldsPage.CheckBox);
                        }
                        else if (customField.MultiLine != null && customField.MultiLine.Equals("false", StringComparison.CurrentCultureIgnoreCase) && (I.WaitForElementToBeChecked(AddCustomFieldsPage.CheckBox, 1)))
                        {
                            I.Click(AddCustomFieldsPage.CheckBox);
                        }
                        _scenarioContext["CustomFieldDefaultValue"] = $"{customField.DefaultValue}";
                        _scenarioContext["CustomFieldMultiLine"] = $"{customField.MultiLine}";
                        _scenarioContext["CustomField"] = $"{_scenarioContext["CustomFieldName"]}, {customField.DefaultValue}, {customField.MultiLine}";
                        _scenarioContext["CustomFieldNameText"] = $"{_scenarioContext["CustomFieldName"]}";
                        break;
                    case "Domain":
                        if (customField.MaxEntries != null)
                        {
                            I.FillField(AddCustomFieldsPage.MaxEntriesField, customField.MaxEntries);
                            _scenarioContext["CustomFieldMaxEntries"] = $"{customField.MaxEntries}";
                        }
                        if (customField.Required != null && customField.Required.Equals("true", StringComparison.CurrentCultureIgnoreCase) && !(I.WaitForElementToBeChecked(AddCustomFieldsPage.CheckBox, 1)))
                        {
                            I.Click(AddCustomFieldsPage.CheckBox);
                            _scenarioContext["CustomFieldRequired"] = $"{customField.Required}";
                        }
                        else if (customField.Required != null && customField.Required.Equals("false", StringComparison.CurrentCultureIgnoreCase) && (I.WaitForElementToBeChecked(AddCustomFieldsPage.CheckBox, 1)))
                        {
                            I.Click(AddCustomFieldsPage.CheckBox);
                            _scenarioContext["CustomFieldRequired"] = $"{customField.Required}";
                        }
                        _scenarioContext["CustomField"] = $"{_scenarioContext["CustomFieldName"]}, {customField.MaxEntries}";
                        _scenarioContext["CustomFieldNameDomain"] = $"{_scenarioContext["CustomFieldName"]}";
                        break;

                    default:
                        throw new NoSuchElementException($"This type of Custom Field: {customField.FieldType} doesn't exist!");
                }
                _scenarioContext["CustomFieldType"] = customField.FieldType;
                I.Click(BasicPage.SaveAndCloseButton);
                AutomationTestManagerHelper.SaveTimingForAction(_scenarioContext);
                I.WaitTillInvisible(BasicPage.SaveAndCloseButton);
                BasicPage.ClickOnDropdownMenuItem("Custom Fields");
                BasicPage.SearchObjectNameInTableViaSearchInputField(_scenarioContext["CustomFieldName"].ToString()!);
            }
        }

        [AfterScenario("deletecustomfield", Order = 90)]
        [When(@"I delete a CustomField")]
        public void WhenIDeleteACustomField()
        {
            BasicPage.ClickOnDropdownMenuItem("Custom Fields");
            BasicPage.SearchObjectNameInTableViaSearchInputField(_scenarioContext["CustomFieldName"].ToString()!);
            I.Click(BasicPage.DeleteObjectButton(_scenarioContext["CustomFieldName"].ToString()!));
            I.WaitTillInvisible(BasicPage.DeleteObjectButton(_scenarioContext["CustomFieldName"].ToString()!));
            I.Click(BasicPage.ConfirmDeletionButton);
            AutomationTestManagerHelper.SaveTimingForAction(_scenarioContext);
            I.WaitTillInvisible(BasicPage.ConfirmDeletionButton);
        }

        [Then(@"I check data on Custom Field page")]
        public void ThenICheckDataOnCustomFieldPage(Table dataTable)
        {
            var customFields = dataTable.CreateSet<CustomFieldsData>();
            RetryHelper.Retry(() =>
            {
                BasicPage.ClickOnDropdownMenuItem("Custom Fields");
                BasicPage.SearchObjectNameInTableViaSearchInputField(_scenarioContext["CustomFieldName"].ToString()!, AddSsoProvider.DisplayNameSearchField);

                I.Click(BasicPage.EditObjectButton(_scenarioContext["CustomFieldName"].ToString()!));
                I.WaitTillInvisible(BasicPage.EditObjectButton(_scenarioContext["CustomFieldName"].ToString()!));
                I.WaitForPageToLoad();

                foreach (var customField in customFields)
                {
                    I.DebounceDelay(configHelper.DebounceDelayMilliseconds);
                    I.WaitForElementWithAttributeValue(BasicPage.NameField, "value", _scenarioContext["CustomFieldName"].ToString()!);
                    var expectedCustomFieldType = _scenarioContext["CustomFieldType"].ToString()!;
                    var actualCustomFieldType = I.ReturnSelectedOption(AddCustomFieldsPage.FieldTypeSelector, 1);

                    Assert.AreEqual(expectedCustomFieldType, actualCustomFieldType, $"Expected Custom Field Type was: {expectedCustomFieldType}, but found: {actualCustomFieldType}");
                    By selector = BasicPage.SelectorByLabel(customField.FieldType);
                    switch (customField.FieldType)
                    {
                        case "Sequence":
                            var expectedSequence = _scenarioContext["SequenceName"].ToString()!;
                            var actualSequence = I.ReturnSelectedOption(selector, 1);
                            Assert.AreEqual(expectedSequence, actualSequence, $"Expected Sequence value was: {expectedSequence}, but found: {actualSequence}");
                            break;
                        case "Glossary":
                            var expectedGlossary = _scenarioContext["GlossaryName"].ToString()!;
                            var actualGlossary = I.ReturnSelectedOption(selector, 1);
                            Assert.AreEqual(expectedGlossary, actualGlossary, $"Expected Glossary value was: {expectedGlossary}, but found: {actualGlossary}");
                            if (_scenarioContext["CustomFieldRequired"].ToString()!.Equals("true"))
                            {
                                Assert.IsTrue(I.WaitForElementToBeChecked(AddCustomFieldsPage.CheckBox, 1), "Custom Field required option is not selected");
                            }
                            else
                            {
                                Assert.IsFalse(I.WaitForElementToBeChecked(AddCustomFieldsPage.CheckBox, 1), "Custom Field required option is selected");
                            }
                            I.WaitForElementWithAttributeValue(AddCustomFieldsPage.MaxEntriesField, "value", _scenarioContext["CustomFieldMaxEntries"].ToString()!);
                            break;
                        case "Form Template":
                            break;
                        case "Number":
                            I.WaitForElementWithAttributeValue(AddCustomFieldsPage.MinValueField, "value", _scenarioContext["CustomFieldMinimumValue"].ToString()!);
                            I.WaitForElementWithAttributeValue(AddCustomFieldsPage.MaxValueField, "value", _scenarioContext["CustomFieldMaximumValue"].ToString()!);
                            I.WaitForElementWithAttributeValue(AddCustomFieldsPage.StepField, "value", _scenarioContext["CustomFieldStep"].ToString()!);
                            if (_scenarioContext["CustomFieldRequired"].ToString()!.Equals("true"))
                            {
                                Assert.IsTrue(I.WaitForElementToBeChecked(AddCustomFieldsPage.CheckBox, 1), "Custom Field required option is not selected");
                            }
                            else
                            {
                                Assert.IsFalse(I.WaitForElementToBeChecked(AddCustomFieldsPage.CheckBox, 1), "Custom Field required option is selected");
                            }
                            I.WaitForElementWithAttributeValue(AddCustomFieldsPage.DefaultValueField, "value", _scenarioContext["CustomFieldDefaultValue"].ToString()!);
                            break;
                        case "Text":
                            if (_scenarioContext["CustomFieldMultiLine"].ToString()!.Equals("true"))
                            {
                                Assert.IsTrue(I.WaitForElementToBeChecked(AddCustomFieldsPage.CheckBox, 1), "Custom Field multiline option is not selected");
                            }
                            else
                            {
                                Assert.IsFalse(I.WaitForElementToBeChecked(AddCustomFieldsPage.CheckBox, 1), "Custom Field multiline option is selected");
                            }
                            I.WaitForElementWithAttributeValue(AddCustomFieldsPage.DefaultValueField, "value", _scenarioContext["CustomFieldDefaultValue"].ToString()!);
                            break;
                        case "Domain":
                            if (_scenarioContext["CustomFieldRequired"].ToString()!.Equals("true"))
                            {
                                Assert.IsTrue(I.WaitForElementToBeChecked(AddCustomFieldsPage.CheckBox, 1), "Custom Field required option is not selected");
                            }
                            else
                            {
                                Assert.IsFalse(I.WaitForElementToBeChecked(AddCustomFieldsPage.CheckBox, 1), "Custom Field required option is selected");
                            }
                            I.WaitForElementWithAttributeValue(AddCustomFieldsPage.MaxEntriesField, "value", _scenarioContext["CustomFieldMaxEntries"].ToString()!);
                            break;
                        default:
                            throw new NoSuchElementException($"This type of Custom Field: {customField} doesn't exist!");
                    }
                }
            });
        }
    }

}
