using CashLineERP.Contracts.Procurement;

namespace CashLineERP.Application.Procurement;

public sealed class SupplierQuotationService : ISupplierQuotationService
{
    private readonly ISupplierQuotationRepository _quotationRepository;

    public SupplierQuotationService(ISupplierQuotationRepository quotationRepository)
    {
        _quotationRepository = quotationRepository;
    }

    public IReadOnlyCollection<SupplierQuotationResponse> GetQuotations(long? rfqId = null) =>
        _quotationRepository.GetQuotations(rfqId).Select(Map).ToArray();

    public SupplierQuotationResponse? GetQuotation(long quotationId)
    {
        var quotation = _quotationRepository.GetQuotation(quotationId);
        return quotation is null ? null : Map(quotation);
    }

    public SupplierQuotationResponse CreateQuotation(CreateSupplierQuotationRequest request)
    {
        var quotation = _quotationRepository.Create(new CreateSupplierQuotationCommand(
            request.RequestForQuotationId,
            request.SupplierId,
            request.QuoteDate,
            request.ValidUntilDate,
            request.CurrencyCode,
            request.FxRate,
            request.Notes,
            request.Lines.Select(line => new CreateSupplierQuotationLineCommand(
                line.RequestForQuotationLineId,
                line.ItemId,
                line.QuotedQuantity,
                line.UnitOfMeasureCode,
                line.UnitPrice,
                line.DiscountPercent,
                line.DiscountAmount,
                line.TaxCode,
                line.LeadTimeDays)).ToArray()));

        return Map(quotation);
    }

    public SupplierQuotationResponse SubmitQuotation(long quotationId, long actorUserId) =>
        Map(_quotationRepository.Submit(quotationId, actorUserId));

    private static SupplierQuotationResponse Map(SupplierQuotationDetailView quotation) =>
        new(
            quotation.SupplierQuotationId,
            quotation.QuotationNumber,
            quotation.RequestForQuotationId,
            quotation.SupplierId,
            quotation.QuoteDate,
            quotation.ValidUntilDate,
            quotation.CurrencyCode,
            quotation.FxRate,
            quotation.StatusCode,
            quotation.SubtotalAmount,
            quotation.DiscountAmount,
            quotation.TaxAmount,
            quotation.TotalAmount,
            quotation.IsSelected,
            quotation.Notes,
            quotation.Lines.Select(line => new SupplierQuotationLineResponse(
                line.SupplierQuotationLineId,
                line.LineNumber,
                line.RequestForQuotationLineId,
                line.ItemId,
                line.QuotedQuantity,
                line.UnitOfMeasureCode,
                line.UnitPrice,
                line.DiscountPercent,
                line.DiscountAmount,
                line.TaxCode,
                line.LineNetAmount,
                line.LineTaxAmount,
                line.LineTotalAmount,
                line.LeadTimeDays)).ToArray());
}
