using Grand.Domain.Catalog;
using Grand.Domain.Media;
using Grand.Web.Vendor.Models.Catalog;

namespace Grand.Web.Vendor.Interfaces
{
    public interface IProductViewModelService
    {
        Task PrepareProductModel(ProductModel model, Product product, bool setPredefinedValues);
        Task PrepareProductReviewModel(ProductReviewModel model, ProductReview productReview, bool excludeProperties, bool formatReviewText);
        Task OutOfStockNotifications(Product product, int prevStockQuantity, List<ProductWarehouseInventory> prevMultiWarehouseStock);
        Task OutOfStockNotifications(Product product, ProductAttributeCombination combination, ProductAttributeCombination prevcombination);
        Task PrepareAddProductAttributeCombinationModel(ProductAttributeCombinationModel model, Product product);
        Task SaveProductWarehouseInventory(Product product, IList<ProductModel.ProductWarehouseInventoryModel> model);
        Task PrepareTierPriceModel(ProductModel.TierPriceModel model);
        Task PrepareProductAttributeValueModel(Product product, ProductModel.ProductAttributeValueModel model);
        Task<ProductListModel> PrepareProductListModel();
        Task<(IEnumerable<ProductModel> productModels, int totalCount)> PrepareProductsModel(ProductListModel model, int pageIndex, int pageSize);
        Task<IList<Product>> PrepareProducts(ProductListModel model);
        Task<Product> InsertProductModel(ProductModel model);
        Task<Product> UpdateProductModel(Product product, ProductModel model);
        Task DeleteProduct(Product product);
        Task DeleteSelected(IEnumerable<string> selectedIds);
        Task<ProductModel.AddRequiredProductModel> PrepareAddRequiredProductModel();
        Task<(IList<ProductModel> products, int totalCount)> PrepareProductModel(ProductModel.AddProductModel model, int pageIndex, int pageSize);
        Task<IList<ProductModel.ProductCategoryModel>> PrepareProductCategoryModel(Product product);
        Task InsertProductCategoryModel(ProductModel.ProductCategoryModel model);
        Task UpdateProductCategoryModel(ProductModel.ProductCategoryModel model);
        Task DeleteProductCategory(string id, string productId);
        Task<IList<ProductModel.ProductCollectionModel>> PrepareProductCollectionModel(Product product);
        Task InsertProductCollection(ProductModel.ProductCollectionModel model);
        Task UpdateProductCollection(ProductModel.ProductCollectionModel model);
        Task DeleteProductCollection(string id, string productId);
        Task InsertRelatedProductModel(ProductModel.AddRelatedProductModel model);
        Task UpdateRelatedProductModel(ProductModel.RelatedProductModel model);
        Task DeleteRelatedProductModel(ProductModel.RelatedProductModel model);
        Task InsertSimilarProductModel(ProductModel.AddSimilarProductModel model);
        Task UpdateSimilarProductModel(ProductModel.SimilarProductModel model);
        Task DeleteSimilarProductModel(ProductModel.SimilarProductModel model);
        Task InsertBundleProductModel(ProductModel.AddBundleProductModel model);
        Task UpdateBundleProductModel(ProductModel.BundleProductModel model);
        Task DeleteBundleProductModel(ProductModel.BundleProductModel model);
        Task InsertCrossSellProductModel(ProductModel.AddCrossSellProductModel model);
        Task DeleteCrossSellProduct(string productId, string crossSellProductId);
        Task InsertRecommendedProductModel(ProductModel.AddRecommendedProductModel model);
        Task DeleteRecommendedProduct(string productId, string recommendedProductId);
        Task InsertAssociatedProductModel(ProductModel.AddAssociatedProductModel model);
        Task DeleteAssociatedProduct(Product product);
        Task<ProductModel.AddRelatedProductModel> PrepareRelatedProductModel();
        Task<ProductModel.AddSimilarProductModel> PrepareSimilarProductModel();
        Task<ProductModel.AddBundleProductModel> PrepareBundleProductModel();
        Task<ProductModel.AddCrossSellProductModel> PrepareCrossSellProductModel();
        Task<ProductModel.AddRecommendedProductModel> PrepareRecommendedProductModel();
        Task<ProductModel.AddAssociatedProductModel> PrepareAssociatedProductModel();
        Task<BulkEditListModel> PrepareBulkEditListModel();
        Task<(IEnumerable<BulkEditProductModel> bulkEditProductModels, int totalCount)> PrepareBulkEditProductModel(BulkEditListModel model, int pageIndex, int pageSize);
        Task UpdateBulkEdit(IEnumerable<BulkEditProductModel> products);
        Task DeleteBulkEdit(IEnumerable<BulkEditProductModel> products);
        //tier-prices
        Task<IList<ProductModel.TierPriceModel>> PrepareTierPriceModel(Product product);
        Task<(IEnumerable<ProductModel.BidModel> bidModels, int totalCount)> PrepareBidMode(string productId, int pageIndex, int pageSize);
        Task<ProductModel.ProductAttributeMappingModel> PrepareProductAttributeMappingModel(Product product);
        Task<ProductModel.ProductAttributeMappingModel> PrepareProductAttributeMappingModel(ProductModel.ProductAttributeMappingModel model);
        Task<IList<ProductModel.ProductAttributeMappingModel>> PrepareProductAttributeMappingModels(Product product);
        Task InsertProductAttributeMappingModel(ProductModel.ProductAttributeMappingModel model);
        Task UpdateProductAttributeMappingModel(ProductModel.ProductAttributeMappingModel model);
        Task<ProductModel.ProductAttributeMappingModel> PrepareProductAttributeMappingModel(ProductAttributeMapping productAttributeMapping);
        Task UpdateProductAttributeValidationRulesModel(ProductAttributeMapping productAttributeMapping, ProductModel.ProductAttributeMappingModel model);
        Task<ProductAttributeConditionModel> PrepareProductAttributeConditionModel(Product product, ProductAttributeMapping productAttributeMapping);
        Task UpdateProductAttributeConditionModel(Product product, ProductAttributeMapping productAttributeMapping, ProductAttributeConditionModel model);
        Task<ProductModel.ProductAttributeValueModel> PrepareProductAttributeValueModel(Product product, ProductAttributeMapping productAttributeMapping);
        Task<IList<ProductModel.ProductAttributeValueModel>> PrepareProductAttributeValueModels(Product product, ProductAttributeMapping productAttributeMapping);
        Task<ProductModel.ProductAttributeValueModel> PrepareProductAttributeValueModel(ProductAttributeMapping pa, ProductAttributeValue pav);
        Task InsertProductAttributeValueModel(ProductModel.ProductAttributeValueModel model);
        Task UpdateProductAttributeValueModel(ProductAttributeValue pav, ProductModel.ProductAttributeValueModel model);
        Task<ProductModel.ProductAttributeValueModel.AssociateProductToAttributeValueModel> PrepareAssociateProductToAttributeValueModel();
        Task<IList<ProductModel.ProductAttributeCombinationModel>> PrepareProductAttributeCombinationModel(Product product);
        Task<ProductAttributeCombinationModel> PrepareProductAttributeCombinationModel(Product product, string combinationId);
        Task<IList<string>> InsertOrUpdateProductAttributeCombinationPopup(Product product, ProductAttributeCombinationModel model);
        Task GenerateAllAttributeCombinations(Product product);

