<?php
declare(strict_types=1);

require_once __DIR__ . '/slot_engine.php';
require_once __DIR__ . '/roulette_engine.php';

const MOCKER_GAMES_KEYS = ['slot', 'roulette'];

function mocker_games_settings_default(): array
{
    return [
        'winChancePercent' => [
            'slot' => 100,
            'roulette' => 100,
        ],
        'updatedAt' => 0,
    ];
}

function mocker_games_settings_path(): string
{
    return dirname(__DIR__) . '/data/games_settings.json';
}

function mocker_games_settings_load(): array
{
    $defaults = mocker_games_settings_default();
    $path = mocker_games_settings_path();
    if (!is_readable($path)) {
        return $defaults;
    }
    $j = json_decode((string) file_get_contents($path), true);
    if (!is_array($j)) {
        return $defaults;
    }
    $pctIn = is_array($j['winChancePercent'] ?? null) ? $j['winChancePercent'] : [];
    $pct = [];
    foreach (MOCKER_GAMES_KEYS as $key) {
        $raw = $pctIn[$key] ?? $defaults['winChancePercent'][$key];
        $n = (int) $raw;
        if ($n < 0) {
            $n = 0;
        }
        if ($n > 100) {
            $n = 100;
        }
        $pct[$key] = $n;
    }

    return [
        'winChancePercent' => $pct,
        'updatedAt' => isset($j['updatedAt']) ? (int) $j['updatedAt'] : 0,
    ];
}

/** @param array<string, mixed> $input */
function mocker_games_settings_save(array $input): array
{
    $defaults = mocker_games_settings_default();
    $pctIn = is_array($input['winChancePercent'] ?? null) ? $input['winChancePercent'] : $input;
    $pct = [];
    foreach (MOCKER_GAMES_KEYS as $key) {
        $raw = $pctIn[$key] ?? $defaults['winChancePercent'][$key];
        $n = (int) $raw;
        if ($n < 0) {
            $n = 0;
        }
        if ($n > 100) {
            $n = 100;
        }
        $pct[$key] = $n;
    }
    $out = [
        'winChancePercent' => $pct,
        'updatedAt' => time(),
    ];

    $path = mocker_games_settings_path();
    $dir = dirname($path);
    if (!is_dir($dir) && !mkdir($dir, 0755, true) && !is_dir($dir)) {
        throw new RuntimeException('data klasörü oluşturulamadı');
    }
    $json = json_encode($out, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
    if ($json === false || file_put_contents($path, $json) === false) {
        throw new RuntimeException('games_settings.json yazılamadı');
    }

    return $out;
}

function mocker_games_win_chance_percent(string $gameKey): int
{
    $settings = mocker_games_settings_load();
    $key = strtolower(trim($gameKey));
    $pct = (int) ($settings['winChancePercent'][$key] ?? 100);
    if ($pct < 0) {
        return 0;
    }
    if ($pct > 100) {
        return 100;
    }

    return $pct;
}

function mocker_games_win_allowed(string $gameKey): bool
{
    $pct = mocker_games_win_chance_percent($gameKey);
    if ($pct >= 100) {
        return true;
    }
    if ($pct <= 0) {
        return false;
    }

    return random_int(1, 100) <= $pct;
}

function mocker_games_slot_spin_reels(): array
{
    for ($i = 0; $i < 32; $i++) {
        $reels = slot_spin_reels();
        $eval = slot_evaluate_spin($reels);
        $wouldWin = (int) ($eval['multiplier'] ?? 0) > 0 || !empty($eval['jackpotSymbols']);
        if (!$wouldWin) {
            return $reels;
        }
        if (mocker_games_win_allowed('slot')) {
            return $reels;
        }
    }
    for ($i = 0; $i < 64; $i++) {
        $reels = slot_spin_reels();
        $eval = slot_evaluate_spin($reels);
        if ((int) ($eval['multiplier'] ?? 0) === 0 && empty($eval['jackpotSymbols'])) {
            return $reels;
        }
    }

    return slot_spin_reels();
}

function mocker_games_roulette_spin_for_bet(string $betType, mixed $betValueRaw): int
{
    for ($i = 0; $i < 24; $i++) {
        $winning = roulette_spin_number();
        $eval = roulette_evaluate_bet($betType, $betValueRaw, $winning);
        if (!$eval['ok']) {
            return $winning;
        }
        $mult = (int) ($eval['mult'] ?? 0);
        if ($mult === 0) {
            return $winning;
        }
        if (mocker_games_win_allowed('roulette')) {
            return $winning;
        }
    }
    for ($i = 0; $i < 48; $i++) {
        $winning = roulette_spin_number();
        $eval = roulette_evaluate_bet($betType, $betValueRaw, $winning);
        if ($eval['ok'] && (int) ($eval['mult'] ?? 0) === 0) {
            return $winning;
        }
    }

    return roulette_spin_number();
}
