<?php

declare(strict_types=1);

namespace App\Services;

final class StockValuationService
{
    public function calculateEntry(
        float $currentQuantity,
        float $currentValue,
        float $receivedQuantity,
        float $purchasePrice
    ): array {
        $currentQuantity = round(max(0, $currentQuantity), 0);
        $currentValue = round(max(0, $currentValue), 2);
        $receivedQuantity = round(max(0, $receivedQuantity), 0);
        $purchasePrice = round(max(0, $purchasePrice), 2);

        $newQuantity = round(
            $currentQuantity + $receivedQuantity,
            0
        );

        $receivedValue = round(
            $receivedQuantity * $purchasePrice,
            2
        );

        $newValue = round(
            $currentValue + $receivedValue,
            2
        );

        $pmp = $newQuantity > 0
            ? round($newValue / $newQuantity, 4)
            : 0.0;

        return [
            'quantity' => $newQuantity,
            'value' => $newValue,
            'pmp' => $pmp,
        ];
    }

    public function calculateExit(
        float $currentQuantity,
        float $currentValue,
        float $outgoingQuantity
    ): array {
        $currentQuantity = round(max(0, $currentQuantity), 0);
        $currentValue = round(max(0, $currentValue), 2);
        $outgoingQuantity = round(max(0, $outgoingQuantity), 0);

        if ($outgoingQuantity > $currentQuantity) {
            throw new \InvalidArgumentException(
                'Stock insuffisant. La sortie demandée dépasse le stock disponible.'
            );
        }

        $currentPmp = $currentQuantity > 0
            ? round($currentValue / $currentQuantity, 4)
            : 0.0;

        $newQuantity = round(
            $currentQuantity - $outgoingQuantity,
            0
        );

        $newValue = $newQuantity > 0
            ? round($newQuantity * $currentPmp, 2)
            : 0.0;

        return [
            'quantity' => $newQuantity,
            'value' => $newValue,
            'pmp' => $currentPmp,
        ];
    }

    public function calculateInventory(
        float $realQuantity,
        float $currentPmp
    ): array {
        $realQuantity = round(max(0, $realQuantity), 0);
        $currentPmp = round(max(0, $currentPmp), 4);

        return [
            'quantity' => $realQuantity,
            'value' => round($realQuantity * $currentPmp, 2),
            'pmp' => $currentPmp,
        ];
    }
}