<?php

declare(strict_types=1);

namespace app\common\library\game;

use app\common\service\GameHotDataRedis;

/**
 * 移动端快捷筹码（固定 1–6 档）及默认选中档位，对应 game_config：`bet_chips`（JSON）、`default_bet_chip_id`（int）。
 */
final class BetChips
{
    public const CONFIG_KEY_CHIPS = 'bet_chips';

    public const CONFIG_KEY_DEFAULT_ID = 'default_bet_chip_id';

    /**
     * @return array<int, string> 键 1..6 => 两位小数字符串面额
     */
    public static function defaultChipAmounts(): array
    {
        return [
            1 => '1.00',
            2 => '5.00',
            3 => '10.00',
            4 => '25.00',
            5 => '50.00',
            6 => '100.00',
        ];
    }

    /**
     * @return array{map: array<int, string>, default_id: int}
     */
    public static function resolveFromHotData(): array
    {
        $rowChips = GameHotDataRedis::gameConfigRow(self::CONFIG_KEY_CHIPS);
        $rowDefault = GameHotDataRedis::gameConfigRow(self::CONFIG_KEY_DEFAULT_ID);
        $rawJson = $rowChips !== null ? ($rowChips['config_value'] ?? null) : null;
        $map = self::parseChipsJson($rawJson);

        $defaultRaw = $rowDefault !== null ? ($rowDefault['config_value'] ?? null) : null;
        $defaultId = filter_var(trim('' . $defaultRaw), FILTER_VALIDATE_INT);
        if ($defaultId === false || $defaultId < 1 || $defaultId > 6) {
            $defaultId = 1;
        }
        $amt = $map[$defaultId] ?? null;
        if ($amt === null || !is_numeric($amt) || bccomp(bcadd($amt, '0', 2), '0', 2) <= 0) {
            $defaultId = self::firstPositiveBetId($map);
        }

        return ['map' => $map, 'default_id' => $defaultId];
    }

    /**
     * @param array<int, string> $map
     */
    public static function amountForBetId(int $betId, array $map): ?string
    {
        if ($betId < 1 || $betId > 6) {
            return null;
        }
        if (!isset($map[$betId])) {
            return null;
        }
        $amt = $map[$betId];
        if (!is_numeric($amt) || bccomp(bcadd($amt, '0', 2), '0', 2) <= 0) {
            return null;
        }

        return bcadd($amt, '0', 2);
    }

    /**
     * lobbyInit 用：筹码为字典，键为标识字符串 `"1"`…`"6"`，值为两位小数字符串面额。
     *
     * @return array{chips: array<string, string>, default_bet_chip_id: int}
     */
    public static function lobbyChipsPayload(): array
    {
        $resolved = self::resolveFromHotData();
        $chips = [];
        foreach ($resolved['map'] as $id => $amount) {
            $chips['' . $id] = $amount;
        }

        return [
            'chips' => $chips,
            'default_bet_chip_id' => $resolved['default_id'],
        ];
    }

    /**
     * @param mixed $rawJson
     * @return array<int, string>
     */
    private static function parseChipsJson($rawJson): array
    {
        $defaults = self::defaultChipAmounts();
        $parsed = [];
        if (is_string($rawJson) && $rawJson !== '') {
            $decoded = json_decode($rawJson, true);
            if (is_array($decoded)) {
                foreach ($decoded as $k => $v) {
                    $id = filter_var($k, FILTER_VALIDATE_INT);
                    if ($id === false || $id < 1 || $id > 6) {
                        continue;
                    }
                    $amtRaw = trim('' . $v);
                    if (!is_numeric($amtRaw) || bccomp(bcadd($amtRaw, '0', 2), '0', 2) <= 0) {
                        continue;
                    }
                    $parsed[$id] = bcadd($amtRaw, '0', 2);
                }
            }
        }
        $out = [];
        foreach ($defaults as $id => $def) {
            if (isset($parsed[$id])) {
                $out[$id] = $parsed[$id];
            } else {
                $out[$id] = $def;
            }
        }
        ksort($out);

        return $out;
    }

    /**
     * @param array<int, string> $map
     */
    private static function firstPositiveBetId(array $map): int
    {
        for ($i = 1; $i <= 6; $i++) {
            if (!isset($map[$i])) {
                continue;
            }
            $a = $map[$i];
            if (is_numeric($a) && bccomp(bcadd($a, '0', 2), '0', 2) > 0) {
                return $i;
            }
        }

        return 1;
    }
}
