<?php

declare(strict_types=1);

/**
 * 站內 N 幣功能設定（JSON）。
 * 路徑：fate/data/fate_ncoin_settings.json
 */

function fate_ncoin_settings_path(): string
{
    return dirname(__DIR__) . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'fate_ncoin_settings.json';
}

function fate_ncoin_display_name_default(): string
{
    return 'N 幣';
}

function fate_ncoin_normalize_display_name(string $raw): string
{
    $name = preg_replace('/\s+/u', ' ', trim($raw)) ?? '';
    $name = preg_replace('/[\x00-\x1F\x7F]/u', '', $name) ?? '';
    if ($name === '') {
        return fate_ncoin_display_name_default();
    }
    if (mb_strlen($name, 'UTF-8') > 20) {
        $name = mb_substr($name, 0, 20, 'UTF-8');
    }

    return $name !== '' ? $name : fate_ncoin_display_name_default();
}

/** 前台／後台顯示用站內貨幣名稱（預設「N 幣」）。 */
function fate_ncoin_display_name(): string
{
    $cfg = fate_ncoin_settings();

    return fate_ncoin_normalize_display_name((string) ($cfg['currency_name'] ?? ''));
}

/** 金額 + 貨幣名稱，例如「1,234 星幣」。 */
function fate_ncoin_amount_with_unit(int $amount): string
{
    return number_format($amount) . ' ' . fate_ncoin_display_name();
}

/** @return array{currency_name:string,transfer_enabled:bool,transfer_fee_pct:int,transfer_reserve:int} */
function fate_ncoin_settings_default(): array
{
    return [
        'currency_name' => fate_ncoin_display_name_default(),
        'transfer_enabled' => true,
        'transfer_fee_pct' => 0,
        'transfer_reserve' => 100,
    ];
}

/** @return array{currency_name:string,transfer_enabled:bool,transfer_fee_pct:int,transfer_reserve:int} */
function fate_ncoin_settings(): array
{
    $d = fate_ncoin_settings_default();
    $p = fate_ncoin_settings_path();
    if (is_file($p)) {
        $raw = (string) file_get_contents($p);
        $j = json_decode($raw, true);
        if (is_array($j)) {
            if (array_key_exists('currency_name', $j) && is_string($j['currency_name'])) {
                $d['currency_name'] = fate_ncoin_normalize_display_name($j['currency_name']);
            }
            if (array_key_exists('transfer_enabled', $j)) {
                $d['transfer_enabled'] = (bool) $j['transfer_enabled'];
            }
            foreach (['transfer_fee_pct', 'transfer_reserve'] as $nk) {
                if (array_key_exists($nk, $j)) {
                    $d[$nk] = max(0, (int) $j[$nk]);
                }
            }
        }
    }

    $d['transfer_fee_pct'] = max(0, min(100, (int) $d['transfer_fee_pct']));
    $d['transfer_reserve'] = max(0, (int) $d['transfer_reserve']);

    return $d;
}

/**
 * @param array<string,mixed> $patch
 */
function fate_ncoin_settings_save(array $patch): bool
{
    $cur = fate_ncoin_settings();
    if (array_key_exists('currency_name', $patch)) {
        $cur['currency_name'] = fate_ncoin_normalize_display_name((string) $patch['currency_name']);
    }
    if (array_key_exists('transfer_enabled', $patch)) {
        $cur['transfer_enabled'] = (bool) $patch['transfer_enabled'];
    }
    if (array_key_exists('transfer_fee_pct', $patch)) {
        $cur['transfer_fee_pct'] = max(0, min(100, (int) $patch['transfer_fee_pct']));
    }
    if (array_key_exists('transfer_reserve', $patch)) {
        $cur['transfer_reserve'] = max(0, (int) $patch['transfer_reserve']);
    }

    $dir = dirname(fate_ncoin_settings_path());
    if (!is_dir($dir) && !mkdir($dir, 0755, true) && !is_dir($dir)) {
        return false;
    }

    $payload = json_encode($cur, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
    if ($payload === false) {
        return false;
    }

    return file_put_contents(fate_ncoin_settings_path(), $payload . "\n", LOCK_EX) !== false;
}
