<?php

namespace App\Modules\Procurement\Services;

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

final class PurchaseOrderReceivingProgressService
{
    public function refreshPurchaseOrderStatus(PurchaseOrder $po): void
    {
        $lines = PurchaseOrderItem::withoutGlobalScopes()
            ->where('purchase_order_id', $po->id)
            ->whereNull('deleted_at')
            ->orderBy('id')
            ->get();

        if ($lines->isEmpty()) {
            return;
        }

        $anyReceived = false;
        $allComplete = true;
        foreach ($lines as $line) {
            $ordered = (string) $line->quantity_ordered;
            $posted = (string) $line->quantity_received_posted;
            if (DecimalQuantity::gtZero($posted)) {
                $anyReceived = true;
            }
            if (! DecimalQuantity::gte($posted, $ordered)) {
                $allComplete = false;
            }
        }

        $next = PurchaseOrderLifecycleStatus::Approved;
        if ($anyReceived) {
            $next = $allComplete
                ? PurchaseOrderLifecycleStatus::FullyReceived
                : PurchaseOrderLifecycleStatus::PartiallyReceived;
        }

        $current = PurchaseOrderLifecycleStatus::tryFrom((string) $po->status);
        if ($current === PurchaseOrderLifecycleStatus::Cancelled
            || $current === PurchaseOrderLifecycleStatus::Closed) {
            return;
        }

        $po->forceFill(['status' => $next->value])->save();
    }
}
