<?php

declare(strict_types=1);

namespace App\Support;

use App\Models\DberpSystemProfile;
use Illuminate\Support\Facades\Schema;

/**
 * 系统档案中的展示类参数（默认货币、金额/数量小数位）统一读取入口。
 */
final class DberpSystemProfileSettings
{
    public static function defaultCurrencyCode(): string
    {
        return once(function (): string {
            $fromProfile = self::readProfileColumn('default_currency_code');

            if (is_string($fromProfile)) {
                $normalized = DberpCurrencySelectOptions::normalizeCode($fromProfile);

                if ($normalized !== null) {
                    return $normalized;
                }
            }

            return DberpCurrencySelectOptions::configuredDefaultCode();
        });
    }

    public static function amountDecimalPlaces(): int
    {
        return self::displayDecimals()['amount'];
    }

    public static function quantityDecimalPlaces(): int
    {
        return self::displayDecimals()['quantity'];
    }

    /**
     * @return array{amount: int, quantity: int}
     */
    private static function displayDecimals(): array
    {
        return once(function (): array {
            $fallbackAmount = self::configPrecision('amount', 2);
            $fallbackQuantity = self::configPrecision('quantity', 2);

            try {
                $table = (new DberpSystemProfile)->getTable();

                if (Schema::hasTable($table)) {
                    $profile = DberpSystemProfile::query()->first([
                        'amount_decimal_places',
                        'quantity_decimal_places',
                    ]);

                    if ($profile !== null) {
                        return [
                            'amount' => self::clampDecimals((int) $profile->amount_decimal_places),
                            'quantity' => self::clampDecimals((int) $profile->quantity_decimal_places),
                        ];
                    }
                }
            } catch (\Throwable) {
            }

            return [
                'amount' => $fallbackAmount,
                'quantity' => $fallbackQuantity,
            ];
        });
    }

    private static function readProfileColumn(string $column): mixed
    {
        try {
            $table = (new DberpSystemProfile)->getTable();

            if (! Schema::hasTable($table)) {
                return null;
            }

            return DberpSystemProfile::query()->value($column);
        } catch (\Throwable) {
            return null;
        }
    }

    private static function configPrecision(string $key, int $default): int
    {
        /** @var array<string, int|string>|null $map */
        $map = config('dberp.number_precision');
        /** @var int|string|null $raw */
        $raw = \is_array($map) ? ($map[$key] ?? null) : null;

        if ($raw === null || $raw === '') {
            return $default;
        }

        return self::clampDecimals((int) $raw);
    }

    private static function clampDecimals(int $decimals): int
    {
        return max(0, min(12, $decimals));
    }
}
