// EN: Inventory repository interface.
// VI: Interface repository Inventory.

using InventoryService.Domain.SeedWork;

namespace InventoryService.Domain.AggregatesModel.InventoryAggregate;

/// <summary>
/// EN: Repository interface for InventoryItem aggregate.
/// VI: Interface repository cho InventoryItem aggregate.
/// </summary>
public interface IInventoryRepository : IRepository<InventoryItem>
{
    /// <summary>
    /// EN: Add a new inventory item.
    /// VI: Thêm inventory item mới.
    /// </summary>
    InventoryItem Add(InventoryItem item);

    /// <summary>
    /// EN: Update an inventory item.
    /// VI: Cập nhật inventory item.
    /// </summary>
    void Update(InventoryItem item);

    /// <summary>
    /// EN: Get inventory item by ID.
    /// VI: Lấy inventory item theo ID.
    /// </summary>
    Task<InventoryItem?> GetByIdAsync(Guid id, CancellationToken cancellationToken = default);

    /// <summary>
    /// EN: Get inventory item by product ID and shop ID.
    /// VI: Lấy inventory item theo product ID và shop ID.
    /// </summary>
    Task<InventoryItem?> GetByProductAndShopAsync(Guid productId, Guid shopId, CancellationToken cancellationToken = default);

    /// <summary>
    /// EN: Get inventory item by product ID (old method for compatibility).
    /// VI: Lấy inventory item theo product ID (phương thức cũ cho tương thích).
    /// </summary>
    Task<InventoryItem?> GetByProductIdAsync(Guid productId, Guid shopId, CancellationToken cancellationToken = default);

    /// <summary>
    /// EN: Get all inventory items for a shop with pagination.
    /// VI: Lấy tất cả inventory items cho một shop với phân trang.
    /// </summary>
    Task<(IReadOnlyList<InventoryItem> Items, int Total)> GetByShopAsync(
        Guid shopId, 
        int skip = 0, 
        int take = 50, 
        CancellationToken cancellationToken = default);

    /// <summary>
    /// EN: Get all inventory items for a shop (old method for compatibility).
    /// VI: Lấy tất cả inventory items cho một shop (phương thức cũ cho tương thích).
    /// </summary>
    Task<IEnumerable<InventoryItem>> GetByShopIdAsync(Guid shopId, CancellationToken cancellationToken = default);

    /// <summary>
    /// EN: Get transactions for inventory item with pagination.
    /// VI: Lấy transactions cho inventory item với phân trang.
    /// </summary>
    Task<(IReadOnlyList<InventoryTransaction> Transactions, int Total)> GetTransactionsAsync(
        Guid inventoryItemId, 
        int skip = 0, 
        int take = 50, 
        CancellationToken cancellationToken = default);

    /// <summary>
    /// EN: Get low stock items (quantity &lt;= reorder level).
    /// VI: Lấy items stock thấp (quantity &lt;= reorder level).
    /// </summary>
    Task<(IReadOnlyList<InventoryItem> Items, int Total)> GetLowStockItemsAsync(
        Guid? shopId = null, 
        int skip = 0, 
        int take = 50, 
        CancellationToken cancellationToken = default);

    /// <summary>
    /// EN: Get all transactions for a shop with pagination.
    /// VI: Lấy tất cả transactions cho một shop với phân trang.
    /// </summary>
    Task<(IReadOnlyList<InventoryTransaction> Transactions, int Total)> GetTransactionsByShopAsync(
        Guid shopId,
        int skip = 0,
        int take = 50,
        CancellationToken cancellationToken = default);

    /// <summary>
    /// EN: Get inventory items by multiple product IDs and shop (for bulk stock check).
    /// VI: Lấy inventory items theo nhiều product IDs và shop (cho kiểm tra stock hàng loạt).
    /// </summary>
    Task<IReadOnlyList<InventoryItem>> GetByProductIdsAndShopAsync(
        Guid shopId,
        IEnumerable<Guid> productIds,
        CancellationToken cancellationToken = default);

    /// <summary>
    /// EN: Add inventory item asynchronously.
    /// VI: Thêm inventory item bất đồng bộ.
    /// </summary>
    Task<InventoryItem> AddAsync(InventoryItem item, CancellationToken cancellationToken = default);

    /// <summary>
    /// EN: Delete an inventory item.
    /// VI: Xóa một inventory item.
    /// </summary>
    void Delete(InventoryItem item);
}
