namespace ZB.MOM.WW.OtOpcUa.Configuration.Entities;

/// <summary>
///     Staged equipment-import batch per Phase 6.4 Stream B.2. Rows land in the child
///     <see cref="EquipmentImportRow"/> table under a batch header; operator reviews + either
///     drops (via <c>DropImportBatch</c>) or finalises (via <c>FinaliseImportBatch</c>) in one
///     bounded transaction. The live <c>Equipment</c> table never sees partial state.
/// </summary>
/// <remarks>
///     <para>User-scoped visibility: the preview modal only shows batches where
///     <see cref="CreatedBy"/> equals the current operator. Prevents accidental
///     cross-operator finalise during concurrent imports. An admin finalise / drop surface
///     can override this — tracked alongside the UI follow-up.</para>
///
///     <para><see cref="FinalisedAtUtc"/> stamps the moment the batch promoted from staging
///     into <c>Equipment</c>. Null = still in staging; non-null = archived / finalised.</para>
/// </remarks>
public sealed class EquipmentImportBatch
{
    /// <summary>Gets or sets the unique identifier for this batch.</summary>
    public Guid Id { get; set; }

    /// <summary>Gets or sets the cluster identifier.</summary>
    public required string ClusterId { get; set; }

    /// <summary>Gets or sets the user name who created this batch.</summary>
    public required string CreatedBy { get; set; }

    /// <summary>Gets or sets the UTC timestamp when this batch was created.</summary>
    public DateTime CreatedAtUtc { get; set; }

    /// <summary>Gets or sets the total number of rows staged in this batch.</summary>
    public int RowsStaged { get; set; }

    /// <summary>Gets or sets the number of rows accepted in this batch.</summary>
    public int RowsAccepted { get; set; }

    /// <summary>Gets or sets the number of rows rejected in this batch.</summary>
    public int RowsRejected { get; set; }

    /// <summary>Gets or sets the UTC timestamp when this batch was finalised, or null if still in staging.</summary>
    public DateTime? FinalisedAtUtc { get; set; }

    /// <summary>Gets or sets the collection of staged rows in this batch.</summary>
    public ICollection<EquipmentImportRow> Rows { get; set; } = [];
}

/// <summary>
///     One staged row under an <see cref="EquipmentImportBatch"/>. Mirrors the decision #117
///     + decision #139 columns from the CSV importer's output + an
///     <see cref="IsAccepted"/> flag + a <see cref="RejectReason"/> string the preview modal
///     renders.
/// </summary>
public sealed class EquipmentImportRow
{
    /// <summary>Gets or sets the unique identifier for this row.</summary>
    public Guid Id { get; set; }

    /// <summary>Gets or sets the parent batch identifier.</summary>
    public Guid BatchId { get; set; }

    /// <summary>Gets or sets the line number in the source file.</summary>
    public int LineNumberInFile { get; set; }

    /// <summary>Gets or sets a value indicating whether this row was accepted.</summary>
    public bool IsAccepted { get; set; }

    /// <summary>Gets or sets the reason this row was rejected, if applicable.</summary>
    public string? RejectReason { get; set; }

    // Required (decision #117)
    /// <summary>Gets or sets the Z tag identifier.</summary>
    public required string ZTag { get; set; }

    /// <summary>Gets or sets the machine code.</summary>
    public required string MachineCode { get; set; }

    /// <summary>Gets or sets the SAP identifier.</summary>
    public required string SAPID { get; set; }

    /// <summary>Gets or sets the equipment identifier.</summary>
    public required string EquipmentId { get; set; }

    /// <summary>Gets or sets the equipment UUID.</summary>
    public required string EquipmentUuid { get; set; }

    /// <summary>Gets or sets the equipment name.</summary>
    public required string Name { get; set; }

    /// <summary>Gets or sets the UNS area name.</summary>
    public required string UnsAreaName { get; set; }

    /// <summary>Gets or sets the UNS line name.</summary>
    public required string UnsLineName { get; set; }

    // Optional (decision #139 — OPC 40010 Identification)
    /// <summary>Gets or sets the manufacturer name.</summary>
    public string? Manufacturer { get; set; }

    /// <summary>Gets or sets the equipment model.</summary>
    public string? Model { get; set; }

    /// <summary>Gets or sets the serial number.</summary>
    public string? SerialNumber { get; set; }

    /// <summary>Gets or sets the hardware revision.</summary>
    public string? HardwareRevision { get; set; }

    /// <summary>Gets or sets the software revision.</summary>
    public string? SoftwareRevision { get; set; }

    /// <summary>Gets or sets the year of construction.</summary>
    public string? YearOfConstruction { get; set; }

    /// <summary>Gets or sets the asset location.</summary>
    public string? AssetLocation { get; set; }

    /// <summary>Gets or sets the manufacturer URI.</summary>
    public string? ManufacturerUri { get; set; }

    /// <summary>Gets or sets the device manual URI.</summary>
    public string? DeviceManualUri { get; set; }

    /// <summary>Gets or sets the parent batch.</summary>
    public EquipmentImportBatch? Batch { get; set; }
}
