using Nop.Core.Caching;

namespace Nop.Services.Catalog;

/// <summary>
/// Represents default values related to catalog services
/// </summary>
public static partial class NopCatalogDefaults
{
    #region Common

    /// <summary>
    /// Gets a default price range 'from'
    /// </summary>
    public static decimal DefaultPriceRangeFrom => 0;

    /// <summary>
    /// Gets a default price range 'to'
    /// </summary>
    public static decimal DefaultPriceRangeTo => 10000;

    #endregion

    #region Products

    /// <summary>
    /// Gets a template of product name on copying
    /// </summary>
    /// <remarks>
    /// {0} : product name
    /// </remarks>
    public static string ProductCopyNameTemplate => "Copy of {0}";

    /// <summary>
    /// Gets default prefix for product
    /// </summary>
    public static string ProductAttributePrefix => "product_attribute_";

    #endregion

    #region Caching defaults

    #region Categories

    /// <summary>
    /// Gets a key for caching
    /// </summary>
    /// <remarks>
    /// {0} : parent category ID
    /// {1} : show hidden records?
    /// {2} : roles of the current user
    /// {3} : store ID
    /// </remarks>
    public static CacheKey CategoriesByParentCategoryCacheKey => new("Nop.category.byparent.{0}-{1}-{2}-{3}");

    /// <summary>
    /// Gets a key pattern to clear cache
    /// </summary>
    /// <remarks>
    /// {0} : parent category ID
    /// </remarks>
    public static string CategoriesByParentCategoryPrefix => "Nop.category.byparent.{0}";

    /// <summary>
    /// Gets a key for caching
    /// </summary>
    /// <remarks>
    /// {0} : parent category id
    /// {1} : roles of the current user
    /// {2} : current store ID
    /// {3} : show hidden records?
    /// </remarks>
    public static CacheKey CategoriesChildIdsCacheKey => new("Nop.category.childids.{0}-{1}-{2}-{3}");

    /// <summary>
    /// Gets a key pattern to clear cache
    /// </summary>
    /// <remarks>
    /// {0} : parent category ID
    /// </remarks>
    public static string CategoriesChildIdsPrefix => "Nop.category.childids.{0}";

    /// <summary>
    /// Gets a key for caching
    /// </summary>
    /// <remarks>
    /// {0} : current store ID
    /// {1} : show hidden records?
    /// </remarks>
    public static CacheKey ChildCategoryIdLookupCacheKey => new("Nop.childcategoryidlookup.bystore.{0}-{1}");

    /// <summary>
    /// Gets a key pattern to clear cache
    /// </summary>
    public static string ChildCategoryIdLookupPrefix => "Nop.childcategoryidlookup.";

    /// <summary>
    /// Gets a key pattern to clear cache
    /// </summary>
    public static string ChildCategoryIdLookupByStorePrefix => "Nop.childcategoryidlookup.bystore.{0}";

    /// <summary>
    /// Gets a key for caching
    /// </summary>
    public static CacheKey CategoriesHomepageCacheKey => new("Nop.category.homepage.");

    /// <summary>
    /// Gets a key for caching
    /// </summary>
    /// <remarks>
    /// {0} : current store ID
    /// {1} : roles of the current user
    /// </remarks>
    public static CacheKey CategoriesHomepageWithoutHiddenCacheKey => new("Nop.category.homepage.withouthidden-{0}-{1}");

    /// <summary>
    /// Gets a key pattern to clear cache
    /// </summary>
    public static string CategoriesHomepagePrefix => "Nop.category.homepage.";

    /// <summary>
    /// Key for caching of category breadcrumb
    /// </summary>
    /// <remarks>
    /// {0} : category id
    /// {1} : roles of the current user
    /// {2} : current store ID
    /// {3} : language ID
    /// {4} : show hidden records?
    /// </remarks>
    public static CacheKey CategoryBreadcrumbCacheKey => new("Nop.category.breadcrumb.{0}-{1}-{2}-{3}-{4}");

    /// <summary>
    /// Gets a key pattern to clear cache
    /// </summary>
    public static string CategoryBreadcrumbPrefix => "Nop.category.breadcrumb.";

