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

namespace CashLineERP.Domain.Procurement;

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

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

    public long BranchId { get; private set; }

    public long? DepartmentId { get; private set; }

    public long? PurchaseRequisitionId { get; private set; }

    public long? RequesterUserId { get; private set; }

    public long? BuyerUserId { get; private set; }

    public string RfqType { get; private set; } = "STANDARD";

    public DateOnly RfqDate { get; private set; }

    public DateOnly? ValidUntilDate { get; private set; }

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

    public string CurrencyCode { get; private set; } = "EGP";

    public string? Notes { get; private set; }

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

    public List<RequestForQuotationSupplier> Suppliers { get; private set; } = [];

    public RequestForQuotation(
        string rfqNumber,
        long branchId,
        long? departmentId,
        long? purchaseRequisitionId,
        long? requesterUserId,
        long? buyerUserId,
        string rfqType,
        DateOnly rfqDate,
        DateOnly? validUntilDate,
        string currencyCode,
        string? notes)
    {
        RfqNumber = rfqNumber;
        BranchId = branchId;
        DepartmentId = departmentId;
        PurchaseRequisitionId = purchaseRequisitionId;
        RequesterUserId = requesterUserId;
        BuyerUserId = buyerUserId;
        RfqType = string.IsNullOrWhiteSpace(rfqType) ? "STANDARD" : rfqType;
        RfqDate = rfqDate;
        ValidUntilDate = validUntilDate;
        CurrencyCode = currencyCode;
        Notes = notes;
    }

    private RequestForQuotation()
    {
    }

    public void AddLine(
        int lineNumber,
        long? purchaseRequisitionLineId,
        long? itemId,
        string itemDescription,
        decimal requestedQuantity,
        string unitOfMeasureCode,
        DateOnly? needByDate,
        string? taxCode,
        decimal? targetUnitPrice,
        string? notes)
    {
        Lines.Add(new RequestForQuotationLine(
            rfqId: Id,
            lineNumber: lineNumber,
            purchaseRequisitionLineId: purchaseRequisitionLineId,
            itemId: itemId,
            itemDescription: itemDescription,
            requestedQuantity: requestedQuantity,
            unitOfMeasureCode: unitOfMeasureCode,
            needByDate: needByDate,
            taxCode: taxCode,
            targetUnitPrice: targetUnitPrice,
            notes: notes));
    }

    public void InviteSupplier(long supplierId, long? actorUserId = null)
    {
        if (Suppliers.Any(existing => existing.SupplierId == supplierId))
        {
            return;
        }

        Suppliers.Add(new RequestForQuotationSupplier(Id, supplierId));
        if (actorUserId.HasValue)
        {
            Touch(actorUserId);
        }
    }

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