<?php

namespace App\Modules\Procurement\Services;

use App\Modules\Inventory\Stock\Support\DecimalQuantity;
use App\Modules\Procurement\Models\GoodsReceipt;
use App\Modules\Procurement\Models\PurchaseOrderItem;

final class GoodsReceiptDraftWithLinesService
{
    public function __construct(
        private readonly GoodsReceiptDraftService $draft,
        private readonly GoodsReceiptItemPersistenceService $lines,
    ) {}

    public function createForPurchaseOrder(int $tenantId, int $purchaseOrderId, int $warehouseId): GoodsReceipt
    {
        $receipt = $this->draft->createDraft($tenantId, $purchaseOrderId, $warehouseId);
        $poLines = PurchaseOrderItem::query()
            ->where('purchase_order_id', $purchaseOrderId)
            ->whereNull('deleted_at')
            ->orderBy('id')
            ->get();

        foreach ($poLines as $poi) {
            $remaining = $this->remainingReceivable((string) $poi->quantity_ordered, (string) $poi->quantity_received_posted);
            if (! DecimalQuantity::gtZero($remaining)) {
                continue;
            }
            $this->lines->addLine($tenantId, (int) $receipt->id, (int) $poi->id, $remaining);
        }

        return $receipt->fresh(['items.purchaseOrderItem.inventoryItem']);
    }

    private function remainingReceivable(string $ordered, string $posted): string
    {
        if (function_exists('bcsub')) {
            return bcsub($ordered, $posted, 4);
        }

        return (string) round((float) $ordered - (float) $posted, 4);
    }
}
