<?php
declare(strict_types=1);

require_once __DIR__ . '/bootstrap.php';
require_once __DIR__ . '/db.php';
require_once __DIR__ . '/ip.php';
require_once __DIR__ . '/user_auth_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();

const SITE_REGISTER_BONUS_COINS = 150;

$input = json_decode((string) file_get_contents('php://input'), true) ?: [];
$username = trim((string) ($input['username'] ?? ''));
$email = trim((string) ($input['email'] ?? ''));
$password = (string) ($input['password'] ?? '');
$phoneRaw = trim((string) ($input['phone'] ?? ''));
$phone = mocker_normalize_phone($phoneRaw);

if (strlen($username) < 2 || strlen($username) > 64) {
    http_response_code(400);
    echo json_encode(['ok' => false, 'error' => 'username'], JSON_UNESCAPED_UNICODE);
    exit;
}
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
    http_response_code(400);
    echo json_encode(['ok' => false, 'error' => 'email'], JSON_UNESCAPED_UNICODE);
    exit;
}
if ($phone === null) {
    http_response_code(400);
    echo json_encode(['ok' => false, 'error' => 'phone'], JSON_UNESCAPED_UNICODE);
    exit;
}
if (strlen($password) < 8) {
    http_response_code(400);
    echo json_encode(['ok' => false, 'error' => 'password'], JSON_UNESCAPED_UNICODE);
    exit;
}

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

$hash = password_hash($password, PASSWORD_DEFAULT);
$now = time();
$coins = SITE_REGISTER_BONUS_COINS;
$clientIp = mocker_client_ip();

try {
    $st = $pdo->prepare(
        'INSERT INTO users (username, email, password_hash, phone, coins, created_at, last_login_at, last_seen_at, register_ip, last_login_ip, profile_completed_at) VALUES (:u, :e, :p, :ph, :c, :t, :t, :t2, :rip, :lip, :pc)'
    );
    $st->execute([
        ':u' => $username,
        ':e' => $email,
        ':p' => $hash,
        ':ph' => $phone,
        ':c' => $coins,
        ':t' => $now,
        ':t2' => $now,
        ':rip' => $clientIp !== '' ? $clientIp : null,
        ':lip' => $clientIp !== '' ? $clientIp : null,
        ':pc' => $now,
    ]);
    $id = (int) $pdo->lastInsertId();
} catch (PDOException $e) {
    if ($e->getCode() === '23000' || str_contains($e->getMessage(), 'UNIQUE')) {
        http_response_code(409);
        echo json_encode(['ok' => false, 'error' => 'taken'], JSON_UNESCAPED_UNICODE);
        exit;
    }
    http_response_code(500);
    echo json_encode(['ok' => false, 'error' => 'server'], JSON_UNESCAPED_UNICODE);
    exit;
}

session_regenerate_id(true);
$_SESSION['mocker_user_id'] = $id;

echo json_encode(
    [
        'ok' => true,
        'user' => [
            'id' => $id,
            'username' => $username,
            'coins' => $coins,
            'bonus' => SITE_REGISTER_BONUS_COINS,
        ],
    ],
    JSON_UNESCAPED_UNICODE
);
