<?php

declare(strict_types=1);

require_once __DIR__ . '/bootstrap.php';
require_once __DIR__ . '/db.php';
require_once __DIR__ . '/ticket_lib.php';
require_once __DIR__ . '/level_lib.php';

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

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

mocker_require_csrf_post();

$uid = isset($_SESSION['mocker_user_id']) ? (int) $_SESSION['mocker_user_id'] : 0;
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) ?: [];
$eventId = (int) ($input['eventId'] ?? 0);
if ($eventId <= 0) {
    http_response_code(400);
    echo json_encode(['ok' => false, 'error' => 'event'], JSON_UNESCAPED_UNICODE);
    exit;
}

$now = time();

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

try {
    $pdo->beginTransaction();

    $st = $pdo->prepare(
        'SELECT id, ticket_cost, max_entries_per_user, status, ends_at FROM ticket_events WHERE id = :id LIMIT 1'
    );
    $st->execute([':id' => $eventId]);
    $ev = $st->fetch(PDO::FETCH_ASSOC);
    if (!$ev) {
        $pdo->rollBack();
        http_response_code(404);
        echo json_encode(['ok' => false, 'error' => 'not_found'], JSON_UNESCAPED_UNICODE);
        exit;
    }
    if ((string) $ev['status'] !== 'open') {
        $pdo->rollBack();
        http_response_code(400);
        echo json_encode(['ok' => false, 'error' => 'closed'], JSON_UNESCAPED_UNICODE);
        exit;
    }
    if ($ev['ends_at'] !== null && (int) $ev['ends_at'] > 0 && (int) $ev['ends_at'] <= $now) {
        $pdo->prepare("UPDATE ticket_events SET status = 'closed' WHERE id = :id")->execute([':id' => $eventId]);
        $pdo->rollBack();
        http_response_code(400);
        echo json_encode(['ok' => false, 'error' => 'ended'], JSON_UNESCAPED_UNICODE);
        exit;
    }

    $maxPerUser = max(1, min(100, (int) $ev['max_entries_per_user']));
    $cntSt = $pdo->prepare('SELECT COUNT(*) FROM ticket_entries WHERE event_id = :eid AND user_id = :uid');
    $cntSt->execute([':eid' => $eventId, ':uid' => $uid]);
    $userCount = (int) $cntSt->fetchColumn();
    if ($userCount >= $maxPerUser) {
        $pdo->rollBack();
        http_response_code(400);
        echo json_encode(['ok' => false, 'error' => 'limit'], JSON_UNESCAPED_UNICODE);
        exit;
    }

    $cost = max(0, (int) $ev['ticket_cost']);
    if ($cost > 0) {
        $up = $pdo->prepare('UPDATE users SET coins = coins - :c WHERE id = :id AND coins >= :c2');
        $up->execute([':c' => $cost, ':id' => $uid, ':c2' => $cost]);
        if ($up->rowCount() !== 1) {
            $pdo->rollBack();
            http_response_code(400);
            echo json_encode(['ok' => false, 'error' => 'coins'], JSON_UNESCAPED_UNICODE);
            exit;
        }
    }

    $code = mocker_ticket_generate_code($pdo);
    $pdo->prepare(
        'INSERT INTO ticket_entries (event_id, user_id, ticket_code, is_winner, created_at) VALUES (:eid, :uid, :code, 0, :t)'
    )->execute([':eid' => $eventId, ':uid' => $uid, ':code' => $code, ':t' => $now]);
    $entryId = (int) $pdo->lastInsertId();
    if ($entryId > 0) {
        try {
            mocker_level_award_ticket_join($pdo, $uid, $entryId);
        } catch (Throwable $e) {
            /* ignore level errors */
        }
    }

    $balSt = $pdo->prepare('SELECT coins FROM users WHERE id = :id');
    $balSt->execute([':id' => $uid]);
    $coins = (int) $balSt->fetchColumn();

    $pdo->commit();

    echo json_encode(
        [
            'ok' => true,
            'ticketCode' => $code,
            'coins' => $coins,
            'entriesCount' => $userCount + 1,
        ],
        JSON_UNESCAPED_UNICODE
    );
} catch (Throwable $e) {
    if ($pdo->inTransaction()) {
        $pdo->rollBack();
    }
    http_response_code(500);
    echo json_encode(['ok' => false, 'error' => 'fail'], JSON_UNESCAPED_UNICODE);
}
