add(function() {
    // Apply security headers
    require_once __DIR__ . '/../app/includes/security_headers_middleware.php';
    return true;
});
// For public pages, we don't need to validate the session
// The Router will handle authentication for protected pages
$validSession = false;
$userId = null;
// Only check session for non-public pages
if (!in_array($page, $public_pages)) {
    $validSession = Session::isValidSession(true);
    if ($validSession) {
        $userId = Session::getUserId();
    }
}
// Initialize feedback message system
require_once '../app/classes/feedback.php';
$system_messages = [];
require '../app/includes/errors.php';
// list of available pages
// edit accordingly, add 'pages/PAGE.php'
$allowed_urls = [
    'dashboard',
    'conferences','participants','components',
    'graphs','latest','livejs','agents',
    'profile','credentials','config','security',
    'settings','theme','theme-asset',
    'admin-tools',
    'status',
    'help','about',
    'login','logout',
];
// Let plugins filter/extend allowed_urls
$allowed_urls = filter_allowed_urls($allowed_urls);
// Dispatch routing and auth
require_once __DIR__ . '/../app/core/Router.php';
use App\Core\Router;
$currentUser = Router::checkAuth($config, $app_root, $public_pages, $page);
// Connect to DB via DatabaseConnector
require_once __DIR__ . '/../app/core/DatabaseConnector.php';
use App\Core\DatabaseConnector;
$db = DatabaseConnector::connect($config);
// Logging: default to NullLogger, plugin can override
require_once __DIR__ . '/../app/core/NullLogger.php';
use App\Core\NullLogger;
$logObject = new NullLogger();
// Get the user IP
require_once __DIR__ . '/../app/helpers/ip_helper.php';
$user_IP = '';
// Plugin: initialize logging system plugin if available
do_hook('logger.system_init', ['db' => $db]);
// Override defaults if plugin provided real logger
if (isset($GLOBALS['logObject'])) {
    $logObject = $GLOBALS['logObject'];
}
if (isset($GLOBALS['user_IP'])) {
    $user_IP = $GLOBALS['user_IP'];
}
// Check for pending DB migrations (non-intrusive: warn only)
try {
    $migrationsDir = __DIR__ . '/../doc/database/migrations';
    if (is_dir($migrationsDir)) {
        require_once __DIR__ . '/../app/core/MigrationRunner.php';
        $runner = new \App\Core\MigrationRunner($db, $migrationsDir);
        if ($runner->hasPendingMigrations()) {
            $pending = $runner->listPendingMigrations();
            $msg = 'Database schema is out of date. There are pending migrations. Run "php scripts/migrate.php up" or use the Admin tools';
            // Log and show as a system message
            $logObject->log('warning', $msg, ['scope' => 'system']);
            Feedback::flash('SYSTEM', 'MIGRATIONS_PENDING', $msg, false, true, false);
        }
    }
} catch (\Throwable $e) {
    // Do not break the app; log only
    error_log('Migration check failed: ' . $e->getMessage());
}
// CSRF middleware and run pipeline
$pipeline->add(function() {
    // Initialize security middleware
    require_once __DIR__ . '/../app/includes/csrf_middleware.php';
    require_once __DIR__ . '/../app/helpers/security.php';
    $security = SecurityHelper::getInstance();
    // Verify CSRF token for POST requests
    return applyCsrfMiddleware();
});
$pipeline->add(function() {
    // Init rate limiter
    global $db, $page, $userId;
    require_once __DIR__ . '/../app/includes/rate_limit_middleware.php';
    return checkRateLimit($db, $page, $userId);
});
$pipeline->add(function() {
    // Init user functions
    global $db, $userObject;
    require_once __DIR__ . '/../app/classes/user.php';
    include __DIR__ . '/../app/helpers/profile.php';
    $userObject = new User($db);
    return true;
});
if (!$pipeline->run()) {
    exit;
}
// Maintenance mode: show maintenance page to non-superusers
try {
    require_once __DIR__ . '/../app/core/Maintenance.php';
    if (\App\Core\Maintenance::isEnabled()) {
        $isSuperuser = false;
        if ($validSession && isset($userId) && isset($userObject) && method_exists($userObject, 'hasRight')) {
            // user 1 is always superuser per implementation, but also check explicit right
            $isSuperuser = ($userId === 1) || (bool)$userObject->hasRight($userId, 'superuser');
        }
        if (!$isSuperuser) {
            http_response_code(503);
            // Advise clients to retry after 10 minutes (600 seconds; configure here)
            header('Retry-After: 600');
            // Show themed maintenance page
            \App\Helpers\Theme::include('page-header');
            \App\Helpers\Theme::include('page-menu');
            include __DIR__ . '/../app/templates/maintenance.php';
            \App\Helpers\Theme::include('page-footer');
            ob_end_flush();
            exit;
        } else {
            // Superusers bypass maintenance; show a small banner
            $maintMsg = \App\Core\Maintenance::getMessage();
            $custom = 'Maintenance mode is enabled.';
            if (!empty($maintMsg)) {
                $custom .= ' ' . htmlspecialchars($maintMsg) . '';
            }
            $custom .= ' Control it in Admin tools';
            // Non-dismissible and small, do not sanitize to allow link and 
            Feedback::flash('SYSTEM', 'MAINTENANCE_ON', $custom, false, true, false);
        }
    }
} catch (\Throwable $e) {
    // Do not break app if maintenance check fails
}
// Apply per-user theme from DB into session (without persisting) once user is known
if ($validSession && isset($userId) && isset($userObject) && is_object($userObject) && method_exists($userObject, 'getUserTheme')) {
    try {
        $dbTheme = $userObject->getUserTheme((int)$userId);
        if ($dbTheme) {
            \App\Helpers\Theme::setCurrentTheme($dbTheme, false);
        }
    } catch (\Throwable $e) {
        // Non-fatal if theme load fails
    }
}
// get platforms details
require '../app/classes/platform.php';
$platformObject = new Platform($db);
$platformsAll = $platformObject->getPlatformDetails();
// by default we connect ot the first configured platform
if ($platform_id == '') {
    $platform_id = $platformsAll[0]['id'];
}
$platformDetails = $platformObject->getPlatformDetails($platform_id);
// logout is a special case, as we can't use session vars for notices
if ($page == 'logout') {
    // Save config before destroying session
    $savedConfig = $config;
    // clean up session
    Session::destroySession();
    // start new session for the login page
    Session::startSession();
    // Restore config to global scope
    $config = $savedConfig;
    $GLOBALS['config'] = $config;
    setcookie('username', "", time() - 100, $config['folder'], $config['domain'], isset($_SERVER['HTTPS']), true);
    // Log successful logout
    $logObject->log('info', "Logout: User \"$currentUser\" logged out. IP: $user_IP", ['user_id' => $userId, 'scope' => 'user']);
    // Set success message
    Feedback::flash('LOGIN', 'LOGOUT_SUCCESS');
    // Use theme helper to include templates
    \App\Helpers\Theme::include('page-header');
    \App\Helpers\Theme::include('page-menu');
    include '../app/pages/login.php';
    \App\Helpers\Theme::include('page-footer');
} else {
    // if user is logged in, we need user details and rights
    if ($validSession) {
        // If by error a logged in user requests the login page
        if ($page === 'login') {
            header('Location: ' . htmlspecialchars($app_root));
            exit();
        }
        $userDetails = $userObject->getUserDetails($userId);
        $userRights = $userObject->getUserRights($userId);
        $userTimezone = (!empty($userDetails[0]['timezone'])) ? $userDetails[0]['timezone'] : 'UTC'; // Default to UTC if no timezone is set (or is missing)
        // check if the Jilo Server is running
        require '../app/classes/server.php';
        $serverObject = new Server($db);
        $server_host = '127.0.0.1';
        $server_port = '8080';
        $server_endpoint = '/health';
        $server_status = $serverObject->getServerStatus($server_host, $server_port, $server_endpoint);
        if (!$server_status) {
            Feedback::flash('ERROR', 'DEFAULT', 'The Jilo Server is not running. Some data may be old and incorrect.', false, true);
        }
    }
    // --- Plugin loading logic for all enabled plugins ---
    // Ensure all enabled plugin bootstraps are loaded before mapping controllers
    foreach ($GLOBALS['enabled_plugins'] as $plugin_name => $plugin_info) {
        $bootstrap_path = $plugin_info['path'] . '/bootstrap.php';
        if (file_exists($bootstrap_path)) {
            require_once $bootstrap_path;
        }
    }
    // Plugin controller mapping logic (we add each controller listed in bootstrap as a page)
    $mapped_plugin_controllers = [];
    foreach ($GLOBALS['enabled_plugins'] as $plugin_name => $plugin_info) {
        if (isset($GLOBALS['plugin_controllers'][$plugin_name])) {
            foreach ($GLOBALS['plugin_controllers'][$plugin_name] as $plugin_page) {
                $controller_path = $plugin_info['path'] . '/controllers/' . $plugin_page . '.php';
                if (file_exists($controller_path)) {
                    $mapped_plugin_controllers[$plugin_page] = $controller_path;
                }
            }
        }
    }
    // page building
    if (in_array($page, $allowed_urls)) {
    // The page is in allowed URLs
        if (isset($mapped_plugin_controllers[$page]) && file_exists($mapped_plugin_controllers[$page])) {
        // The page is from a plugin controller
            if (defined('PLUGIN_PAGE_DIRECT_OUTPUT') && PLUGIN_PAGE_DIRECT_OUTPUT === true) {
                // Barebone page controller, we don't output anything extra
                include $mapped_plugin_controllers[$page];
                ob_end_flush();
                exit;
            } else {
                \App\Helpers\Theme::include('page-header');
                \App\Helpers\Theme::include('page-menu');
                if ($validSession) {
                    \App\Helpers\Theme::include('page-sidebar');
                }
                include $mapped_plugin_controllers[$page];
                \App\Helpers\Theme::include('page-footer');
            }
        } else {
        // The page is from a core controller
            \App\Helpers\Theme::include('page-header');
            \App\Helpers\Theme::include('page-menu');
            if ($validSession) {
                \App\Helpers\Theme::include('page-sidebar');
            }
            if (file_exists("../app/pages/{$page}.php")) {
                include "../app/pages/{$page}.php";
            } else {
                include '../app/templates/error-notfound.php';
            }
            \App\Helpers\Theme::include('page-footer');
        }
    } else {
    // The page is not in allowed URLs
        \App\Helpers\Theme::include('page-header');
        \App\Helpers\Theme::include('page-menu');
        if ($validSession) {
            \App\Helpers\Theme::include('page-sidebar');
        }
        include '../app/templates/error-notfound.php';
        \App\Helpers\Theme::include('page-footer');
    }
}
// flush the output buffer and show the page
ob_end_flush();
// clear errors and notices before next page just in case
unset($_SESSION['error']);
unset($_SESSION['notice']);