<?php

namespace App\Helpers;

class Auth
{
    public static function start()
    {
        if (session_status() === PHP_SESSION_NONE) {
            // Secure session cookie params
            $isHttps = !empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off';
            ini_set('session.cookie_httponly', 1);
            ini_set('session.cookie_samesite', 'Lax');
            if ($isHttps) {
                ini_set('session.cookie_secure', 1);
            }
            ini_set('session.use_strict_mode', 1);
            ini_set('session.use_only_cookies', 1);
            ini_set('session.cookie_path', Url::getBaseUrl() ?: '/');

            session_start();

            // Regenerate ID periodically to prevent fixation
            if (!isset($_SESSION['_last_regenerated']) || (time() - $_SESSION['_last_regenerated']) > 900) {
                session_regenerate_id(true);
                $_SESSION['_last_regenerated'] = time();
            }
        }
    }

    public static function login($email, $password)
    {
        $user = new \App\Models\User();
        $users = $user->where('email', $email);

        if (count($users) > 0 && password_verify($password, $users[0]->password)) {
            session_regenerate_id(true);
            $_SESSION['user_id'] = $users[0]->id;
            $_SESSION['user_name'] = $users[0]->name;
            $_SESSION['user_email'] = $users[0]->email;
            $_SESSION['user_role'] = $users[0]->role;
            $_SESSION['logged_in'] = true;
            $_SESSION['_last_regenerated'] = time();
            return true;
        }
        return false;
    }

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

    public static function check()
    {
        self::start();
        return isset($_SESSION['logged_in']) && $_SESSION['logged_in'] === true;
    }

    public static function user()
    {
        self::start();
        if (self::check()) {
            return (object) [
                'id' => $_SESSION['user_id'],
                'name' => $_SESSION['user_name'],
                'email' => $_SESSION['user_email'],
                'role' => $_SESSION['user_role'],
            ];
        }
        return null;
    }

    public static function id()
    {
        return isset($_SESSION['user_id']) ? $_SESSION['user_id'] : null;
    }

    public static function isAdmin()
    {
        self::start();
        return isset($_SESSION['user_role']) && $_SESSION['user_role'] === 'admin';
    }

    public static function requireAdmin()
    {
        self::start();
        if (!self::isAdmin()) {
            $_SESSION['error'] = 'You do not have permission to access that page.';
            Url::redirect('/dashboard');
            exit;
        }
    }

    public static function requireLogin()
    {
        self::start();
        if (!self::check()) {
            Url::redirect('/login');
        }
    }

    // CSRF token generation and validation
    public static function csrfToken()
    {
        self::start();
        if (empty($_SESSION['_csrf_token'])) {
            $_SESSION['_csrf_token'] = bin2hex(random_bytes(32));
        }
        return $_SESSION['_csrf_token'];
    }

    public static function csrfField()
    {
        return '<input type="hidden" name="_csrf_token" value="' . self::csrfToken() . '">';
    }

    public static function verifyCsrf($token)
    {
        self::start();
        if (empty($_SESSION['_csrf_token']) || empty($token)) {
            return false;
        }
        return hash_equals($_SESSION['_csrf_token'], $token);
    }

    public static function requireCsrf()
    {
        $token = $_POST['_csrf_token'] ?? ($_SERVER['HTTP_X_CSRF_TOKEN'] ?? '');
        if (!self::verifyCsrf($token)) {
            http_response_code(419);
            $_SESSION['error'] = 'Session expired or invalid request. Please try again.';
            $referer = $_SERVER['HTTP_REFERER'] ?? '/';
            Url::redirect($referer);
            exit;
        }
        // Rotate token after successful use
        $_SESSION['_csrf_token'] = bin2hex(random_bytes(32));
    }
}