<?php

declare(strict_types=1);

namespace Instinctor\Core;


if (!defined('ABSPATH')) exit;
use Instinctor\Core\Session\DriverInterface;
use Instinctor\Core\Session\WordPressDriver;
use Instinctor\Core\Session\StandaloneDriver;

/**
 * Session — static facade over the active session/CSRF driver.
 *
 * Driver selection:
 *   INSTINCTOR_ENV = 'wordpress'   → WordPressDriver  (default)
 *   INSTINCTOR_ENV = 'standalone'  → StandaloneDriver (stub until M11)
 *
 * Usage:
 *   $nonce = Session::token('instinctor_admin');
 *   check_ajax_referer('instinctor_admin', 'nonce');           // dies on failure
 *   if (!wp_verify_nonce($token, 'instinctor_frontend')) { return; }
 */
class Session
{
    private static ?DriverInterface $driver = null;

    public static function driver(): DriverInterface
    {
        if (self::$driver === null) {
            self::$driver = self::makeDriver();
        }
        return self::$driver;
    }

    public static function setDriver(DriverInterface $driver): void
    {
        self::$driver = $driver;
    }

    private static function makeDriver(): DriverInterface
    {
        $env = defined('INSTINCTOR_ENV') ? INSTINCTOR_ENV : 'wordpress';
        return match ($env) {
            'standalone' => new StandaloneDriver(),
            default      => new WordPressDriver(),
        };
    }

    // -------------------------------------------------------------------------
    // Static API
    // -------------------------------------------------------------------------

    /**
     * Generate a CSRF token for the given action.
     * Replaces: wp_create_nonce($action)
     */
    public static function token(string $action): string
    {
        return self::driver()->token($action);
    }

    /**
     * Verify a CSRF token. Returns true if valid.
     * Replaces: (bool) wp_verify_nonce($token, $action)
     */
    public static function verify(string $token, string $action): bool
    {
        return self::driver()->verify($token, $action);
    }

    /**
     * Verify a CSRF token from request data, die on failure.
     * Replaces: check_ajax_referer($action, $field)
     */
    public static function check(string $action, string $field = 'nonce', bool $die = true): bool
    {
        return self::driver()->check($action, $field, $die);
    }

    /**
     * Create a persistent session token for a user.
     * Used by LoginController (standalone) after successful authentication.
     * Returns the session token string to be stored in a cookie.
     *
     * On WordPress, WP handles session cookies — this is a no-op that returns
     * a dummy value (WP auth cookies are set via wp_set_auth_cookie).
     *
     * @param int $userId   User ID to create session for
     * @param int $ttl      Token lifetime in seconds
     * @return string       Session token
     */
    public static function create(int $userId, int $ttl = 7200): string
    {
        if (method_exists(self::driver(), 'create')) {
            return self::driver()->create($userId, $ttl);
        }

        // WordPress fallback — WP manages its own auth cookies
        // Return a dummy token; WP's cookie is set separately via wp_set_auth_cookie
        return '';
    }

    /**
     * Destroy a session token (logout).
     * On WordPress, WP handles session destruction — this is a no-op.
     *
     * @param string $token  The session token to invalidate
     */
    public static function destroy(string $token): void
    {
        if (method_exists(self::driver(), 'destroy')) {
            self::driver()->destroy($token);
        }
        // WordPress: wp_destroy_current_session() handles this via wp-login.php
    }
}
