using CashLineERP.Domain.Common;
using CashLineERP.SharedKernel.Workflow;

namespace CashLineERP.Domain.Procurement;

public sealed class PurchaseReturn : Entity
{
    public long Id { get; private set; }

    public string PurchaseReturnNumber { get; private set; } = string.Empty;

    public long BranchId { get; private set; }

    public long SupplierId { get; private set; }

    public long PurchaseOrderId { get; private set; }

    public long GoodsReceiptId { get; private set; }

    public DateOnly ReturnDate { get; private set; }

    public long ReturnWarehouseId { get; private set; }

    public string ReasonCode { get; private set; } = string.Empty;

    public string? Notes { get; private set; }

    public long StatusId { get; private set; } = WorkflowStatusSeedIds.Draft;

    public decimal TotalReturnedQuantity { get; private set; }

    public long? DebitNoteBillId { get; private set; }

    public DateTime? DebitNoteIssuedAtUtc { get; private set; }

    public List<PurchaseReturnLine> Lines { get; private set; } = [];

    public PurchaseReturn(
        string purchaseReturnNumber,
        long branchId,
        long supplierId,
        long purchaseOrderId,
        long goodsReceiptId,
        DateOnly returnDate,
        long returnWarehouseId,
        string reasonCode,
        string? notes)
    {
        PurchaseReturnNumber = purchaseReturnNumber;
        BranchId = branchId;
        SupplierId = supplierId;
        PurchaseOrderId = purchaseOrderId;
        GoodsReceiptId = goodsReceiptId;
        ReturnDate = returnDate;
        ReturnWarehouseId = returnWarehouseId;
        ReasonCode = reasonCode;
        Notes = notes;
    }

    private PurchaseReturn()
    {
    }

    public void AddLine(
        int lineNumber,
        long goodsReceiptLineId,
        long purchaseOrderLineId,
        long itemId,
        decimal quantityReturned,
        long? warehouseLocationId,
        string? batchNumber,
        string? serialNumber,
        string? notes)
    {
        Lines.Add(new PurchaseReturnLine(
            purchaseReturnId: Id,
            lineNumber: lineNumber,
            goodsReceiptLineId: goodsReceiptLineId,
            purchaseOrderLineId: purchaseOrderLineId,
            itemId: itemId,
            quantityReturned: quantityReturned,
            warehouseLocationId: warehouseLocationId,
            batchNumber: batchNumber,
            serialNumber: serialNumber,
            notes: notes));

        RecalculateTotals();
    }

    public void Submit(long actorUserId)
    {
        StatusId = WorkflowStatusSeedIds.Submitted;
        Touch(actorUserId);
    }

    public void Post(long actorUserId)
    {
        StatusId = WorkflowStatusSeedIds.Posted;
        Touch(actorUserId);
    }

    public void LinkDebitNote(long actorUserId, long debitNoteBillId)
    {
        DebitNoteBillId = debitNoteBillId;
        DebitNoteIssuedAtUtc = DateTime.UtcNow;
        Touch(actorUserId);
    }

    private void RecalculateTotals()
    {
        TotalReturnedQuantity = Lines.Sum(line => line.QuantityReturned);
    }
}
