using CashLineERP.Contracts.Procurement;

namespace CashLineERP.Application.Procurement;

public sealed class GoodsReceiptService : IGoodsReceiptService
{
    private readonly IGoodsReceiptRepository _repository;

    public GoodsReceiptService(IGoodsReceiptRepository repository)
    {
        _repository = repository;
    }

    public IReadOnlyCollection<GoodsReceiptResponse> GetGoodsReceipts() =>
        _repository.GetGoodsReceipts().Select(Map).ToArray();

    public GoodsReceiptResponse? GetGoodsReceipt(long goodsReceiptId)
    {
        var goodsReceipt = _repository.GetGoodsReceipt(goodsReceiptId);
        return goodsReceipt is null ? null : Map(goodsReceipt);
    }

    public GoodsReceiptResponse CreateGoodsReceipt(CreateGoodsReceiptRequest request)
    {
        var goodsReceipt = _repository.Create(new CreateGoodsReceiptCommand(
            request.BranchId,
            request.PurchaseOrderId,
            request.SupplierId,
            request.ReceivedAtUtc,
            request.ReceivedByUserId,
            request.InspectionStatus,
            request.Lines.Select(line => new CreateGoodsReceiptLineCommand(
                line.PurchaseOrderLineId,
                line.ItemId,
                line.WarehouseId,
                line.WarehouseLocationId,
                line.QuantityReceived,
                line.QuantityAccepted,
                line.QuantityRejected,
                line.BatchNumber,
                line.SerialNumber)).ToArray()));

        return Map(goodsReceipt);
    }

    public GoodsReceiptResponse PostGoodsReceipt(long goodsReceiptId, long actorUserId) =>
        Map(_repository.Post(goodsReceiptId, actorUserId));

    private static GoodsReceiptResponse Map(GoodsReceiptDetailView goodsReceipt) =>
        new(
            goodsReceipt.GoodsReceiptId,
            goodsReceipt.GoodsReceiptNumber,
            goodsReceipt.BranchId,
            goodsReceipt.PurchaseOrderId,
            goodsReceipt.SupplierId,
            goodsReceipt.ReceivedAtUtc,
            goodsReceipt.ReceivedByUserId,
            goodsReceipt.StatusCode,
            goodsReceipt.InspectionStatus,
            goodsReceipt.Lines.Select(line => new GoodsReceiptLineResponse(
                line.GoodsReceiptLineId,
                line.LineNumber,
                line.PurchaseOrderLineId,
                line.ItemId,
                line.WarehouseId,
                line.WarehouseLocationId,
                line.QuantityReceived,
                line.QuantityAccepted,
                line.QuantityRejected,
                line.BatchNumber,
                line.SerialNumber)).ToArray());
}
