using Grand.Data.Tests.MongoDb;
using Grand.Domain.Catalog;
using Grand.Domain.Data;
using Grand.Domain.Discounts;
using Grand.Domain.Seo;
using Grand.Domain.Vendors;
using Grand.Infrastructure.Caching;
using Grand.Infrastructure.Tests.Caching;
using MediatR;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;

namespace Grand.Business.Catalog.Events.Handlers.Tests
{
    [TestClass()]
    public class DiscountDeletedEventHandlerTests
    {
        private IRepository<Product> _productRepository;
        private IRepository<Category> _categoryRepository;
        private IRepository<Brand> _brandRepository;
        private IRepository<Collection> _collectionRepository;
        private IRepository<Vendor> _vendorRepository;
        private IRepository<DiscountCoupon> _discountCouponRepository;
        private MemoryCacheBase _cacheBase;
        private Mock<IMediator> _mediatorMock;

        private DiscountDeletedEventHandler _handler;

        [TestInitialize()]
        public void Init()
        {
            _mediatorMock = new Mock<IMediator>();
            _productRepository = new MongoDBRepositoryTest<Product>();
            _categoryRepository = new MongoDBRepositoryTest<Category>();
            _brandRepository = new MongoDBRepositoryTest<Brand>();
            _collectionRepository = new MongoDBRepositoryTest<Collection>();
            _vendorRepository = new MongoDBRepositoryTest<Vendor>();
            _discountCouponRepository = new MongoDBRepositoryTest<DiscountCoupon>();
            _cacheBase = new MemoryCacheBase(MemoryCacheTest.Get(), _mediatorMock.Object);

            _handler = new DiscountDeletedEventHandler(_productRepository, _categoryRepository,
                _brandRepository, _collectionRepository, _vendorRepository, _discountCouponRepository, _cacheBase);
        }

        [TestMethod()]
        public async Task Handle_Product_Test()
        {
            //Arrange
            var discount = new Discount() { DiscountTypeId = DiscountType.AssignedToSkus };
            var product = new Product();
            product.AppliedDiscounts.Add(discount.Id);
            await _productRepository.InsertAsync(product);
            var product3 = new Product();
            product3.AppliedDiscounts.Add("1");
            await _productRepository.InsertAsync(product3);

            //Act
            await _handler.Handle(new Infrastructure.Events.EntityDeleted<Discount>(discount), CancellationToken.None);
            //Assert
            Assert.AreEqual(0, _productRepository.Table.Where(x => x.AppliedDiscounts.Contains(discount.Id)).Count());
            Assert.AreEqual(1, _productRepository.Table.Where(x => x.AppliedDiscounts.Contains("1")).Count());
        }
        [TestMethod()]
        public async Task Handle_Category_Test()
        {
            //Arrange
            var discount = new Discount() { DiscountTypeId = DiscountType.AssignedToCategories };
            var category = new Category();
            category.AppliedDiscounts.Add(discount.Id);
            await _categoryRepository.InsertAsync(category);
            var category3 = new Category();
            category3.AppliedDiscounts.Add("1");
            await _categoryRepository.InsertAsync(category3);

            //Act
            await _handler.Handle(new Infrastructure.Events.EntityDeleted<Discount>(discount), CancellationToken.None);
            //Assert
            Assert.AreEqual(0,_categoryRepository.Table.Where(x => x.AppliedDiscounts.Contains(discount.Id)).Count());
            Assert.AreEqual(1, _categoryRepository.Table.Where(x => x.AppliedDiscounts.Contains("1")).Count());
        }

        [TestMethod()]
        public async Task Handle_Collection_Test()
        {
            //Arrange
            var discount = new Discount() { DiscountTypeId = DiscountType.AssignedToCollections };
            var collection = new Collection();
            collection.AppliedDiscounts.Add(discount.Id);
            await _collectionRepository.InsertAsync(collection);
            var collection3 = new Collection();
            collection3.AppliedDiscounts.Add("1");
            await _collectionRepository.InsertAsync(collection3);

            //Act
            await _handler.Handle(new Infrastructure.Events.EntityDeleted<Discount>(discount), CancellationToken.None);
            //Assert
            Assert.AreEqual(0, _collectionRepository.Table.Where(x => x.AppliedDiscounts.Contains(discount.Id)).Count());
            Assert.AreEqual(1, _collectionRepository.Table.Where(x => x.AppliedDiscounts.Contains("1")).Count());
        }
        [TestMethod()]
        public async Task Handle_Vendor_Test()
        {
            //Arrange
            var discount = new Discount() { DiscountTypeId = DiscountType.AssignedToVendors };
            var vendor = new Vendor();
            vendor.AppliedDiscounts.Add(discount.Id);
            await _vendorRepository.InsertAsync(vendor);
            var vendor3 = new Vendor();
            vendor3.AppliedDiscounts.Add("1");
            await _vendorRepository.InsertAsync(vendor3);

            //Act
            await _handler.Handle(new Infrastructure.Events.EntityDeleted<Discount>(discount), CancellationToken.None);
            //Assert
            Assert.AreEqual(0, _vendorRepository.Table.Where(x => x.AppliedDiscounts.Contains(discount.Id)).Count());
            Assert.AreEqual(1, _vendorRepository.Table.Where(x => x.AppliedDiscounts.Contains("1")).Count());
        }
    }
}