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

namespace CashLineERP.Domain.Procurement;

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

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

    public long RequestForQuotationId { get; private set; }

    public long SupplierId { get; private set; }

    public DateOnly QuoteDate { get; private set; }

    public DateOnly? ValidUntilDate { get; private set; }

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

    public decimal? FxRate { get; private set; }

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

    public decimal SubtotalAmount { get; private set; }

    public decimal DiscountAmount { get; private set; }

    public decimal TaxAmount { get; private set; }

    public decimal TotalAmount { get; private set; }

    public bool IsSelected { get; private set; }

    public DateTime? SelectedAtUtc { get; private set; }

    public string? Notes { get; private set; }

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

    public SupplierQuotation(
        string quotationNumber,
        long requestForQuotationId,
        long supplierId,
        DateOnly quoteDate,
        DateOnly? validUntilDate,
        string currencyCode,
        decimal? fxRate,
        string? notes)
    {
        QuotationNumber = quotationNumber;
        RequestForQuotationId = requestForQuotationId;
        SupplierId = supplierId;
        QuoteDate = quoteDate;
        ValidUntilDate = validUntilDate;
        CurrencyCode = currencyCode;
        FxRate = fxRate;
        Notes = notes;
    }

    private SupplierQuotation()
    {
    }

    public void AddLine(
        int lineNumber,
        long requestForQuotationLineId,
        long? itemId,
        decimal quotedQuantity,
        string unitOfMeasureCode,
        decimal unitPrice,
        decimal discountPercent,
        decimal discountAmount,
        string? taxCode,
        int? leadTimeDays)
    {
        var line = new SupplierQuotationLine(
            quotationId: Id,
            lineNumber: lineNumber,
            requestForQuotationLineId: requestForQuotationLineId,
            itemId: itemId,
            quotedQuantity: quotedQuantity,
            unitOfMeasureCode: unitOfMeasureCode,
            unitPrice: unitPrice,
            discountPercent: discountPercent,
            discountAmount: discountAmount,
            taxCode: taxCode,
            leadTimeDays: leadTimeDays);

        Lines.Add(line);
        RecalculateTotals();
    }

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

    public void SelectForAward(long actorUserId)
    {
        IsSelected = true;
        SelectedAtUtc = DateTime.UtcNow;
        StatusId = WorkflowStatusSeedIds.Approved;
        Touch(actorUserId);
    }

    private void RecalculateTotals()
    {
        SubtotalAmount = Lines.Sum(line => line.LineNetAmount);
        DiscountAmount = Lines.Sum(line => line.DiscountAmount);
        TaxAmount = Lines.Sum(line => line.LineTaxAmount);
        TotalAmount = Lines.Sum(line => line.LineTotalAmount);
    }
}
