using CMSMicroservice.Domain.Entities;
using CMSMicroservice.Domain.Enums;

namespace CMSMicroservice.Application.Common.Interfaces;

/// <summary>
/// سرویس مدیریت موجودی - لایه بالاتر برای عملیات business
/// این سرویس مسئول همگام‌سازی موجودی بین InventoryItem و Product.RemainingCount است
/// </summary>
public interface IInventoryService
{
    #region Initialization
    
    /// <summary>
    /// ایجاد رکورد موجودی برای محصول جدید
    /// این متد باید در CreateProductCommandHandler و CreateDiscountProductCommandHandler فراخوانی شود
    /// </summary>
    /// <param name="productId">شناسه محصول (Product.Id یا DiscountProduct.Id)</param>
    /// <param name="productType">نوع محصول (RegularProduct یا DiscountProduct)</param>
    /// <param name="initialQuantity">موجودی اولیه</param>
    /// <param name="warehouseId">شناسه انبار (پیش‌فرض: انبار اصلی)</param>
    /// <param name="lowStockThreshold">آستانه هشدار کم‌موجودی</param>
    /// <param name="ct">CancellationToken</param>
    /// <returns>شناسه InventoryItem ایجاد شده</returns>
    Task<long> InitializeInventoryAsync(
        long productId,
        ProductType productType,
        int initialQuantity,
        long? warehouseId = null,
        int lowStockThreshold = 10,
        CancellationToken ct = default);
    
    #endregion
    
    #region Query Operations
    
    /// <summary>
    /// دریافت موجودی یک محصول
    /// </summary>
    Task<InventoryItem?> GetInventoryAsync(
        long productId, 
        ProductType productType, 
        long? warehouseId = null,
        CancellationToken ct = default);
    
    /// <summary>
    /// دریافت موجودی قابل فروش (Quantity - ReservedQuantity)
    /// </summary>
    Task<int> GetAvailableQuantityAsync(
        long productId, 
        ProductType productType, 
        long? warehouseId = null,
        CancellationToken ct = default);
    
    /// <summary>
    /// بررسی اینکه آیا موجودی کافی برای فروش وجود دارد
    /// </summary>
    Task<bool> CheckAvailabilityAsync(
        long productId, 
        ProductType productType, 
        int requiredQuantity,
        long? warehouseId = null,
        CancellationToken ct = default);
    
    /// <summary>
    /// دریافت لیست محصولات کم‌موجود
    /// </summary>
    Task<List<InventoryItem>> GetLowStockItemsAsync(
        ProductType? productType = null, 
        long? warehouseId = null,
        int count = 50,
        CancellationToken ct = default);
    
    /// <summary>
    /// دریافت تاریخچه حرکات موجودی
    /// </summary>
    Task<List<StockMovement>> GetStockMovementsAsync(
        long productId, 
        ProductType productType,
        DateTime? fromDate = null,
        DateTime? toDate = null,
        CancellationToken ct = default);
    
    #endregion
    
    #region Order Flow Operations
    
    /// <summary>
    /// رزرو موجودی برای سفارش pending
    /// این متد در PlaceOrderCommandHandler فراخوانی می‌شود
    /// فقط ReservedQuantity را افزایش می‌دهد، Quantity تغییر نمی‌کند
    /// </summary>
    /// <param name="productId">شناسه محصول</param>
    /// <param name="productType">نوع محصول</param>
    /// <param name="quantity">تعداد رزرو</param>
    /// <param name="orderId">شناسه سفارش (Order.Id یا DiscountOrder.Id)</param>
    /// <param name="ct">CancellationToken</param>
    /// <returns>true اگر رزرو موفق بود</returns>
    Task<bool> ReserveStockAsync(
        long productId, 
        ProductType productType, 
        int quantity, 
        long? orderId = null,
        CancellationToken ct = default);
    
    /// <summary>
    /// آزادسازی رزرو (لغو سفارش یا timeout)
    /// این متد در CancelOrderCommandHandler فراخوانی می‌شود
    /// </summary>
    Task<bool> ReleaseReservationAsync(
        long productId, 
        ProductType productType, 
        int quantity, 
        long? orderId = null,
        CancellationToken ct = default);
    
    /// <summary>
    /// تایید فروش - کسر واقعی موجودی
    /// این متد در CompleteOrderPaymentCommandHandler فراخوانی می‌شود
    /// ReservedQuantity کاهش می‌یابد، Quantity کاهش می‌یابد، Product.RemainingCount sync می‌شود
    /// </summary>
    Task<bool> ConfirmSaleAsync(
        long productId, 
        ProductType productType, 
        int quantity, 
        long? orderId = null,
        CancellationToken ct = default);
    
    #endregion
    
    #region Stock Management Operations
    
    /// <summary>
    /// ورود کالا به انبار (Restock)
    /// </summary>
    /// <param name="productId">شناسه محصول</param>
    /// <param name="productType">نوع محصول</param>
    /// <param name="quantity">تعداد ورودی</param>
    /// <param name="referenceNumber">شماره مرجع (مثل شماره فاکتور خرید)</param>
    /// <param name="note">یادداشت</param>
    /// <param name="performedByUserId">شناسه کاربر انجام‌دهنده</param>
    /// <param name="ct">CancellationToken</param>
    Task<bool> AddStockAsync(
        long productId, 
        ProductType productType, 
        int quantity,
        string? referenceNumber = null,
        string? note = null,
        long? performedByUserId = null,
        CancellationToken ct = default);
    
    /// <summary>
    /// تعدیل موجودی (تنظیم به مقدار جدید)
    /// </summary>
    Task<bool> AdjustStockAsync(
        long productId, 
        ProductType productType, 
        int newQuantity,
        string? note = null,
        long? performedByUserId = null,
        CancellationToken ct = default);
    
    /// <summary>
    /// ثبت برگشت کالا از مشتری
    /// </summary>
    Task<bool> ProcessReturnAsync(
        long productId, 
        ProductType productType, 
        int quantity,
        long? orderId = null,
        string? note = null,
        long? performedByUserId = null,
        CancellationToken ct = default);
    
    /// <summary>
    /// ثبت ضایعات/مفقودی
    /// </summary>
    Task<bool> RecordLossAsync(
        long productId, 
        ProductType productType, 
        int quantity,
        StockMovementType lossType, // Damaged or Lost
        string? note = null,
        long? performedByUserId = null,
        CancellationToken ct = default);
    
    #endregion
    
    #region Bulk Operations
    
    /// <summary>
    /// رزرو موجودی برای چند آیتم (یک سفارش با چند محصول)
    /// </summary>
    Task<bool> BulkReserveStockAsync(
        IEnumerable<(long ProductId, ProductType ProductType, int Quantity)> items,
        long? orderId = null,
        CancellationToken ct = default);
    
    /// <summary>
    /// آزادسازی رزرو برای چند آیتم
    /// </summary>
    Task<bool> BulkReleaseReservationAsync(
        IEnumerable<(long ProductId, ProductType ProductType, int Quantity)> items,
        long? orderId = null,
        CancellationToken ct = default);
    
    /// <summary>
    /// تایید فروش برای چند آیتم
    /// </summary>
    Task<bool> BulkConfirmSaleAsync(
        IEnumerable<(long ProductId, ProductType ProductType, int Quantity)> items,
        long? orderId = null,
        CancellationToken ct = default);
    
    #endregion
}
