<?php
declare(strict_types=1);

require_once __DIR__ . '/bootstrap.php';
require_once __DIR__ . '/db.php';
require_once __DIR__ . '/wheel_helpers.php';

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

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

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

$wheelCfg = mocker_wheel_load_config();
$SITE_WHEEL_COOLDOWN = $wheelCfg['cooldown_seconds'];
$SITE_WHEEL_PRIZES = $wheelCfg['prizes'];
$SITE_WHEEL_ENABLED = $wheelCfg['enabled'] ?? true;

if ($method === 'GET') {
    if ($uid <= 0) {
        echo json_encode(
            [
                'ok' => true,
                'authenticated' => false,
                'prizes' => $SITE_WHEEL_PRIZES,
                'cooldown_hours' => $wheelCfg['cooldown_hours'],
                'enabled' => $SITE_WHEEL_ENABLED,
            ],
            JSON_UNESCAPED_UNICODE
        );
        exit;
    }
    $st = $pdo->prepare('SELECT last_wheel_spin_at, 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;
    }
    $now = time();
    $last = isset($row['last_wheel_spin_at']) ? (int) $row['last_wheel_spin_at'] : 0;
    $nextAt = $last > 0 ? $last + $SITE_WHEEL_COOLDOWN : 0;
    $canSpin = $last <= 0 || $now >= $nextAt;
    $secondsLeft = $canSpin ? 0 : max(0, $nextAt - $now);
    echo json_encode(
        [
            'ok' => true,
            'authenticated' => true,
            'prizes' => $SITE_WHEEL_PRIZES,
            'cooldown_hours' => $wheelCfg['cooldown_hours'],
            'enabled' => $SITE_WHEEL_ENABLED,
            'coins' => (int) $row['coins'],
            'can_spin' => $canSpin,
            'last_spin_at' => $last > 0 ? $last : null,
            'next_spin_at' => $canSpin ? null : $nextAt,
            'seconds_left' => $secondsLeft,
        ],
        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;
}

$now = time();
$wheelCfg = mocker_wheel_load_config();
$SITE_WHEEL_COOLDOWN = $wheelCfg['cooldown_seconds'];
$SITE_WHEEL_PRIZES = $wheelCfg['prizes'];

if (!($wheelCfg['enabled'] ?? true)) {
    http_response_code(403);
    echo json_encode(['ok' => false, 'error' => 'disabled'], JSON_UNESCAPED_UNICODE);
    exit;
}

try {
    $pdo->beginTransaction();
    $st = $pdo->prepare('SELECT id, last_wheel_spin_at, coins FROM users WHERE id = :id LIMIT 1');
    $st->execute([':id' => $uid]);
    $row = $st->fetch();
    if (!$row) {
        $pdo->rollBack();
        http_response_code(404);
        echo json_encode(['ok' => false, 'error' => 'user'], JSON_UNESCAPED_UNICODE);
        exit;
    }
    $last = isset($row['last_wheel_spin_at']) ? (int) $row['last_wheel_spin_at'] : 0;

    $segment = random_int(0, 2);
    $amount = $SITE_WHEEL_PRIZES[$segment];
    $threshold = $now - $SITE_WHEEL_COOLDOWN;

    $up = $pdo->prepare(
        'UPDATE users
         SET coins = coins + :add, last_wheel_spin_at = :t
         WHERE id = :id
           AND (
               last_wheel_spin_at IS NULL
               OR last_wheel_spin_at <= 0
               OR last_wheel_spin_at <= :threshold
           )'
    );
    $up->execute([':add' => $amount, ':t' => $now, ':id' => $uid, ':threshold' => $threshold]);
    if ($up->rowCount() !== 1) {
        $stCooldown = $pdo->prepare('SELECT last_wheel_spin_at FROM users WHERE id = :id LIMIT 1');
        $stCooldown->execute([':id' => $uid]);
        $lastCurrent = (int) (($stCooldown->fetch()['last_wheel_spin_at'] ?? 0));
        $pdo->rollBack();
        $nextAt = $lastCurrent > 0 ? ($lastCurrent + $SITE_WHEEL_COOLDOWN) : ($now + $SITE_WHEEL_COOLDOWN);
        http_response_code(429);
        echo json_encode(
            [
                'ok' => false,
                'error' => 'cooldown',
                'next_spin_at' => $nextAt,
                'seconds_left' => max(0, $nextAt - $now),
            ],
            JSON_UNESCAPED_UNICODE
        );
        exit;
    }

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

    try {
        $insHistory = $pdo->prepare(
            'INSERT INTO wheel_spins (user_id, segment, amount, created_at) VALUES (:uid, :segment, :amount, :t)'
        );
        $insHistory->execute([
            ':uid' => $uid,
            ':segment' => $segment,
            ':amount' => $amount,
            ':t' => $now,
        ]);
    } catch (Throwable $e) {

        try {
            $pdo->exec(
                'CREATE TABLE IF NOT EXISTS wheel_spins (
                    id INTEGER PRIMARY KEY AUTOINCREMENT,
                    user_id INTEGER NOT NULL,
                    segment INTEGER NOT NULL,
                    amount INTEGER NOT NULL,
                    created_at INTEGER NOT NULL,
                    FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
                )'
            );
            $pdo->exec('CREATE INDEX IF NOT EXISTS idx_wheel_spins_user ON wheel_spins(user_id, created_at DESC)');
            $insHistoryRetry = $pdo->prepare(
                'INSERT INTO wheel_spins (user_id, segment, amount, created_at) VALUES (:uid, :segment, :amount, :t)'
            );
            $insHistoryRetry->execute([
                ':uid' => $uid,
                ':segment' => $segment,
                ':amount' => $amount,
                ':t' => $now,
            ]);
        } catch (Throwable $e2) {

        }
    }

    $pdo->commit();
} catch (Throwable $e) {
    if (isset($pdo) && $pdo->inTransaction()) {
        $pdo->rollBack();
    }
    http_response_code(500);
    echo json_encode(['ok' => false, 'error' => 'server'], JSON_UNESCAPED_UNICODE);
    exit;
}

echo json_encode(
    [
        'ok' => true,
        'segment' => $segment,
        'amount' => $amount,
        'coins' => $newCoins,
        'next_spin_at' => $now + $SITE_WHEEL_COOLDOWN,
    ],
    JSON_UNESCAPED_UNICODE
);