    /// <summary>
    /// Gets a key for caching
    /// </summary>
    /// <remarks>
    /// {0} : current store ID
    /// {1} : roles of the current user
    /// {2} : show hidden records?
    /// </remarks>
    public static CacheKey CategoriesAllCacheKey => new("Nop.category.all.{0}-{1}-{2}");

    /// <summary>
    /// Gets a key for caching
    /// </summary>
    /// <remarks>
    /// {0} : product ID
    /// {1} : show hidden records?
    /// {2} : roles of the current user
    /// {3} : store ID
    /// </remarks>
    public static CacheKey ProductCategoriesByProductCacheKey => new("Nop.productcategory.byproduct.{0}-{1}-{2}-{3}");

    /// <summary>
    /// Gets a key pattern to clear cache
    /// </summary>
    public static string ProductCategoriesByProductPrefix => "Nop.productcategory.byproduct.{0}";

    /// <summary>
    /// Gets a key pattern to clear cache
    /// </summary>
    public static string ProductCategoriesByProductWithoutIdPrefix => "Nop.productcategory.byproduct.";
    
    /// <summary>
    /// Key for caching
    /// </summary>
    /// <remarks>
    /// {0} : customer roles ID hash
    /// {1} : current store ID
    /// {2} : categories ID hash
    /// </remarks>
    public static CacheKey CategoryProductsNumberCacheKey => new("Nop.productcategory.products.number.{0}-{1}-{2}");

    /// <summary>
    /// Gets a key pattern to clear cache
    /// </summary>
    public static string CategoryProductsNumberPrefix => "Nop.productcategory.products.number.";

    #endregion

    #region Manufacturers

    /// <summary>
    /// Gets a key for caching
    /// </summary>
    /// <remarks>
    /// {0} : product ID
    /// {1} : show hidden records?
    /// {2} : roles of the current user
    /// {3} : store ID
    /// </remarks>
    public static CacheKey ProductManufacturersByProductCacheKey => new("Nop.productmanufacturer.byproduct.{0}-{1}-{2}-{3}");

    /// <summary>
    /// Gets a key pattern to clear cache
    /// </summary>
    public static string ProductManufacturersPrefix => "Nop.productmanufacturer.";

    /// <summary>
    /// Gets a key pattern to clear cache
    /// </summary>
    /// <remarks>
    /// {0} : product ID
    /// </remarks>
    public static string ProductManufacturersByProductPrefix => "Nop.productmanufacturer.byproduct.{0}";

    /// <summary>
    /// Gets a key for caching
    /// </summary>
    /// <remarks>
    /// {0} : category ID
    /// {1} : store ID
    /// {2} : customer role Ids
    /// </remarks>
    public static CacheKey ManufacturersByCategoryCacheKey => new("Nop.manufacturer.bycategory.{0}.{1}.{2}");

    /// <summary>
    /// Gets a key pattern to clear cache
    /// </summary>
    public static string ManufacturersByCategoryPrefix => "Nop.manufacturer.bycategory.";

    /// <summary>
    /// Gets a key pattern to clear cache
    /// </summary>
    public static string ManufacturersByCategoryWithIdPrefix => "Nop.manufacturer.bycategory.{0}.";

    #endregion

    #region Products

    /// <summary>
    /// Key for "related" product displayed on the product details page
    /// </summary>
    /// <remarks>
    /// {0} : current product id
    /// {1} : show hidden records?
    /// </remarks>
    public static CacheKey RelatedProductsCacheKey => new("Nop.relatedproduct.byproduct.{0}-{1}");

    /// <summary>
    /// Gets a key pattern to clear cache
    /// </summary>
    /// <remarks>
    /// {0} : product ID
    /// </remarks>
    public static string RelatedProductsPrefix => "Nop.relatedproduct.byproduct.{0}";

    /// <summary>
    /// Key for "related" product identifiers displayed on the product details page
    /// </summary>
    /// <remarks>
    /// {0} : current product id
    /// </remarks>
    public static CacheKey TierPricesByProductCacheKey => new("Nop.tierprice.byproduct.{0}");

    /// <summary>
    /// Gets a key for caching
    /// </summary>
    public static CacheKey ProductsHomepageCacheKey => new("Nop.product.homepage.");

