using System.ComponentModel.DataAnnotations;
using ERPCore.Domain.Enums;

namespace ERPCore.Dtos.Procurement;

// Responses (docs/11 §3.3) ------------------------------------------------------

public sealed record PoLineDto(
    int PoLineId, int ItemId, int WarehouseId,
    decimal Qty, decimal UnitPrice, decimal Tax, decimal QtyReceived);

public sealed record PoTotalsDto(decimal SubTotal, decimal Tax, decimal GrandTotal, string Currency);

public sealed record PurchaseOrderDto(
    int PoId, string DocNo, int VendorId, int? RequisitionId, PurchaseOrderStatus Status,
    bool ApprovalRequired, int CreatedBy, DateTime CreatedAt, DateTime? UpdatedAt,
    PoTotalsDto Totals, IReadOnlyList<PoLineDto> Lines);

public sealed record PurchaseOrderSummaryDto(
    int PoId, string DocNo, int VendorId, PurchaseOrderStatus Status,
    bool ApprovalRequired, DateTime CreatedAt, PoTotalsDto Totals);

// Requests — server sets docNo, status, createdBy, timestamps, qtyReceived, totals

public sealed class CreatePoLineInput
{
    [Required] public int ItemId { get; set; }
    [Required] public int WarehouseId { get; set; }
    [Range(0.0001, double.MaxValue)] public decimal Qty { get; set; }
    [Range(0, double.MaxValue)] public decimal UnitPrice { get; set; }
    [Range(0, 1)] public decimal Tax { get; set; }
}

public sealed class CreatePurchaseOrderRequest
{
    [Required] public int VendorId { get; set; }
    public int? RequisitionId { get; set; }
    [Required, MinLength(1)] public List<CreatePoLineInput> Lines { get; set; } = new();

    /// <summary>
    /// When true the PO is created in <c>Draft</c> (editable/deletable, not yet issued).
    /// When false (default) it auto-approves on creation, preserving the Requisition→PO
    /// and RFQ→PO flows unchanged (docs/11 §3.3).
    /// </summary>
    public bool SaveAsDraft { get; set; }
}

public sealed class UpdatePurchaseOrderRequest
{
    [Required] public int VendorId { get; set; }
    public int? RequisitionId { get; set; }
    [Required, MinLength(1)] public List<CreatePoLineInput> Lines { get; set; } = new();
}

public sealed class CancelPurchaseOrderRequest
{
    [StringLength(500)] public string? Reason { get; set; }
}
