using TakeoutSaaS.Domain.Products.Entities;
using TakeoutSaaS.Domain.Products.Enums;

namespace TakeoutSaaS.Domain.Products.Repositories;

/// <summary>
/// 商品聚合仓储契约。
/// </summary>
public interface IProductRepository
{
    /// <summary>
    /// 依据标识获取商品。
    /// </summary>
    Task<Product?> FindByIdAsync(long productId, long tenantId, CancellationToken cancellationToken = default);

    /// <summary>
    /// 按分类与状态筛选商品列表。
    /// </summary>
    Task<IReadOnlyList<Product>> SearchAsync(long tenantId, long? storeId, long? categoryId, ProductStatus? status, CancellationToken cancellationToken = default, DateTime? updatedAfter = null);

    /// <summary>
    /// 获取租户下的商品分类。
    /// </summary>
    Task<IReadOnlyList<ProductCategory>> GetCategoriesAsync(long tenantId, CancellationToken cancellationToken = default);

    /// <summary>
    /// 获取门店商品分类。
    /// </summary>
    Task<IReadOnlyList<ProductCategory>> GetCategoriesByStoreAsync(long tenantId, long storeId, bool onlyEnabled = true, CancellationToken cancellationToken = default);

    /// <summary>
    /// 获取商品 SKU。
    /// </summary>
    Task<IReadOnlyList<ProductSku>> GetSkusAsync(long productId, long tenantId, CancellationToken cancellationToken = default);

    /// <summary>
    /// 批量获取商品 SKU。
    /// </summary>
    Task<IReadOnlyList<ProductSku>> GetSkusByProductIdsAsync(IReadOnlyCollection<long> productIds, long tenantId, CancellationToken cancellationToken = default);

    /// <summary>
    /// 获取商品加料组与选项。
    /// </summary>
    /// <param name="productId">商品 ID。</param>
    /// <param name="tenantId">租户 ID。</param>
    /// <param name="cancellationToken">取消标记。</param>
    /// <returns>加料组集合。</returns>
    Task<IReadOnlyList<ProductAddonGroup>> GetAddonGroupsAsync(long productId, long tenantId, CancellationToken cancellationToken = default);

    /// <summary>
    /// 批量获取商品加料组。
    /// </summary>
    Task<IReadOnlyList<ProductAddonGroup>> GetAddonGroupsByProductIdsAsync(IReadOnlyCollection<long> productIds, long tenantId, CancellationToken cancellationToken = default);

    /// <summary>
    /// 获取商品加料选项。
    /// </summary>
    /// <param name="productId">商品 ID。</param>
    /// <param name="tenantId">租户 ID。</param>
    /// <param name="cancellationToken">取消标记。</param>
    /// <returns>加料选项集合。</returns>
    Task<IReadOnlyList<ProductAddonOption>> GetAddonOptionsAsync(long productId, long tenantId, CancellationToken cancellationToken = default);

    /// <summary>
    /// 批量获取商品加料选项。
    /// </summary>
    Task<IReadOnlyList<ProductAddonOption>> GetAddonOptionsByGroupIdsAsync(IReadOnlyCollection<long> addonGroupIds, long tenantId, CancellationToken cancellationToken = default);

    /// <summary>
    /// 获取商品规格组与选项。
    /// </summary>
    /// <param name="productId">商品 ID。</param>
    /// <param name="tenantId">租户 ID。</param>
    /// <param name="cancellationToken">取消标记。</param>
    /// <returns>规格组集合。</returns>
    Task<IReadOnlyList<ProductAttributeGroup>> GetAttributeGroupsAsync(long productId, long tenantId, CancellationToken cancellationToken = default);

    /// <summary>
    /// 批量获取商品规格组。
    /// </summary>
    Task<IReadOnlyList<ProductAttributeGroup>> GetAttributeGroupsByProductIdsAsync(IReadOnlyCollection<long> productIds, long tenantId, CancellationToken cancellationToken = default);

