using ERPCore.Domain.Enums;

namespace ERPCore.Domain.Entities;

/// <summary>
/// One execution instance of a template (FR-MFG-08), numbered <c>PRD-2026-00001</c>.
/// Every stage, input, output and edge is <b>copied</b> from the template at creation
/// with quantities scaled by <see cref="ScaleFactor"/>, so a completed run stays
/// readable even if the template is later edited (FR-MFG-06).
/// <para>The run's <b>cost pool</b> is derived, never stored:
/// <c>Σ RunStageInput.ConsumedValue − Σ RunStageInput.ReturnedValue</c>. The terminal
/// approve divides it by the good quantity to cost the finished layer, then closes it
/// (FR-MFG-13, <c>409 RUN_COST_CLOSED</c>).</para>
/// Mutable aggregate with a <see cref="RowVersion"/> token. Model: docs/30 Part C.
/// </summary>
public class ProductionRun
{
    public int RunId { get; set; }
    public string DocNo { get; set; } = string.Empty;

    public int TemplateId { get; set; }
    public ProductionTemplate? Template { get; set; }

    /// <summary>Stock inputs are consumed from, and the finished good received into, this warehouse.</summary>
    public int WarehouseId { get; set; }
    public Warehouse? Warehouse { get; set; }

    /// <summary>Optional destination bin for the finished goods. Reaches the ledger only — stock layers carry no bin.</summary>
    public int? OutputBinId { get; set; }
    public Bin? OutputBin { get; set; }

    /// <summary>Target quantity of the finished item; drives <see cref="ScaleFactor"/>.</summary>
    public decimal TargetQty { get; set; }

    /// <summary><c>TargetQty / terminalOutput.QtyPerBatch</c>, applied to every copied quantity.</summary>
    public decimal ScaleFactor { get; set; }

    public ProductionRunStatus Status { get; set; } = ProductionRunStatus.InProgress;

    /// <summary>Incremented by each terminal reject (FR-MFG-16); prior figures live in the event history.</summary>
    public int ReworkCount { get; set; }

    public int? CancelReasonCodeId { get; set; }
    public ReasonCode? CancelReason { get; set; }

    public int CreatedBy { get; set; }
    public User? Creator { get; set; }

    public DateTime CreatedAt { get; set; }

    /// <summary>Set by the terminal approve only. A cancelled run leaves this null.</summary>
    public DateTime? CompletedAt { get; set; }

    public uint RowVersion { get; set; }

    public ICollection<RunStage> Stages { get; set; } = new List<RunStage>();
    public ICollection<RunEdge> Edges { get; set; } = new List<RunEdge>();
    public ICollection<RunStageEvent> Events { get; set; } = new List<RunStageEvent>();
}
