<?php
declare(strict_types=1);

const BASE_PATH = __DIR__ . '/..';

spl_autoload_register(static function (string $class): void {
	$prefix = 'App\\';
	if (!str_starts_with($class, $prefix)) {
		return;
	}
	$path = BASE_PATH . '/app/' . str_replace('\\', '/', substr($class, strlen($prefix))) . '.php';
	if (is_file($path)) {
		require $path;
	}
});

$configFile = BASE_PATH . '/config.php';
if (!is_file($configFile)) {
	http_response_code(503);
	exit('Brak config.php. Skopiuj config.example.php i uzupełnij dane.');
}
$config = require $configFile;

ini_set('session.use_strict_mode', '1');
ini_set('session.use_only_cookies', '1');
ini_set('session.cookie_httponly', '1');
session_name($config['app']['session_name'] ?? 'shinobi_transfer_session');
session_set_cookie_params([
	'lifetime' => 0,
	'path' => '/',
	'secure' => !empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off',
	'httponly' => true,
	'samesite' => 'Lax',
]);
session_start();

use App\Core\Auth;
use App\Core\Csrf;
use App\Transfer\TransferController;

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

header('X-Content-Type-Options: nosniff');
header('Referrer-Policy: same-origin');

if ($path === '/' && $method === 'GET') {
	header('Location: ' . (Auth::user() ? '/transfer' : '/login'), true, 302);
	exit;
}

if ($path === '/login' && $method === 'GET') {
	if (Auth::user()) {
		header('Location: /transfer');
		exit;
	}
	$error = null;
	$csrf = Csrf::token();
	require BASE_PATH . '/views/login.php';
	exit;
}

if ($path === '/login' && $method === 'POST') {
	Csrf::verify($_POST['_csrf'] ?? null);
	$username = trim((string)($_POST['username'] ?? ''));
	$password = (string)($_POST['password'] ?? '');
	if (Auth::login($username, $password)) {
		header('Location: /transfer', true, 303);
		exit;
	}
	http_response_code(401);
	$error = 'Nieprawidłowy login lub hasło.';
	$csrf = Csrf::token();
	require BASE_PATH . '/views/login.php';
	exit;
}

if ($path === '/logout' && $method === 'POST') {
	Csrf::verify($_POST['_csrf'] ?? null);
	Auth::logout();
	header('Location: /login', true, 303);
	exit;
}

if (!Auth::user()) {
	if (str_starts_with($path, '/transfer/api/')) {
		http_response_code(401);
		header('Content-Type: application/json; charset=utf-8');
		echo json_encode(['error' => 'Zaloguj się ponownie.']);
		exit;
	}
	Auth::requireLogin();
}

$transfer = new TransferController();
$routes = [
	['GET', '#^/transfer/?$#', fn(array $p) => $transfer->index()],
	['GET', '#^/transfer/admin/?$#', fn(array $p) => $transfer->admin()],
	['POST', '#^/transfer/api/create$#', fn(array $p) => $transfer->create()],
	['POST', '#^/transfer/api/register$#', fn(array $p) => $transfer->registerFile()],
	['POST', '#^/transfer/api/chunk$#', fn(array $p) => $transfer->chunk()],
	['GET', '#^/transfer/api/status$#', fn(array $p) => $transfer->status()],
	['POST', '#^/transfer/api/finish-file$#', fn(array $p) => $transfer->finishFile()],
	['POST', '#^/transfer/api/finish-package$#', fn(array $p) => $transfer->finishPackage()],
	['POST', '#^/transfer/api/delete$#', fn(array $p) => $transfer->deletePackage()],
	['GET', '#^/transfer/file/(?P<id>\d+)$#', fn(array $p) => $transfer->download((int)$p['id'])],
	['GET', '#^/transfer/preview/(?P<id>\d+)$#', fn(array $p) => $transfer->download((int)$p['id'], true)],
	['GET', '#^/transfer/zip/(?P<token>[a-f0-9]{64})$#', fn(array $p) => $transfer->downloadPackage($p['token'])],
	['GET', '#^/transfer/(?P<token>[a-f0-9]{64})$#', fn(array $p) => $transfer->show($p['token'])],
];

foreach ($routes as [$routeMethod, $pattern, $handler]) {
	if ($method === $routeMethod && preg_match($pattern, $path, $params)) {
		$handler($params);
		exit;
	}
}

http_response_code(404);
echo 'Nie znaleziono strony.';
