<?php
namespace App\Core;

/** Manajemen sesi dengan pengerasan keamanan. */
class Session
{
    private static bool $started = false;

    public static function start(): void
    {
        if (self::$started || session_status() === PHP_SESSION_ACTIVE) { self::$started = true; return; }

        $secure = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off')
               || ($_SERVER['HTTP_X_FORWARDED_PROTO'] ?? '') === 'https';

        session_name(Config::get('app.session_name', 'sipiutang_session'));
        session_set_cookie_params([
            'lifetime' => 0,
            'path'     => '/',
            'domain'   => '',
            'secure'   => $secure,
            'httponly' => true,
            'samesite' => 'Lax',
        ]);
        @ini_set('session.use_strict_mode', '1');
        @ini_set('session.use_only_cookies', '1');
        @session_start();
        self::$started = true;

        // Pengikatan sidik jari peramban untuk mencegah pembajakan sesi
        $fp = self::fingerprint();
        if (!isset($_SESSION['_fp'])) {
            $_SESSION['_fp'] = $fp;
        } elseif (!hash_equals($_SESSION['_fp'], $fp)) {
            self::destroy();
            @session_start();
            $_SESSION['_fp'] = $fp;
        }

        // Logout otomatis setelah tidak aktif
        $idle = 30;
        try { $idle = max(1, Settings::int('keamanan.idle_timeout_menit', 30)); } catch (\Throwable $e) {}
        if (isset($_SESSION['_last']) && (time() - (int)$_SESSION['_last']) > $idle * 60) {
            $wasLogged = isset($_SESSION['user_id']);
            self::destroy();
            @session_start();
            $_SESSION['_fp'] = $fp;
            if ($wasLogged) Flash::add('warning', 'Sesi Anda berakhir karena tidak ada aktivitas. Silakan masuk kembali.');
        }
        $_SESSION['_last'] = time();
    }

    private static function fingerprint(): string
    {
        $ua = $_SERVER['HTTP_USER_AGENT'] ?? '';
        return hash('sha256', $ua . '|' . Config::get('app.key', 'sipiutang'));
    }

    public static function get(string $k, $d = null)  { return $_SESSION[$k] ?? $d; }
    public static function set(string $k, $v): void   { $_SESSION[$k] = $v; }
    public static function has(string $k): bool       { return isset($_SESSION[$k]); }
    public static function forget(string $k): void    { unset($_SESSION[$k]); }

    public static function regenerate(): void
    {
        if (session_status() === PHP_SESSION_ACTIVE) @session_regenerate_id(true);
    }

    public static function destroy(): void
    {
        $_SESSION = [];
        if (ini_get('session.use_cookies')) {
            $p = session_get_cookie_params();
            setcookie(session_name(), '', time() - 42000, $p['path'], $p['domain'], $p['secure'], $p['httponly']);
        }
        @session_destroy();
    }
}
