<?php
declare(strict_types=1);

ini_set('display_errors', '0');
require __DIR__ . '/backend.php';
date_default_timezone_set('Europe/Moscow');
header('X-Content-Type-Options: nosniff');
header('X-Frame-Options: DENY');
header('Referrer-Policy: strict-origin-when-cross-origin');

$path = parse_url($_SERVER['REQUEST_URI'] ?? '/', PHP_URL_PATH);
$path = rtrim(is_string($path) ? $path : '', '/') ?: '/';
$method = $_SERVER['REQUEST_METHOD'] ?? 'GET';

if ($path === '/' || $path === '/admin') {
    if ($path === '/admin') {
        header('X-Robots-Tag: noindex, nofollow');
        header('Cache-Control: no-store');
    }
    header('Content-Type: text/html; charset=UTF-8');
    readfile(__DIR__ . ($path === '/admin' ? '/admin.html' : '/home.html'));
    exit;
}

header('Cache-Control: no-store, private');
try {
    if (!str_starts_with($path, '/api/')) {
        fail(404, 'Страница не найдена.');
    }
    $isMedia = preg_match('~^/api/media/([a-f0-9]{32})$~D', $path, $matches);
    $allowed = match ($path) {
        '/api/admin/auth', '/api/auth', '/api/space', '/api/admin/space' => ['GET', 'POST'],
        '/api/admin/media' => ['POST', 'DELETE'],
        default => $isMedia ? ['GET', 'HEAD'] : [],
    };
    if (!$allowed) fail(404, 'Адрес не найден.');
    if (!in_array($method, $allowed, true)) fail(405, 'Метод не поддерживается.');

    $input = [];
    if (!in_array($method, ['GET', 'HEAD'], true)) {
        $origin = $_SERVER['HTTP_ORIGIN'] ?? '';
        $host = $_SERVER['HTTP_HOST'] ?? '';
        $fetchSite = $_SERVER['HTTP_SEC_FETCH_SITE'] ?? '';
        if ($fetchSite === 'cross-site' || ($origin !== '' && !in_array($origin, ["https://$host", "http://$host"], true))) {
            fail(403, 'Обнови страницу и повтори действие на сайте.');
        }
        $type = strtolower(trim(explode(';', $_SERVER['CONTENT_TYPE'] ?? '', 2)[0]));
        if ($type === 'application/json') {
            try {
                $input = json_decode(file_get_contents('php://input', false, null, 0, 1048577), true, 64, JSON_THROW_ON_ERROR);
            } catch (JsonException) {
                fail(400, 'Не удалось прочитать запрос.');
            }
            if (!is_array($input)) fail(400, 'Не удалось прочитать запрос.');
        } elseif (!($type === 'multipart/form-data' && $path === '/api/admin/media' && $origin !== '')) {
            fail(415, 'Этот формат запроса не поддерживается.');
        }
    }
    $secure = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off')
        || ($_SERVER['HTTP_X_FORWARDED_PROTO'] ?? '') === 'https';
    ini_set('session.use_strict_mode', '1');
    ini_set('session.use_only_cookies', '1');
    session_name('lunea_sid');
    session_set_cookie_params(['path' => '/', 'secure' => $secure, 'httponly' => true, 'samesite' => 'Lax']);
    session_save_path(ensureDirectory(dbPath() . '/sessions'));
    if (!session_start()) fail(503, 'Не удалось открыть сеанс.');
    if ($isMedia) serveMedia($matches[1], $method);

    $kind = is_string($input['kind'] ?? null) ? $input['kind'] : '';
    $value = is_array($input['value'] ?? null) ? $input['value'] : [];
    $result = match ($path) {
        '/api/admin/auth' => adminAuth($method, $input),
        '/api/auth' => customerAuth($method, $input),
        '/api/space' => $method === 'GET'
            ? withData(false, 'publicSpace')
            : withData(true, fn(array &$data) => userWrite($data, $kind, $value)),
        '/api/admin/space' => withData($method === 'POST', fn(array &$data) => adminSpace($data, $method, $kind, $value)),
        '/api/admin/media' => adminMedia($method, $input),
    };
} catch (HttpError $error) {
    http_response_code($error->getCode());
    $result = ['error' => $error->getMessage()];
} catch (Throwable $error) {
    error_log('Lunea: ' . $error->getMessage());
    http_response_code(500);
    $result = ['error' => 'Внутренняя ошибка. Повтори попытку позже.'];
}

header('Content-Type: application/json; charset=UTF-8');
echo json_encode($result, JSON_UNESCAPED_UNICODE | JSON_INVALID_UTF8_SUBSTITUTE);
