using Grand.Business.Core.Interfaces.Common.Localization;
using Grand.Business.Core.Interfaces.Customers;
using Grand.Business.Customers.Services;
using Grand.Domain.Common;
using Grand.Domain.Customers;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;

namespace Grand.Business.Customers.Tests.Services
{
    [TestClass()]
    public class CustomerAttributeParserTests
    {
        private Mock<ICustomerAttributeService> _customerAtrServiceMock;
        private CustomerAttributeParser _parser;
        private List<CustomAttribute> customAtr;
        private List<CustomerAttribute> _customerAtr;

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

            _parser = new CustomerAttributeParser(_customerAtrServiceMock.Object, _translationServiceMock.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" },
            };

            _customerAtr = new List<CustomerAttribute>()
            {
                new CustomerAttribute(){Id="key1", Name="name1", AttributeControlTypeId = Domain.Catalog.AttributeControlType.TextBox},
                new CustomerAttribute(){Id="key2", Name="name2"},
                new CustomerAttribute(){Id="key3", Name="name3"},
                new CustomerAttribute(){Id="key4", Name="name4"},
                new CustomerAttribute(){Id="key5", Name="name5"},
            };
            _customerAtr.ForEach(c => c.CustomerAttributeValues.Add(new CustomerAttributeValue() { Id = "value" + c.Id.Last() }));
        }

        [TestMethod()]
        public async Task ParseCustomerAttributes_ReturnExpectedValues()
        {
            _customerAtrServiceMock.Setup(c => c.GetCustomerAttributeById(It.IsAny<string>())).Returns((string w) => Task.FromResult(_customerAtr.FirstOrDefault(a => a.Id.Equals(w))));
            var result = await _parser.ParseCustomerAttributes(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 ParseCustomerAttributes_ReturnEmptyList()
        {
            //not exist
            _customerAtrServiceMock.Setup(c => c.GetCustomerAttributeById(It.IsAny<string>())).Returns(() => Task.FromResult<CustomerAttribute>(null));
            var result = await _parser.ParseCustomerAttributes(customAtr);
            Assert.IsTrue(result.Count == 0);
        }

        [TestMethod()]
        public async Task ParseCustomer0AttributeValues_ReturnExpectedValues()
        {
            _customerAtrServiceMock.Setup(c => c.GetCustomerAttributeById(It.IsAny<string>())).Returns((string w) => Task.FromResult(_customerAtr.FirstOrDefault(a => a.Id.Equals(w))));
            var result = await _parser.ParseCustomerAttributeValues(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 AddCustomerAttribute_ReturnExpectedValues()
        {
            //not exist

            var result = _parser.AddCustomerAttribute(customAtr, new CustomerAttribute() { Id = "key7" }, "value7");
            Assert.IsTrue(result.Count == 5);
            Assert.IsTrue(result.Any(c => c.Key.Equals("key7")));
        }

        [TestMethod()]
        public async Task GetAttributeWarnings_Return_NoWarning()
        {
            _customerAtrServiceMock.Setup(c => c.GetAllCustomerAttributes()).Returns(() => Task.FromResult((IList<CustomerAttribute>)_customerAtr));
            _customerAtrServiceMock.Setup(c => c.GetCustomerAttributeById(It.IsAny<string>())).Returns((string w) => Task.FromResult(_customerAtr.FirstOrDefault(a => a.Id.Equals(w))));
            var result = await _parser.GetAttributeWarnings(customAtr);
            Assert.IsTrue(result.Count == 0);
        }
        [TestMethod()]
        public async Task GetAttributeWarnings_Return_WithWarning()
        {
            _customerAtr.FirstOrDefault(x=>x.Id == "key5").IsRequired = true;
            _customerAtrServiceMock.Setup(c => c.GetAllCustomerAttributes()).Returns(() => Task.FromResult((IList<CustomerAttribute>)_customerAtr));
            _customerAtrServiceMock.Setup(c => c.GetCustomerAttributeById(It.IsAny<string>())).Returns((string w) => Task.FromResult(_customerAtr.FirstOrDefault(a => a.Id.Equals(w))));
            var result = await _parser.GetAttributeWarnings(customAtr);
            Assert.IsTrue(result.Count == 1);
        }
        [TestMethod()]
        public async Task FormatAttributes_Return_string()
        {
            _customerAtrServiceMock.Setup(c => c.GetAllCustomerAttributes()).Returns(() => Task.FromResult((IList<CustomerAttribute>)_customerAtr));
            _customerAtrServiceMock.Setup(c => c.GetCustomerAttributeById(It.IsAny<string>())).Returns((string w) => Task.FromResult(_customerAtr.FirstOrDefault(a => a.Id.Equals(w))));
            var result = await _parser.FormatAttributes(new Domain.Localization.Language(),
                new List<CustomAttribute>() {
                    new CustomAttribute(){Key="key1",Value="value1" }
                });
            Assert.IsTrue(result == "name1: value1");
        }
    }
}
