<?php
/**
 * OTIS Life System — Front Controller
 * All requests pass through here via .htaccess rewrite rules
 * Production-hardened: Security headers, session timeout, global exception handler
 */

// ── 0. Set Default Timezone ────────────────────────────────────
date_default_timezone_set('Africa/Cairo');

// ── 0. Global Exception Handler ────────────────────────────────
set_exception_handler(function (\Throwable $e) {
    error_log('[OTIS FATAL] ' . get_class($e) . ': ' . $e->getMessage()
              . ' in ' . $e->getFile() . ':' . $e->getLine());

    $isAjax = !empty($_SERVER['HTTP_X_REQUESTED_WITH'])
              && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest';

    if ($isAjax) {
        http_response_code(500);
        header('Content-Type: application/json; charset=utf-8');
        echo json_encode(['success' => false, 'error' => 'حدث خطأ غير متوقع. يرجى المحاولة لاحقاً.']);
        exit;
    }
    http_response_code(500);
    $msg = htmlspecialchars($e->getMessage(), ENT_QUOTES, 'UTF-8');
    echo '<!DOCTYPE html><html dir="rtl"><head><meta charset="UTF-8"><title>خطأ | OTIS</title>
    <style>body{font-family:sans-serif;background:#fff3f3;display:flex;align-items:center;justify-content:center;min-height:100vh;margin:0}
    .box{background:#fff;border-radius:12px;padding:40px;max-width:500px;box-shadow:0 4px 30px rgba(0,0,0,.1);text-align:center}
    h2{color:#c0392b}a{color:#2980b9;text-decoration:none}</style></head>
    <body><div class="box"><h2>⚠ خطأ في النظام</h2>
    <p>حدث خطأ غير متوقع. يرجى المحاولة لاحقاً.</p>
    <a href="/">← العودة للرئيسية</a></div></body></html>';
    exit;
});

set_error_handler(function ($severity, $message, $file, $line) {
    if (!(error_reporting() & $severity)) return false;
    throw new \ErrorException($message, 0, $severity, $file, $line);
}, E_ERROR | E_PARSE);

// ── 1a. Define root paths ──────────────────────────────────────────
define('ROOT_PATH', realpath(__DIR__));
$basePath = str_replace('\\', '/', dirname($_SERVER['SCRIPT_NAME']));
define('BASE_URL', rtrim($basePath, '/'));

// ── 1b. Production Error Config ──────────────────────────────────
$_dbConf = require ROOT_PATH . '/config/database.php';
$_appEnv = $_dbConf['APP_ENV'] ?? 'local';
if ($_appEnv === 'production') {
    error_reporting(0);
    ini_set('display_errors', '0');
    ini_set('display_startup_errors', '0');
    ini_set('log_errors', '1');
    ini_set('error_log', ROOT_PATH . '/storage/logs/php_errors.log');
} else {
    error_reporting(E_ALL);
    ini_set('display_errors', '1');
}
unset($_dbConf, $_appEnv);

// ── 1. Secure Session Configuration ────────────────────────────
ini_set('session.cookie_httponly', 1);
ini_set('session.use_only_cookies', 1);
ini_set('session.cookie_samesite', 'Lax');
ini_set('session.use_strict_mode', 1);

$isHttps = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off')
        || (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https')
        || (isset($_SERVER['SERVER_PORT']) && (int)$_SERVER['SERVER_PORT'] === 443);

if ($isHttps) {
    ini_set('session.cookie_secure', 1);
}

session_start([
    'cookie_lifetime' => 0,       // Expire on browser close
    'use_strict_mode'  => true,
    'gc_maxlifetime'   => 14400,  // 4 hours server-side max
]);


// ── 3. Session Timeout (4 hours inactivity) ─────────────────────
const SESSION_TIMEOUT = 14400; // 4 hours in seconds
if (isset($_SESSION['_last_activity'])) {
    if ((time() - $_SESSION['_last_activity']) > SESSION_TIMEOUT) {
        // Expired — destroy session cleanly
        session_unset();
        session_destroy();
        session_start();
        session_regenerate_id(true);
        // Redirect to login (only for non-auth routes)
        $uri = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
        if (!str_contains($uri, '/auth/')) {
            header('Location: ' . BASE_URL . '/auth/login?timeout=1');
            exit;
        }
    }
}
$_SESSION['_last_activity'] = time();

// ── 3. Security Headers (Namecheap/shared-hosting compatible) ──
header('X-Frame-Options: SAMEORIGIN');
header('X-Content-Type-Options: nosniff');
header('X-XSS-Protection: 1; mode=block');
header('Referrer-Policy: strict-origin-when-cross-origin');
header('Permissions-Policy: geolocation=(), microphone=(), camera=()');
header("Content-Security-Policy: default-src 'self'; "
     . "script-src 'self' 'unsafe-inline' https://cdn.jsdelivr.net https://cdnjs.cloudflare.com https://unpkg.com; "
     . "style-src 'self' 'unsafe-inline' https://cdn.jsdelivr.net https://cdnjs.cloudflare.com https://fonts.googleapis.com https://unpkg.com; "
     . "font-src 'self' https://cdnjs.cloudflare.com https://fonts.gstatic.com https://fonts.googleapis.com; "
     . "img-src 'self' data: https:; "
     . "connect-src 'self'; "
     . "frame-ancestors 'none';");


// ── 5. Composer Autoloader ───────────────────────────────────────
if (file_exists(ROOT_PATH . '/vendor/autoload.php')) {
    require_once ROOT_PATH . '/vendor/autoload.php';
} else {
    http_response_code(503);
    die('Composer autoload not found. Please run "composer install".');
}

// ── 6. Global Helpers ────────────────────────────────────────────
require_once ROOT_PATH . '/helpers/functions.php';
require_once ROOT_PATH . '/helpers/security.php';
require_once ROOT_PATH . '/helpers/encryption.php';

// ── 7. Router ────────────────────────────────────────────────────
$router = new Core\Router();
