<?php

/**
 * ITSWEBER CMS – Front Controller
 *
 * All requests are routed through this file.
 */

// Define base path (one level up from public/)
define('BASE_PATH', dirname(__DIR__));

// ── Maintenance mode check ────────────────────────────────────────────────────
// Two distinct flags:
//   storage/.maintenance      – set/cleared automatically by BackupService
//                               during backup restore / CMS update operations
//   storage/.maintenance_mode – set/cleared by admin via Maintenance settings
//
// Either flag blocks the public frontend (HTTP 503). Admin and installer paths
// are always passed through so the admin can manage the site while it is down.
$_iw_flagBackup = BASE_PATH . '/storage/.maintenance';
$_iw_flagMode   = BASE_PATH . '/storage/.maintenance_mode';

if (is_file($_iw_flagBackup) || is_file($_iw_flagMode)) {
    $requestPath = parse_url($_SERVER['REQUEST_URI'] ?? '/', PHP_URL_PATH) ?? '/';

    // Allowlist: admin area + installer (read admin slug from file cache)
    $_iw_adminSlug = 'admin';
    $_iw_slugFile = BASE_PATH . '/storage/.admin_slug';
    if (is_file($_iw_slugFile)) {
        $_iw_adminSlug = trim(file_get_contents($_iw_slugFile)) ?: 'admin';
    }
    $iw_allowed = false;
    foreach (['/' . $_iw_adminSlug, '/admin', '/installer'] as $_iw_prefix) {
        if (strncmp($requestPath, $_iw_prefix, strlen($_iw_prefix)) === 0) {
            $iw_allowed = true;
            break;
        }
    }

    if (!$iw_allowed) {
        // Read user-controlled maintenance config for custom title/message
        $iw_cfg = [];
        if (is_file($_iw_flagMode)) {
            $iw_raw = @file_get_contents($_iw_flagMode);
            if ($iw_raw !== false) {
                $iw_cfg = json_decode($iw_raw, true) ?? [];
            }
        }

        // Raw values – page.php handles escaping to support nl2br on messages
        $mainTitle   = $iw_cfg['title']     ?? 'Wartung – Gleich zurück';
        $mainMessage = $iw_cfg['message']   ?? 'Diese Website wird gerade aktualisiert oder gewartet. Bitte versuchen Sie es in wenigen Momenten erneut.';
        $mainSite    = $iw_cfg['site_name'] ?? '';

        http_response_code(503);
        header('Retry-After: 300');
        header('Content-Type: text/html; charset=UTF-8');

        // Theme-aware maintenance page: check if active theme provides its own
        $_iw_activeTheme = '';
        $_iw_appCfg = BASE_PATH . '/app/Config/app.php';
        if (is_file($_iw_appCfg)) {
            // Try to read active_theme from DB settings via a lightweight approach
            $_iw_dbCfg = BASE_PATH . '/app/Config/database.php';
            if (is_file($_iw_dbCfg)) {
                try {
                    $_iw_db = require $_iw_dbCfg;
                    $_iw_dsn = 'mysql:host=' . ($_iw_db['host'] ?? 'localhost')
                             . ';dbname=' . ($_iw_db['name'] ?? '')
                             . ';charset=' . ($_iw_db['charset'] ?? 'utf8mb4');
                    $_iw_pdo = new PDO($_iw_dsn, $_iw_db['user'] ?? '', $_iw_db['password'] ?? '', [
                        PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
                        PDO::ATTR_TIMEOUT => 2,
                    ]);
                    $_iw_prefix = $_iw_db['prefix'] ?? 'iw_';
                    $_iw_stmt = $_iw_pdo->prepare("SELECT setting_value FROM {$_iw_prefix}settings WHERE setting_key = 'active_theme' LIMIT 1");
                    $_iw_stmt->execute();
                    $_iw_row = $_iw_stmt->fetch(PDO::FETCH_ASSOC);
                    if ($_iw_row) {
                        $_iw_activeTheme = $_iw_row['setting_value'];
                    }
                } catch (\Throwable $e) {
                    // Silently fall through to core page
                }
            }
        }

        // Check for theme maintenance template
        $config = $iw_cfg;
        $_iw_themeFile = BASE_PATH . '/themes/' . $_iw_activeTheme . '/templates/maintenance.php';
        if ($_iw_activeTheme !== '' && is_file($_iw_themeFile)) {
            include $_iw_themeFile;
        } else {
            include BASE_PATH . '/app/Maintenance/page.php';
        }
        exit;
    }
}
// ─────────────────────────────────────────────────────────────────────────────

// Autoloader
require_once BASE_PATH . '/app/Core/Autoloader.php';
Autoloader::register(BASE_PATH);

// Helper functions
require_once BASE_PATH . '/app/Helpers/functions.php';

// Set timezone
date_default_timezone_set('Europe/Berlin');

// ── Security headers ──────────────────────────────────────────────────────────
header('X-Frame-Options: SAMEORIGIN');
header('X-Content-Type-Options: nosniff');
header('Referrer-Policy: strict-origin-when-cross-origin');
header('Permissions-Policy: camera=(), microphone=(), geolocation=()');
if (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') {
    header('Strict-Transport-Security: max-age=31536000; includeSubDomains');
}

// Initialize application
$app = \App\Core\App::init(BASE_PATH);

// Load active plugins (Phase 17)
// Plugins are loaded after bootstrap but before route dispatch, so they can
// register hooks. Only runs when the CMS is fully installed.
if ($app->isInstalled()) {
    // Auto-run pending PHP migrations after updates.
    // Updates deployed via FTP or the CMS updater may include new PHP migration
    // classes that haven't been executed yet. This ensures they run on the first
    // request, eliminating the need for SSH/CLI access.
    $migrationsDir = BASE_PATH . '/database/migrations';
    if (is_dir($migrationsDir)) {
        try {
            $migrator = new \App\Database\Migrator($app->db(), $migrationsDir);
            $migrator->runAll();
        } catch (\Throwable $e) {
            error_log('ITSWEBER auto-migration error: ' . $e->getMessage());
        }
    }

    \App\Services\PluginLoader::loadActive(BASE_PATH);

    // Register core sections + fire 'sections.register' hook for third-party plugins.
    // Must run AFTER PluginLoader so plugins can add their hooks first.
    \App\Sections\SectionRegistry::registerCore();
}

// Load routes
$router = $app->service('router');

// Route loading order is critical:
// Installer and admin routes must be registered BEFORE the frontend catch-all /{slug}.
// Otherwise /admin would match /{slug} (slug='admin') before reaching the admin routes.

// 1. Installer routes (own namespace, most specific)
if (file_exists(BASE_PATH . '/app/Config/installer_routes.php')) {
    require_once BASE_PATH . '/app/Config/installer_routes.php';
}

// 2. Admin routes (specific paths under /admin)
if (file_exists(BASE_PATH . '/app/Config/admin_routes.php')) {
    require_once BASE_PATH . '/app/Config/admin_routes.php';
}

// 3. Frontend routes (contains catch-all /{slug} — must be last)
if (file_exists(BASE_PATH . '/app/Config/routes.php')) {
    require_once BASE_PATH . '/app/Config/routes.php';
}

// Dispatch
$app->run();