    /// <summary>
    /// 获取商品规格选项。
    /// </summary>
    /// <param name="productId">商品 ID。</param>
    /// <param name="tenantId">租户 ID。</param>
    /// <param name="cancellationToken">取消标记。</param>
    /// <returns>规格选项集合。</returns>
    Task<IReadOnlyList<ProductAttributeOption>> GetAttributeOptionsAsync(long productId, long tenantId, CancellationToken cancellationToken = default);

    /// <summary>
    /// 批量获取商品规格选项。
    /// </summary>
    Task<IReadOnlyList<ProductAttributeOption>> GetAttributeOptionsByGroupIdsAsync(IReadOnlyCollection<long> attributeGroupIds, long tenantId, CancellationToken cancellationToken = default);

    /// <summary>
    /// 获取商品媒资。
    /// </summary>
    /// <param name="productId">商品 ID。</param>
    /// <param name="tenantId">租户 ID。</param>
    /// <param name="cancellationToken">取消标记。</param>
    /// <returns>媒资列表。</returns>
    Task<IReadOnlyList<ProductMediaAsset>> GetMediaAssetsAsync(long productId, long tenantId, CancellationToken cancellationToken = default);

    /// <summary>
    /// 批量获取商品媒资。
    /// </summary>
    Task<IReadOnlyList<ProductMediaAsset>> GetMediaAssetsByProductIdsAsync(IReadOnlyCollection<long> productIds, long tenantId, CancellationToken cancellationToken = default);

    /// <summary>
    /// 获取商品定价规则。
    /// </summary>
    /// <param name="productId">商品 ID。</param>
    /// <param name="tenantId">租户 ID。</param>
    /// <param name="cancellationToken">取消标记。</param>
    /// <returns>定价规则集合。</returns>
    Task<IReadOnlyList<ProductPricingRule>> GetPricingRulesAsync(long productId, long tenantId, CancellationToken cancellationToken = default);

    /// <summary>
    /// 批量获取商品定价规则。
    /// </summary>
    Task<IReadOnlyList<ProductPricingRule>> GetPricingRulesByProductIdsAsync(IReadOnlyCollection<long> productIds, long tenantId, CancellationToken cancellationToken = default);

    /// <summary>
    /// 新增分类。
    /// </summary>
    /// <param name="category">分类实体。</param>
    /// <param name="cancellationToken">取消标记。</param>
    /// <returns>异步任务。</returns>
    Task AddCategoryAsync(ProductCategory category, CancellationToken cancellationToken = default);

    /// <summary>
    /// 新增商品。
    /// </summary>
    /// <param name="product">商品实体。</param>
    /// <param name="cancellationToken">取消标记。</param>
    /// <returns>异步任务。</returns>
    Task AddProductAsync(Product product, CancellationToken cancellationToken = default);

    /// <summary>
    /// 新增 SKU。
    /// </summary>
    /// <param name="skus">SKU 集合。</param>
    /// <param name="cancellationToken">取消标记。</param>
    /// <returns>异步任务。</returns>
    Task AddSkusAsync(IEnumerable<ProductSku> skus, CancellationToken cancellationToken = default);

    /// <summary>
    /// 新增加料组与选项。
    /// </summary>
    /// <param name="groups">加料组集合。</param>
    /// <param name="options">加料选项集合。</param>
    /// <param name="cancellationToken">取消标记。</param>
    /// <returns>异步任务。</returns>
    Task AddAddonGroupsAsync(IEnumerable<ProductAddonGroup> groups, IEnumerable<ProductAddonOption> options, CancellationToken cancellationToken = default);

    /// <summary>
    /// 新增规格组与选项。
    /// </summary>
    /// <param name="groups">规格组集合。</param>
    /// <param name="options">规格选项集合。</param>
    /// <param name="cancellationToken">取消标记。</param>
    /// <returns>异步任务。</returns>
    Task AddAttributeGroupsAsync(IEnumerable<ProductAttributeGroup> groups, IEnumerable<ProductAttributeOption> options, CancellationToken cancellationToken = default);

    /// <summary>
    /// 新增媒资。
    /// </summary>
    /// <param name="assets">媒资集合。</param>
    /// <param name="cancellationToken">取消标记。</param>
    /// <returns>异步任务。</returns>
    Task AddMediaAssetsAsync(IEnumerable<ProductMediaAsset> assets, CancellationToken cancellationToken = default);

