using Grand.Business.Core.Interfaces.Common.Localization;
using Grand.Business.Core.Interfaces.Marketing.Contacts;
using Grand.Domain.Common;
using Grand.Domain.Customers;
using Grand.Domain.Messages;
using Grand.Infrastructure;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;

namespace Grand.Business.Marketing.Services.Contacts.Tests
{
    [TestClass()]
    public class ContactAttributeParserTests
    {
        private Mock<IContactAttributeService> _contactAttributeServiceMock;
        private Mock<IWorkContext> _workContextMock;
        private ContactAttributeParser _parser;
        private List<CustomAttribute> customAtr;
        private List<ContactAttribute> _contactAtr;

        [TestInitialize()]
        public void Init()
        {
            _contactAttributeServiceMock = new Mock<IContactAttributeService>();
            _workContextMock = new Mock<IWorkContext>();
            var _translationServiceMock = new Mock<ITranslationService>();
            {
                _translationServiceMock.Setup(x => x.GetResource(It.IsAny<string>())).Returns("Warning{0}");
            }

            _parser = new ContactAttributeParser(_contactAttributeServiceMock.Object, _workContextMock.Object);
            customAtr = new List<CustomAttribute>()
            {
                new CustomAttribute(){Key="key1",Value="value1" },
                new CustomAttribute(){Key="key2",Value="value2" },
                new CustomAttribute(){Key="key3",Value="value3" },
                new CustomAttribute(){Key="key4",Value="value4" },
            };

            _contactAtr = new List<ContactAttribute>()
            {
                new ContactAttribute(){Id="key1", Name="name1", AttributeControlType = Domain.Catalog.AttributeControlType.TextBox},
                new ContactAttribute(){Id="key2", Name="name2"},
                new ContactAttribute(){Id="key3", Name="name3"},
                new ContactAttribute(){Id="key4", Name="name4"},
                new ContactAttribute(){Id="key5", Name="name5"},
            };
            _contactAtr.ForEach(c => c.ContactAttributeValues.Add(new ContactAttributeValue() { Id = "value" + c.Id.Last() }));
        }

        [TestMethod()]
        public async Task ParseContactAttributes_ReturnExpectedValues()
        {
            _contactAttributeServiceMock.Setup(c => c.GetContactAttributeById(It.IsAny<string>())).Returns((string w) => Task.FromResult(_contactAtr.FirstOrDefault(a => a.Id.Equals(w))));
            var result = await _parser.ParseContactAttributes(customAtr);
            Assert.IsTrue(result.Count == 4);
            Assert.IsTrue(result.Any(c => c.Id.Equals("key1")));
            Assert.IsTrue(result.Any(c => c.Id.Equals("key2")));
            Assert.IsTrue(result.Any(c => c.Id.Equals("key3")));
            Assert.IsTrue(result.Any(c => c.Id.Equals("key4")));
            Assert.IsFalse(result.Any(c => c.Id.Equals("key5")));
        }

        [TestMethod()]
        public async Task ParseCustomer0AttributeValues_ReturnExpectedValues()
        {
            _contactAttributeServiceMock.Setup(c => c.GetContactAttributeById(It.IsAny<string>())).Returns((string w) => Task.FromResult(_contactAtr.FirstOrDefault(a => a.Id.Equals(w))));
            var result = await _parser.ParseContactAttributeValues(customAtr);
            Assert.IsTrue(result.Count == 3);
            Assert.IsTrue(result.Any(c => c.Id.Equals("value2")));
            Assert.IsTrue(result.Any(c => c.Id.Equals("value3")));
            Assert.IsTrue(result.Any(c => c.Id.Equals("value4")));
            Assert.IsFalse(result.Any(c => c.Id.Equals("value5")));
        }

        [TestMethod()]
        public void AddContactAttributeTest()
        {
            var result = _parser.AddContactAttribute(customAtr, new ContactAttribute() { Id = "key7" }, "value7");
            Assert.IsTrue(result.Count == 5);
            Assert.IsTrue(result.Any(c => c.Key.Equals("key7")));
        }

        [TestMethod()]
        public async Task IsConditionMetTest_IsConditionMet_True()
        {
            _contactAttributeServiceMock.Setup(c => c.GetContactAttributeById(It.IsAny<string>())).Returns((string w) => Task.FromResult(_contactAtr.FirstOrDefault(a => a.Id.Equals(w))));
            var contactAttribute = new ContactAttribute() { };
            contactAttribute.ConditionAttribute.Add(new CustomAttribute() { Key = "key2", Value = "2" });
            var result = await _parser.IsConditionMet(contactAttribute, new List<CustomAttribute>() { new CustomAttribute() { Key = "key2", Value = "2" } });
            Assert.IsTrue(result);
        }

        [TestMethod()]
        public async Task IsConditionMetTest_IsConditionMet_False()
        {
            _contactAttributeServiceMock.Setup(c => c.GetContactAttributeById(It.IsAny<string>())).Returns((string w) => Task.FromResult(_contactAtr.FirstOrDefault(a => a.Id.Equals(w))));
            var contactAttribute = new ContactAttribute() { };
            contactAttribute.ConditionAttribute.Add(new CustomAttribute() { Key = "key2", Value = "2" });
            var result = await _parser.IsConditionMet(contactAttribute, new List<CustomAttribute>() { new CustomAttribute() { Key = "key3", Value = "2" } });
            Assert.IsFalse(result);
        }

        [TestMethod()]
        public void RemoveContactAttributeTest()
        {
            var result = _parser.RemoveContactAttribute(customAtr, new ContactAttribute() { Id = "key1" });
            Assert.IsTrue(result.Count == 3);
            Assert.IsFalse(result.Any(c => c.Key.Equals("key1")));
        }

        [TestMethod()]
        public async Task FormatAttributesTest()
        {
            _contactAttributeServiceMock.Setup(c => c.GetAllContactAttributes("", false)).Returns(() => Task.FromResult((IList<ContactAttribute>)_contactAtr));
            _contactAttributeServiceMock.Setup(c => c.GetContactAttributeById(It.IsAny<string>())).Returns((string w) => Task.FromResult(_contactAtr.FirstOrDefault(a => a.Id.Equals(w))));
            var result = await _parser.FormatAttributes(new Domain.Localization.Language(),
                new List<CustomAttribute>() {
                    new CustomAttribute(){Key="key1",Value="value1" }
                }, new Customer());
            Assert.IsTrue(result == "name1: value1");
        }
    }
}