    /// <summary>
    /// Key for caching identifiers of category featured products
    /// </summary>
    /// <remarks>
    /// {0} : category id
    /// {1} : customer role Ids
    /// {2} : current store ID
    /// </remarks>
    public static CacheKey CategoryFeaturedProductsIdsKey => new("Nop.product.featured.bycategory.{0}-{1}-{2}");
    public static string CategoryFeaturedProductsIdsPrefix => "Nop.product.featured.bycategory.{0}";

    /// <summary>
    /// Key for caching of a value indicating whether a manufacturer has featured products
    /// </summary>
    /// <remarks>
    /// {0} : manufacturer id
    /// {1} : customer role Ids
    /// {2} : current store ID
    /// </remarks>
    public static CacheKey ManufacturerFeaturedProductIdsKey => new("Nop.product.featured.bymanufacturer.{0}-{1}-{2}");
    public static string ManufacturerFeaturedProductIdsPrefix => "Nop.product.featured.bymanufacturer.{0}";

    public static string FeaturedProductIdsPrefix => "Nop.product.featured.";

    /// <summary>
    /// Gets a key for product prices
    /// </summary>
    /// <remarks>
    /// {0} : product id
    /// {1} : overridden product price
    /// {2} : additional charge
    /// {3} : include discounts (true, false)
    /// {4} : quantity
    /// {5} : roles of the current user
    /// {6} : current store ID
    /// </remarks>
    public static CacheKey ProductPriceCacheKey => new("Nop.totals.productprice.{0}-{1}-{2}-{3}-{4}-{5}-{6}");

    /// <summary>
    /// Gets a key pattern to clear cache
    /// </summary>
    /// <remarks>
    /// {0} : product id
    /// </remarks>
    public static string ProductPricePrefix => "Nop.totals.productprice.{0}";

    /// <summary>
    /// Gets a key for product multiple prices
    /// </summary>
    /// <remarks>
    /// {0} : product id
    /// {1} : customer role ids
    /// {2} : store id
    /// </remarks>
    public static CacheKey ProductMultiplePriceCacheKey => new("Nop.totals.productprice.multiple.{0}-{1}-{2}");

    /// <summary>
    /// Gets a key pattern to clear cache
    /// </summary>
    /// <remarks>
    /// {0} : product id
    /// </remarks>
    public static string ProductMultiplePricePrefix => "Nop.totals.productprice.multiple.{0}";

    #endregion

    #region Product attributes

    /// <summary>
    /// Gets a key for caching
    /// </summary>
    /// <remarks>
    /// {0} : product ID
    /// </remarks>
    public static CacheKey ProductAttributeMappingsByProductCacheKey => new("Nop.productattributemapping.byproduct.{0}");

    /// <summary>
    /// Gets a key pattern to clear cache
    /// </summary>
    /// <remarks>
    /// </remarks>
    public static string ProductAttributeMappingsByProductPrefix => new("Nop.productattributemapping.byproduct.");

    /// <summary>
    /// Gets a key for caching
    /// </summary>
    /// <remarks>
    /// {0} : product attribute mapping ID
    /// </remarks>
    public static CacheKey ProductAttributeValuesByAttributeCacheKey => new("Nop.productattributevalue.byattribute.{0}");

    /// <summary>
    /// Gets a key for caching
    /// </summary>
    /// <remarks>
    /// {0} : product ID
    /// </remarks>
    public static CacheKey ProductAttributeCombinationsByProductCacheKey => new("Nop.productattributecombination.byproduct.{0}");

    /// <summary>
    /// Gets a key for caching
    /// </summary>
    /// <remarks>
    /// {0} : Product attribute ID
    /// </remarks>
    public static CacheKey PredefinedProductAttributeValuesByAttributeCacheKey => new("Nop.predefinedproductattributevalue.byattribute.{0}");

    /// <summary>
    /// Gets a key for caching
    /// </summary>
    /// <remarks>
    /// {0} : combination ID
    /// </remarks>
    public static CacheKey ProductAttributeCombinationPicturesByCombinationCacheKey => new("Nop.productattributecombinationpicture.bycombination.{0}");

    /// <summary>
    /// Gets a key for caching
    /// </summary>
    /// <remarks>
    /// {0} : value ID
    /// </remarks>
    public static CacheKey ProductAttributeValuePicturesByValueCacheKey => new("Nop.productattributevaluepicture.byvalue.{0}");

    #endregion