    /// <summary>
    /// 新增定价规则。
    /// </summary>
    /// <param name="rules">定价规则集合。</param>
    /// <param name="cancellationToken">取消标记。</param>
    /// <returns>异步任务。</returns>
    Task AddPricingRulesAsync(IEnumerable<ProductPricingRule> rules, CancellationToken cancellationToken = default);

    /// <summary>
    /// 持久化变更。
    /// </summary>
    /// <param name="cancellationToken">取消标记。</param>
    /// <returns>异步任务。</returns>
    Task SaveChangesAsync(CancellationToken cancellationToken = default);

    /// <summary>
    /// 更新商品。
    /// </summary>
    /// <param name="product">商品实体。</param>
    /// <param name="cancellationToken">取消标记。</param>
    /// <returns>异步任务。</returns>
    Task UpdateProductAsync(Product product, CancellationToken cancellationToken = default);

    /// <summary>
    /// 删除商品。
    /// </summary>
    /// <param name="productId">商品 ID。</param>
    /// <param name="tenantId">租户 ID。</param>
    /// <param name="cancellationToken">取消标记。</param>
    /// <returns>异步任务。</returns>
    Task DeleteProductAsync(long productId, long tenantId, CancellationToken cancellationToken = default);

    /// <summary>
    /// 更新分类。
    /// </summary>
    /// <param name="category">分类实体。</param>
    /// <param name="cancellationToken">取消标记。</param>
    /// <returns>异步任务。</returns>
    Task UpdateCategoryAsync(ProductCategory category, CancellationToken cancellationToken = default);

    /// <summary>
    /// 删除分类。
    /// </summary>
    /// <param name="categoryId">分类 ID。</param>
    /// <param name="tenantId">租户 ID。</param>
    /// <param name="cancellationToken">取消标记。</param>
    /// <returns>异步任务。</returns>
    Task DeleteCategoryAsync(long categoryId, long tenantId, CancellationToken cancellationToken = default);

    /// <summary>
    /// 删除商品下的 SKU。
    /// </summary>
    /// <param name="productId">商品 ID。</param>
    /// <param name="tenantId">租户 ID。</param>
    /// <param name="cancellationToken">取消标记。</param>
    /// <returns>异步任务。</returns>
    Task RemoveSkusAsync(long productId, long tenantId, CancellationToken cancellationToken = default);

    /// <summary>
    /// 删除商品下的加料组及选项。
    /// </summary>
    /// <param name="productId">商品 ID。</param>
    /// <param name="tenantId">租户 ID。</param>
    /// <param name="cancellationToken">取消标记。</param>
    /// <returns>异步任务。</returns>
    Task RemoveAddonGroupsAsync(long productId, long tenantId, CancellationToken cancellationToken = default);

    /// <summary>
    /// 删除商品下的规格组及选项。
    /// </summary>
    /// <param name="productId">商品 ID。</param>
    /// <param name="tenantId">租户 ID。</param>
    /// <param name="cancellationToken">取消标记。</param>
    /// <returns>异步任务。</returns>
    Task RemoveAttributeGroupsAsync(long productId, long tenantId, CancellationToken cancellationToken = default);

    /// <summary>
    /// 删除商品媒资。
    /// </summary>
    /// <param name="productId">商品 ID。</param>
    /// <param name="tenantId">租户 ID。</param>
    /// <param name="cancellationToken">取消标记。</param>
    /// <returns>异步任务。</returns>
    Task RemoveMediaAssetsAsync(long productId, long tenantId, CancellationToken cancellationToken = default);

    /// <summary>
    /// 删除商品定价规则。
    /// </summary>
    /// <param name="productId">商品 ID。</param>
    /// <param name="tenantId">租户 ID。</param>
    /// <param name="cancellationToken">取消标记。</param>
    /// <returns>异步任务。</returns>
    Task RemovePricingRulesAsync(long productId, long tenantId, CancellationToken cancellationToken = default);
}
