<?php

namespace App\Modules\Sales\Services;

use App\Modules\Sales\Models\SalesOrderLine;
use App\Modules\Sales\Support\SalesOrderLifecycleStatus;
use App\Modules\Inventory\Stock\Support\DecimalQuantity;
use Illuminate\Support\Collection;

final class SalesOrderStatusEvaluator
{
    /**
     * @param  Collection<int, SalesOrderLine>  $lines
     */
    public static function evaluate(Collection $lines): SalesOrderLifecycleStatus
    {
        if ($lines->isEmpty()) {
            return SalesOrderLifecycleStatus::Confirmed;
        }

        $allFulfilled = true;
        $anyFulfilled = false;
        $allFullyCovered = true;
        $anyCoverage = false;

        foreach ($lines as $line) {
            $ordered = trim((string) $line->quantity_ordered);
            $reserved = trim((string) $line->quantity_reserved);
            $fulfilled = trim((string) $line->quantity_fulfilled);
            $covered = DecimalQuantity::add($reserved, $fulfilled);

            if (DecimalQuantity::gtZero($fulfilled)) {
                $anyFulfilled = true;
            }
            if (! DecimalQuantity::equals($fulfilled, $ordered)) {
                $allFulfilled = false;
            }
            if (DecimalQuantity::gtZero($covered)) {
                $anyCoverage = true;
            }
            if (! DecimalQuantity::gte($covered, $ordered)) {
                $allFullyCovered = false;
            }
        }

        if ($allFulfilled) {
            return SalesOrderLifecycleStatus::Fulfilled;
        }
        if ($anyFulfilled) {
            return SalesOrderLifecycleStatus::PartiallyFulfilled;
        }
        if ($allFullyCovered) {
            return SalesOrderLifecycleStatus::Allocated;
        }
        if ($anyCoverage) {
            return SalesOrderLifecycleStatus::PartiallyAllocated;
        }

        return SalesOrderLifecycleStatus::Confirmed;
    }
}
