package de.effigenix.domain.inventory;

import de.effigenix.shared.common.Quantity;
import de.effigenix.shared.common.Result;
import de.effigenix.shared.common.UnitOfMeasure;

import java.math.BigDecimal;

public record MinimumLevel(Quantity quantity) {

    public static Result<StockError, MinimumLevel> of(String amount, String unit) {
        if (amount == null || amount.isBlank()) {
            return Result.failure(new StockError.InvalidMinimumLevel("amount must not be blank"));
        }
        if (unit == null || unit.isBlank()) {
            return Result.failure(new StockError.InvalidMinimumLevel("unit must not be blank"));
        }

        BigDecimal parsedAmount;
        try {
            parsedAmount = new BigDecimal(amount);
        } catch (NumberFormatException e) {
            return Result.failure(new StockError.InvalidMinimumLevel("amount is not a valid number: " + amount));
        }

        if (parsedAmount.compareTo(BigDecimal.ZERO) < 0) {
            return Result.failure(new StockError.InvalidMinimumLevel("amount must be >= 0, was: " + amount));
        }

        UnitOfMeasure parsedUnit;
        try {
            parsedUnit = UnitOfMeasure.valueOf(unit);
        } catch (IllegalArgumentException e) {
            return Result.failure(new StockError.InvalidMinimumLevel("invalid unit: " + unit));
        }

        // MinimumLevel erlaubt amount == 0 (kein Mindestbestand)
        // Quantity.of() verlangt amount > 0, daher Reconstitute verwenden
        if (parsedAmount.compareTo(BigDecimal.ZERO) == 0) {
            return Result.success(new MinimumLevel(Quantity.reconstitute(parsedAmount, parsedUnit)));
        }

        return Quantity.of(parsedAmount, parsedUnit)
                .map(MinimumLevel::new)
                .mapError(qErr -> new StockError.InvalidMinimumLevel(qErr.message()));
    }
}
