<?php

namespace App\Services;

use App\Models\MaterialType;
use InvalidArgumentException;

class FeedStockService
{
    public function addStock(MaterialType $type, float $quantity): MaterialType
    {
        $this->assertFeedType($type);

        if ($quantity <= 0) {
            throw new InvalidArgumentException('La cantidad a agregar debe ser mayor a cero.');
        }

        $type->increment('stock_quantity', round($quantity, 3));

        return $type->fresh();
    }

    public function deductStock(MaterialType $type, float $quantity): MaterialType
    {
        $this->assertFeedType($type);

        if ($quantity <= 0) {
            throw new InvalidArgumentException('La cantidad a descontar debe ser mayor a cero.');
        }

        $available = (float) $type->stock_quantity;
        if ($quantity > $available + 0.001) {
            throw new InvalidArgumentException(
                "Stock insuficiente de «{$type->name}»: disponible {$available} {$type->unit}, solicitado {$quantity}."
            );
        }

        $type->decrement('stock_quantity', round($quantity, 3));

        return $type->fresh();
    }

    public function restoreStock(MaterialType $type, float $quantity): MaterialType
    {
        return $this->addStock($type, $quantity);
    }

    /**
     * @return list<array{id: int, name: string, unit: string, stock_quantity: float}>
     */
    public function feedInventory(): array
    {
        return MaterialType::query()
            ->feed()
            ->active()
            ->orderBy('name')
            ->get()
            ->map(fn (MaterialType $type) => [
                'id' => $type->id,
                'name' => $type->name,
                'unit' => $type->unit,
                'stock_quantity' => round((float) $type->stock_quantity, 3),
            ])
            ->all();
    }

    private function assertFeedType(MaterialType $type): void
    {
        if ($type->category !== 'feed_supplements') {
            throw new InvalidArgumentException('Solo alimentos del catálogo tienen inventario.');
        }
    }
}