        Task ClearAllAttributeCombinations(Product product);

        Task<IList<ProductModel.ProductAttributeCombinationTierPricesModel>> PrepareProductAttributeCombinationTierPricesModel(Product product, string productAttributeCombinationId);
        Task InsertProductAttributeCombinationTierPricesModel(Product product, ProductAttributeCombination productAttributeCombination, ProductModel.ProductAttributeCombinationTierPricesModel model);
        Task UpdateProductAttributeCombinationTierPricesModel(Product product, ProductAttributeCombination productAttributeCombination, ProductModel.ProductAttributeCombinationTierPricesModel model);
        Task DeleteProductAttributeCombinationTierPrices(Product product, ProductAttributeCombination productAttributeCombination, ProductCombinationTierPrices tierPrice);

        //Pictures
        Task<IList<ProductModel.ProductPictureModel>> PrepareProductPicturesModel(Product product);
        Task<(ProductModel.ProductPictureModel model, Picture Picture)> PrepareProductPictureModel(Product product, ProductPicture productPicture);
        Task InsertProductPicture(Product product, Picture picture, int displayOrder);
        Task UpdateProductPicture(ProductModel.ProductPictureModel model);
        Task DeleteProductPicture(ProductModel.ProductPictureModel model);

        //Product specification
        Task<IList<ProductSpecificationAttributeModel>> PrepareProductSpecificationAttributeModel(Product product);
        Task InsertProductSpecificationAttributeModel(ProductModel.AddProductSpecificationAttributeModel model, Product product);
        Task UpdateProductSpecificationAttributeModel(ProductSpecificationAttribute psa, ProductModel.AddProductSpecificationAttributeModel model);
        Task DeleteProductSpecificationAttribute(Product product, ProductSpecificationAttribute psa);
    }
}
