using CashLineERP.Contracts.Procurement;

namespace CashLineERP.Application.Procurement;

public sealed class RfqService : IRfqService
{
    private readonly IRfqRepository _rfqRepository;

    public RfqService(IRfqRepository rfqRepository)
    {
        _rfqRepository = rfqRepository;
    }

    public IReadOnlyCollection<RfqResponse> GetRfqs() => _rfqRepository.GetRfqs().Select(Map).ToArray();

    public RfqResponse? GetRfq(long rfqId)
    {
        var rfq = _rfqRepository.GetRfq(rfqId);
        return rfq is null ? null : Map(rfq);
    }

    public RfqResponse CreateRfq(CreateRfqRequest request)
    {
        var rfq = _rfqRepository.Create(new CreateRfqCommand(
            request.BranchId,
            request.DepartmentId,
            request.PurchaseRequisitionId,
            request.RequesterUserId,
            request.BuyerUserId,
            request.RfqType,
            request.RfqDate,
            request.ValidUntilDate,
            request.CurrencyCode,
            request.Notes,
            request.Lines.Select(line => new CreateRfqLineCommand(
                line.PurchaseRequisitionLineId,
                line.ItemId,
                line.ItemDescription,
                line.RequestedQuantity,
                line.UnitOfMeasureCode,
                line.NeedByDate,
                line.TaxCode,
                line.TargetUnitPrice,
                line.Notes)).ToArray(),
            request.SupplierIds));

        return Map(rfq);
    }

    public RfqResponse SubmitRfq(long rfqId, long actorUserId) => Map(_rfqRepository.Submit(rfqId, actorUserId));

    private static RfqResponse Map(RfqDetailView rfq) =>
        new(
            rfq.RfqId,
            rfq.RfqNumber,
            rfq.BranchId,
            rfq.DepartmentId,
            rfq.PurchaseRequisitionId,
            rfq.RequesterUserId,
            rfq.BuyerUserId,
            rfq.RfqType,
            rfq.RfqDate,
            rfq.ValidUntilDate,
            rfq.StatusCode,
            rfq.CurrencyCode,
            rfq.Notes,
            rfq.Lines.Select(line => new RfqLineResponse(
                line.RfqLineId,
                line.LineNumber,
                line.PurchaseRequisitionLineId,
                line.ItemId,
                line.ItemDescription,
                line.RequestedQuantity,
                line.UnitOfMeasureCode,
                line.NeedByDate,
                line.TaxCode,
                line.TargetUnitPrice,
                line.Notes)).ToArray(),
            rfq.Suppliers.Select(supplier => new RfqSupplierResponse(
                supplier.SupplierId,
                supplier.InviteStatus,
                supplier.InvitedAtUtc,
                supplier.RespondedAtUtc,
                supplier.DeclineReason)).ToArray());
}
