<?php
/* ============================================================
   منصة خبرة — التهيئة المشتركة
   الرؤوس الأمنية · الجلسة الآمنة · الاتصال بقاعدة البيانات
   ============================================================ */

declare(strict_types=1);

if (!defined('EXP_ROOT')) define('EXP_ROOT', __DIR__);

/* ---------- الأخطاء لا تُعرض للزائر أبدًا ---------- */
error_reporting(E_ALL);
ini_set('display_errors', '0');
ini_set('log_errors', '1');

$CONFIG = require EXP_ROOT . '/config.php';

/* ============================================================
   1) الرؤوس الأمنية
   ============================================================ */
function exp_security_headers(): void {
  header('X-Content-Type-Options: nosniff');
  header('X-Frame-Options: SAMEORIGIN');
  header('Referrer-Policy: strict-origin-when-cross-origin');
  header('Permissions-Policy: geolocation=(), microphone=(), camera=()');
  header_remove('X-Powered-By');
}
exp_security_headers();

/* ============================================================
   2) إلزام HTTPS
   ============================================================ */
function exp_is_https(): bool {
  if (!empty($_SERVER['HTTPS']) && strtolower((string)$_SERVER['HTTPS']) !== 'off') return true;
  if (($_SERVER['SERVER_PORT'] ?? '') === '443') return true;
  // خلف بروكسي أو CDN
  if (strtolower((string)($_SERVER['HTTP_X_FORWARDED_PROTO'] ?? '')) === 'https') return true;
  return false;
}

if (!empty($CONFIG['security']['force_https']) && !exp_is_https()) {
  $isLocal = in_array($_SERVER['REMOTE_ADDR'] ?? '', ['127.0.0.1', '::1'], true);
  if (!$isLocal) {
    header('Strict-Transport-Security: max-age=31536000');
    http_response_code(403);
    header('Content-Type: application/json; charset=utf-8');
    echo json_encode(['ok' => false, 'error' => 'يجب استخدام اتصال آمن (HTTPS)'],
      JSON_UNESCAPED_UNICODE);
    exit;
  }
}
if (exp_is_https()) header('Strict-Transport-Security: max-age=31536000');

/* ============================================================
   3) الجلسة الآمنة
   ============================================================ */
function exp_start_session(array $CONFIG): void {
  if (session_status() === PHP_SESSION_ACTIVE) return;

  $minutes = (int)($CONFIG['security']['session_minutes'] ?? 480);
  $lifetime = $minutes * 60;

  ini_set('session.use_strict_mode', '1');
  ini_set('session.use_only_cookies', '1');
  ini_set('session.cookie_httponly', '1');
  ini_set('session.gc_maxlifetime', (string)$lifetime);

  session_set_cookie_params([
    'lifetime' => 0,                 // ينتهي بإغلاق المتصفح
    'path'     => '/',
    'secure'   => exp_is_https(),
    'httponly' => true,              // لا يمكن قراءته من JavaScript
    'samesite' => 'Strict',          // يمنع هجمات CSRF عبر المواقع
  ]);

  session_name('EXPSESS');
  session_start();

  /* انتهاء الجلسة بالخمول */
  $now = time();
  if (isset($_SESSION['last_seen']) && ($now - (int)$_SESSION['last_seen']) > $lifetime) {
    $_SESSION = [];
    session_destroy();
    session_start();
  }
  $_SESSION['last_seen'] = $now;
}

/* ============================================================
   4) الاتصال بقاعدة البيانات
   ============================================================ */
function exp_db(array $CONFIG): PDO {
  static $pdo = null;
  if ($pdo instanceof PDO) return $pdo;

  $d = $CONFIG['db'];
  $dsn = sprintf('mysql:host=%s;dbname=%s;charset=%s', $d['host'], $d['name'], $d['charset']);

  try {
    $pdo = new PDO($dsn, $d['user'], $d['pass'], [
      PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
      PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
      PDO::ATTR_EMULATE_PREPARES   => false,   // استعلامات مُعدّة حقيقية
      PDO::ATTR_STRINGIFY_FETCHES  => false,
    ]);
  } catch (Throwable $e) {
    error_log('DB connect failed: ' . $e->getMessage());
    http_response_code(500);
    header('Content-Type: application/json; charset=utf-8');
    echo json_encode([
      'ok' => false,
      'error' => 'تعذّر الاتصال بقاعدة البيانات — راجع api/config.php'
    ], JSON_UNESCAPED_UNICODE);
    exit;
  }
  return $pdo;
}
