<?php

namespace App\Support;

use Brick\Math\BigDecimal;
use Brick\Math\RoundingMode;
use InvalidArgumentException;

final class Decimal
{
    public static function add(string ...$values): string
    {
        $result = BigDecimal::zero();
        foreach ($values as $value) {
            $result = $result->plus($value);
        }
        return self::scale($result->__toString());
    }

    public static function subtract(string $left, string $right): string
    {
        return self::scale(BigDecimal::of($left)->minus($right)->__toString());
    }

    public static function multiply(string $left, string $right): string
    {
        return self::scale(BigDecimal::of($left)->multipliedBy($right)->__toString());
    }

    public static function divide(string $left, string $right): string
    {
        if (BigDecimal::of($right)->isZero()) {
            throw new InvalidArgumentException('Division by zero.');
        }
        return BigDecimal::of($left)->dividedBy($right, self::scaleValue(), RoundingMode::HALF_UP)->__toString();
    }

    public static function compare(string $left, string $right): int
    {
        return BigDecimal::of($left)->compareTo($right);
    }

    public static function equals(string $left, string $right): bool
    {
        return self::compare($left, $right) === 0;
    }

    public static function isNegative(string $value): bool
    {
        return self::compare($value, '0') < 0;
    }

    public static function scale(string $value, ?int $scale = null): string
    {
        return BigDecimal::of($value)->toScale($scale ?? self::scaleValue(), RoundingMode::HALF_UP)->__toString();
    }

    private static function scaleValue(): int
    {
        return (int) config('accounting.scale', 4);
    }
}
