namespace Apollinare.Domain.Entities.Warehouse;

/// <summary>
/// Storico valorizzazione magazzino per periodo
/// </summary>
public class StockValuation : BaseEntity
{
    /// <summary>
    /// Data della valorizzazione
    /// </summary>
    public DateTime ValuationDate { get; set; }

    /// <summary>
    /// Periodo di riferimento (YYYYMM)
    /// </summary>
    public int Period { get; set; }

    /// <summary>
    /// Articolo
    /// </summary>
    public int ArticleId { get; set; }

    /// <summary>
    /// Magazzino (null = totale tutti i magazzini)
    /// </summary>
    public int? WarehouseId { get; set; }

    /// <summary>
    /// Quantità a fine periodo
    /// </summary>
    public decimal Quantity { get; set; }

    /// <summary>
    /// Metodo di valorizzazione usato
    /// </summary>
    public ValuationMethod Method { get; set; }

    /// <summary>
    /// Costo unitario calcolato
    /// </summary>
    public decimal UnitCost { get; set; }

    /// <summary>
    /// Valore totale = Quantity * UnitCost
    /// </summary>
    public decimal TotalValue { get; set; }

    /// <summary>
    /// Quantità in carico nel periodo
    /// </summary>
    public decimal InboundQuantity { get; set; }

    /// <summary>
    /// Valore carichi nel periodo
    /// </summary>
    public decimal InboundValue { get; set; }

    /// <summary>
    /// Quantità in scarico nel periodo
    /// </summary>
    public decimal OutboundQuantity { get; set; }

    /// <summary>
    /// Valore scarichi nel periodo
    /// </summary>
    public decimal OutboundValue { get; set; }

    /// <summary>
    /// Se è una chiusura definitiva (non più modificabile)
    /// </summary>
    public bool IsClosed { get; set; }

    /// <summary>
    /// Data chiusura
    /// </summary>
    public DateTime? ClosedDate { get; set; }

    /// <summary>
    /// Utente che ha chiuso
    /// </summary>
    public string? ClosedBy { get; set; }

    /// <summary>
    /// Note
    /// </summary>
    public string? Notes { get; set; }

    // Navigation properties
    public WarehouseArticle? Article { get; set; }
    public WarehouseLocation? Warehouse { get; set; }
}

/// <summary>
/// Dettaglio valorizzazione FIFO/LIFO per layer
/// </summary>
public class StockValuationLayer : BaseEntity
{
    /// <summary>
    /// Articolo
    /// </summary>
    public int ArticleId { get; set; }

    /// <summary>
    /// Magazzino
    /// </summary>
    public int WarehouseId { get; set; }

    /// <summary>
    /// Partita (opzionale)
    /// </summary>
    public int? BatchId { get; set; }

    /// <summary>
    /// Data del layer (data carico originale)
    /// </summary>
    public DateTime LayerDate { get; set; }

    /// <summary>
    /// Movimento di carico che ha creato il layer
    /// </summary>
    public int? SourceMovementId { get; set; }

    /// <summary>
    /// Quantità originale del layer
    /// </summary>
    public decimal OriginalQuantity { get; set; }

    /// <summary>
    /// Quantità residua nel layer
    /// </summary>
    public decimal RemainingQuantity { get; set; }

    /// <summary>
    /// Costo unitario del layer
    /// </summary>
    public decimal UnitCost { get; set; }

    /// <summary>
    /// Valore residuo = RemainingQuantity * UnitCost
    /// </summary>
    public decimal RemainingValue => RemainingQuantity * UnitCost;

    /// <summary>
    /// Se il layer è esaurito
    /// </summary>
    public bool IsExhausted { get; set; }

    // Navigation properties
    public WarehouseArticle? Article { get; set; }
    public WarehouseLocation? Warehouse { get; set; }
    public ArticleBatch? Batch { get; set; }
    public StockMovement? SourceMovement { get; set; }
}
