// EN: Commands for Inventory Service.
// VI: Commands cho Inventory Service.

using MediatR;

namespace InventoryService.API.Application.Commands;

/// <summary>
/// EN: Command to create a new inventory item (raw materials / consumables).
/// VI: Command để tạo inventory item mới (nguyên liệu thô / vật tư tiêu hao).
/// </summary>
public record CreateInventoryItemCommand(
    Guid ShopId,
    string Name,
    int ItemTypeId,
    string Unit,
    decimal CostPerUnit,
    int InitialQuantity,
    int ReorderLevel,
    string? SupplierName,
    DateTime? ExpiryDate) : IRequest<Guid>;

/// <summary>
/// EN: Command to perform stock in operation.
/// VI: Command để thực hiện nhập kho.
/// </summary>
public record StockInCommand(
    Guid ProductId,
    Guid ShopId,
    int Amount,
    string? Notes,
    Guid? ReferenceId,
    string? InvoiceImageUrl,
    decimal? UnitCost) : IRequest<Guid>;

/// <summary>
/// EN: Command to perform stock out operation.
/// VI: Command để thực hiện xuất kho.
/// </summary>
public record StockOutCommand(
    Guid ProductId,
    Guid ShopId,
    int Amount,
    string? Notes,
    Guid? ReferenceId) : IRequest<bool>;

/// <summary>
/// EN: Command to reserve stock for order.
/// VI: Command để đặt trước stock cho order.
/// </summary>
public record ReserveStockCommand(
    Guid ProductId,
    Guid ShopId,
    int Amount,
    Guid OrderId) : IRequest<bool>;

/// <summary>
/// EN: Command to release stock reservation.
/// VI: Command để giải phóng đặt trước stock.
/// </summary>
public record ReleaseReservationCommand(
    Guid ProductId,
    Guid ShopId,
    int Amount,
    Guid OrderId) : IRequest<bool>;

/// <summary>
/// EN: Command to adjust stock (manual correction).
/// VI: Command để điều chỉnh stock (sửa thủ công).
/// </summary>
public record AdjustStockCommand(
    Guid ProductId,
    Guid ShopId,
    int NewQuantity,
    string Notes) : IRequest<bool>;

/// <summary>
/// EN: Command to stock out by inventory item ID directly (for recipe deduction).
/// VI: Command xuất kho theo inventory item ID trực tiếp (cho trừ nguyên liệu công thức).
/// </summary>
public record StockOutByIdCommand(
    Guid InventoryItemId,
    int Amount,
    string? Notes,
    Guid? ReferenceId) : IRequest<bool>;

/// <summary>
/// EN: Command to record wastage/shrinkage.
/// VI: Command để ghi nhận hao hụt.
/// </summary>
public record RecordWastageCommand(Guid InventoryItemId, int Amount, string Reason, string? Notes) : IRequest<bool>;

/// <summary>
/// EN: Command to perform stocktake (inventory count).
/// VI: Command để thực hiện kiểm kê (đếm tồn kho).
/// </summary>
public record StocktakeCommand(Guid ShopId, List<StocktakeItem> Items) : IRequest<StocktakeResult>;

public record StocktakeItem(Guid InventoryItemId, int CountedQuantity);

public record StocktakeResult(List<StocktakeDiscrepancy> Discrepancies, int TotalItemsCounted);

public record StocktakeDiscrepancy(Guid InventoryItemId, string? ItemName, int ExpectedQuantity, int CountedQuantity, int Difference);

/// <summary>
/// EN: Command to set low stock alert threshold for a product.
/// VI: Command để cài đặt ngưỡng cảnh báo stock thấp cho sản phẩm.
/// </summary>
public record SetLowStockAlertCommand(
    Guid ShopId,
    Guid ProductId,
    int MinimumLevel) : IRequest<bool>;

/// <summary>
/// EN: Command to delete an inventory item.
/// VI: Command để xóa một inventory item.
/// </summary>
public record DeleteInventoryItemCommand(Guid InventoryItemId) : IRequest<bool>;
