<?php
declare(strict_types=1);

require_once __DIR__ . '/bootstrap.php';
require_once __DIR__ . '/db.php';
require_once __DIR__ . '/slot_engine.php';
require_once __DIR__ . '/slot_jackpots.php';
require_once __DIR__ . '/games_settings_helpers.php';
require_once __DIR__ . '/level_lib.php';

header('Content-Type: application/json; charset=utf-8');

$uid = isset($_SESSION['mocker_user_id']) ? (int) $_SESSION['mocker_user_id'] : 0;
$method = $_SERVER['REQUEST_METHOD'] ?? 'GET';

try {
    $pdo = mocker_db();
} catch (Throwable $e) {
    http_response_code(503);
    echo json_encode(['ok' => false, 'error' => 'db'], JSON_UNESCAPED_UNICODE);
    exit;
}

$paytable = slot_paytable_public();
$jackpots = slot_jackpots_public(slot_jackpots_read());

if ($method === 'GET') {
    if ($uid <= 0) {
        echo json_encode(
            [
                'ok' => true,
                'authenticated' => false,
                'minBet' => SLOT_MIN_BET,
                'maxBet' => SLOT_MAX_BET,
                'paytable' => $paytable,
                'jackpots' => $jackpots,
            ],
            JSON_UNESCAPED_UNICODE
        );
        exit;
    }
    $st = $pdo->prepare('SELECT coins FROM users WHERE id = :id LIMIT 1');
    $st->execute([':id' => $uid]);
    $row = $st->fetch();
    if (!$row) {
        http_response_code(404);
        echo json_encode(['ok' => false, 'error' => 'user'], JSON_UNESCAPED_UNICODE);
        exit;
    }
    $coins = (int) $row['coins'];
    echo json_encode(
        [
            'ok' => true,
            'authenticated' => true,
            'coins' => $coins,
            'minBet' => SLOT_MIN_BET,
            'maxBet' => SLOT_MAX_BET,
            'paytable' => $paytable,
            'jackpots' => $jackpots,
        ],
        JSON_UNESCAPED_UNICODE
    );
    exit;
}

if ($method !== 'POST') {
    http_response_code(405);
    echo json_encode(['ok' => false, 'error' => 'method'], JSON_UNESCAPED_UNICODE);
    exit;
}

mocker_require_csrf_post();

if ($uid <= 0) {
    http_response_code(401);
    echo json_encode(['ok' => false, 'error' => 'auth'], JSON_UNESCAPED_UNICODE);
    exit;
}

$input = json_decode((string) file_get_contents('php://input'), true) ?: [];
$action = strtolower(trim((string) ($input['action'] ?? '')));

if ($action !== 'spin') {
    echo json_encode(['ok' => false, 'error' => 'action'], JSON_UNESCAPED_UNICODE);
    exit;
}

$bet = (int) ($input['bet'] ?? 0);
if ($bet < SLOT_MIN_BET || $bet > SLOT_MAX_BET) {
    echo json_encode(['ok' => false, 'error' => 'bet_range', 'min' => SLOT_MIN_BET, 'max' => SLOT_MAX_BET], JSON_UNESCAPED_UNICODE);
    exit;
}

try {
    $pdo->beginTransaction();

    $stUser = $pdo->prepare('SELECT coins FROM users WHERE id = :id LIMIT 1');
    $stUser->execute([':id' => $uid]);
    $urow = $stUser->fetch();
    if (!$urow) {
        $pdo->rollBack();
        http_response_code(404);
        echo json_encode(['ok' => false, 'error' => 'user'], JSON_UNESCAPED_UNICODE);
        exit;
    }
    $coins = (int) $urow['coins'];
    if ($coins < $bet) {
        $pdo->rollBack();
        echo json_encode(['ok' => false, 'error' => 'coins'], JSON_UNESCAPED_UNICODE);
        exit;
    }

    $upd = $pdo->prepare('UPDATE users SET coins = coins - :b WHERE id = :id AND coins >= :b');
    $upd->execute([':b' => $bet, ':id' => $uid]);
    if ($upd->rowCount() !== 1) {
        $pdo->rollBack();
        echo json_encode(['ok' => false, 'error' => 'coins'], JSON_UNESCAPED_UNICODE);
        exit;
    }

    $jpState = slot_jackpots_contribute($bet);

    $reels = mocker_games_slot_spin_reels();
    $eval = slot_evaluate_spin($reels);
    $mult = (int) ($eval['multiplier'] ?? 0);
    $linePayout = $mult > 0 ? (int) ($bet * $mult) : 0;

    $jackpotWin = null;
    if (!empty($eval['jackpotSymbols'])) {
        $jackpotWin = slot_jackpots_award_symbol_win();
    } else {
        $jackpotWin = slot_jackpots_roll_win($bet);
    }

    if ($jackpotWin !== null && !mocker_games_win_allowed('slot')) {
        $jackpotWin = null;
    }

    $jackpotPayout = $jackpotWin !== null ? (int) ($jackpotWin['amount'] ?? 0) : 0;
    $payout = $linePayout + $jackpotPayout;

    if ($payout > 0) {
        $up2 = $pdo->prepare('UPDATE users SET coins = coins + :p WHERE id = :id');
        $up2->execute([':p' => $payout, ':id' => $uid]);
    }

    $reelsJson = json_encode($reels, JSON_UNESCAPED_UNICODE);
    if ($reelsJson === false) {
        throw new RuntimeException('reels json');
    }

    try {
        $roundId = 0;
        $ins = $pdo->prepare(
            'INSERT INTO slot_rounds (user_id, created_at, bet, reels_json, multiplier, payout)
             VALUES (:uid, :t, :bet, :rj, :m, :pay)'
        );
        $ins->execute([
            ':uid' => $uid,
            ':t' => time(),
            ':bet' => $bet,
            ':rj' => $reelsJson,
            ':m' => $mult,
            ':pay' => $payout,
        ]);
        $roundId = (int) $pdo->lastInsertId();
        if ($roundId > 0) {
            mocker_level_award_game_round($pdo, $uid, 'slot', $roundId);
        }
    } catch (Throwable $e) {
        error_log('slot_rounds: ' . $e->getMessage());
    }

    $pdo->commit();

    $st2 = $pdo->prepare('SELECT coins FROM users WHERE id = :id LIMIT 1');
    $st2->execute([':id' => $uid]);
    $coinsAfter = (int) ($st2->fetch()['coins'] ?? 0);

    $jpAfter = slot_jackpots_public(slot_jackpots_read());
    $message = slot_spin_message($eval, $linePayout, $jackpotWin);

    echo json_encode(
        [
            'ok' => true,
            'coins' => $coinsAfter,
            'reels' => $reels,
            'multiplier' => $mult,
            'winType' => $eval['winType'] ?? 'none',
            'linePayout' => $linePayout,
            'payout' => $payout,
            'jackpot' => $jackpotWin,
            'jackpots' => $jpAfter,
            'message' => $message,
        ],
        JSON_UNESCAPED_UNICODE
    );
} catch (Throwable $e) {
    if ($pdo->inTransaction()) {
        $pdo->rollBack();
    }
    error_log('game_slot: ' . $e->getMessage());
    http_response_code(500);
    echo json_encode(['ok' => false, 'error' => 'server'], JSON_UNESCAPED_UNICODE);
}