    #region Product tags

    /// <summary>
    /// Gets a key for caching
    /// </summary>
    /// <remarks>
    /// {0} : store ID
    /// {1} : hash of list of customer roles IDs
    /// {2} : show hidden records?
    /// </remarks>
    public static CacheKey ProductTagCountCacheKey => new("Nop.producttag.count.{0}-{1}-{2}");

    /// <summary>
    /// Gets a key for caching
    /// </summary>
    /// <remarks>
    /// {0} : product ID
    /// </remarks>
    public static CacheKey ProductTagsByProductCacheKey => new("Nop.producttag.byproduct.{0}");

    #endregion

    #region Review type

    /// <summary>
    /// Key for caching product review and review type mapping
    /// </summary>
    /// <remarks>
    /// {0} : product review ID
    /// </remarks>
    public static CacheKey ProductReviewTypeMappingByReviewIdCacheKey => new("Nop.productreviewreviewtypemapping.byreviewid.{0}");

    /// <summary>
    /// Gets a key pattern to clear cache
    /// </summary>
    /// <remarks>
    /// </remarks>
    public static string ProductReviewTypeMappingByReviewIdPrefix => new("Nop.productreviewreviewtypemapping.byreviewid.");

    #endregion

    #region Specification attributes

    /// <summary>
    /// Gets a key for caching
    /// </summary>
    /// <remarks>
    /// {0} : product ID
    /// {1} : specification attribute option ID
    /// {2} : allow filtering
    /// {3} : show on product page
    /// {4} : specification attribute group ID
    /// </remarks>
    public static CacheKey ProductSpecificationAttributeByProductCacheKey => new("Nop.productspecificationattribute.byproduct.{0}-{1}-{2}-{3}-{4}");

    /// <summary>
    /// Gets a key pattern to clear cache
    /// </summary>
    /// <remarks>
    /// {0} : product ID
    /// </remarks>
    public static string ProductSpecificationAttributeByProductPrefix => "Nop.productspecificationattribute.byproduct.{0}";

    /// <summary>
    /// Gets a key pattern to clear cache
    /// </summary>
    /// <remarks>
    /// {1} (not 0, see the <ref>ProductSpecificationAttributeAllByProductIdCacheKey</ref>) :specification attribute option ID
    /// </remarks>
    public static string ProductSpecificationAttributeAllByProductPrefix => "Nop.productspecificationattribute.byproduct.";

    /// <summary>
    /// Key for specification attributes caching (product details page)
    /// </summary>
    public static CacheKey SpecificationAttributesWithOptionsCacheKey => new("Nop.specificationattribute.withoptions.");

    /// <summary>
    /// Key for specification attributes caching
    /// </summary>
    /// <remarks>
    /// {0} : specification attribute ID
    /// </remarks>
    public static CacheKey SpecificationAttributeOptionsCacheKey => new("Nop.specificationattributeoption.byattribute.{0}");

    /// <summary>
    /// Key for specification attribute options by category ID caching
    /// </summary>
    /// <remarks>
    /// {0} : category ID
    /// </remarks>
    public static CacheKey SpecificationAttributeOptionsByCategoryCacheKey => new("Nop.specificationattributeoption.bycategory.{0}");

    /// <summary>
    /// Key for specification attribute options by manufacturer ID caching
    /// </summary>
    /// <remarks>
    /// {0} : manufacturer ID
    /// </remarks>
    public static CacheKey SpecificationAttributeOptionsByManufacturerCacheKey => new("Nop.specificationattributeoption.bymanufacturer.{0}");

    /// <summary>
    /// Gets a key pattern to clear cache
    /// </summary>
    public static string FilterableSpecificationAttributeOptionsPrefix => "Nop.specificationattributeoption";

    /// <summary>
    /// Gets a key for specification attribute groups caching by product id
    /// </summary>
    /// <remarks>
    /// {0} : product ID
    /// </remarks>
    public static CacheKey SpecificationAttributeGroupByProductCacheKey => new("Nop.specificationattributegroup.byproduct.{0}");

    /// <summary>
    /// Gets a key pattern to clear cache
    /// </summary>
    public static string SpecificationAttributeGroupByProductPrefix => "Nop.specificationattributegroup.byproduct.";

    #endregion

    #endregion
}