<?php
/**
 * Features Manager for FleekDash V2.2
 *
 * Server-Side Rendering (SSR) of user features to avoid frontend flash/delay
 * Injects feature data directly into HTML for instant, synchronous access
 *
 * @package FleekDash V2.2
 * @since 2.2.0
 */

namespace FleekDash\Core;

defined('ABSPATH') || exit;

// Load debug helpers
if (!function_exists('fleekdash_log_error')) {
    require_once FLEEKDASH_PLUGIN_DIR . 'includes/Core/debug-helpers.php';
}

use FleekDash\Controllers\License\LicenseHelpers;
use FleekDash\Services\LabsFeaturesService;

/**
 * Class FeaturesManager
 *
 * Manages server-side feature injection for zero-delay UX
 */
class FeaturesManager
{
    /**
     * Singleton instance
     *
     * @var FeaturesManager|null
     */
    private static $instance = null;

    /**
     * Get singleton instance
     *
     * @return FeaturesManager
     */
    public static function getInstance(): FeaturesManager
    {
        if (self::$instance === null) {
            self::$instance = new self();
        }
        return self::$instance;
    }

    /**
     * Constructor
     */
    private function __construct()
    {
        $this->initHooks();
        LabsFeaturesService::init();
    }

    /**
     * Initialize WordPress hooks
     */
    private function initHooks(): void
    {
        // Inject feature data into admin scripts (high priority)
        \add_action('admin_enqueue_scripts', array($this, 'injectFeatures'), 5);
    }

    /**
     * Inject user features into window.FleekDash
     *
     * @param string $hook Current admin page hook
     */
    public function injectFeatures(string $hook): void
    {
        // Only load on FleekDash pages
        if (strpos($hook, 'fleekdash') === false && (!isset($_GET['page']) || strpos($_GET['page'], 'fleekdash') === false)) {
            return;
        }

        // Get current user features
        $features_data = $this->getUserFeatures();

        // Phase 2: Add timestamp for frontend staleness check (milliseconds)
        $features_data['_ssr_timestamp'] = (int) (microtime(true) * 1000);

        // Inject directly in <head> (SSR for instant access)
        \add_action('admin_head', function () use ($features_data) {
            echo '<script type="text/javascript">';
            echo 'window.FleekDash = window.FleekDash || {};';
            echo 'window.FleekDash.features = ' . \wp_json_encode($features_data) . ';';
            echo '</script>';
        }, -9999); // Highest priority (earliest execution)
    }

    /**
     * Get user features (server-side)
     *
     * @return array Feature data
     */
    private function getUserFeatures(): array
    {
        $result = $this->getFallbackFeatures();

        if (class_exists('\FleekDash\API\FeatureController')) {
            try {
                $controller = \FleekDash\API\FeatureController::getInstance();
                $request = new \WP_REST_Request('GET', '/fleekdash/v1/features/user');
                $request->set_param('app_name', 'fleekdash');
                $request->set_param('force_refresh', 'true');
                $response = $controller->getUserFeatures($request);

                if (!is_wp_error($response)) {
                    $service = LabsFeaturesService::init();
                    $result = $service->enhanceFeaturesData($response->get_data());
                }
            } catch (\Exception $e) {
                fleekdash_log_error('[FeaturesManager] Error getting features: ' . $e->getMessage());
            }
        }

        return $result;
    }

    /**
     * Get fallback features (if API fails)
     *
     * @return array Fallback feature data
     */
    private function getFallbackFeatures(): array
    {
        $fallback = array(
            'success' => true,
            'message' => 'Fallback mode (admin user)',
            'features' => array(),
            'limits' => array(),
            'tier_id' => null,
            'app_name' => 'fleekdash',
            'cached' => false,
            'fallback' => true,
            // Admin users get all features by default
            'admin_override' => \current_user_can('manage_options'),
        );

        $service = LabsFeaturesService::init();
        return $service->enhanceFeaturesData($fallback);
    }

    /**
     * Get cached features without forcing a refresh.
     *
     * Reads from the transient that FeatureController populates:
     *   fleekdash_v2_features_{app_name}_{deal_tier_id}
     *
     * Returns the raw features data (before LabsFeaturesService enhancement)
     * or an empty array on cache miss. Intended for internal use by
     * PermissionManager to avoid redundant REST dispatches during SSR.
     * PermissionFeatureResolver applies LabsFeaturesService on read so feature
     * checks match /features/user and window.FleekDash.features.
     *
     * @param string $app_name App name (default: fleekdash)
     * @return array Feature data array, or empty array on cache miss.
     */
    public function getCachedFeatures(string $app_name = 'fleekdash'): array
    {
        $raw_license = \get_option('fleekdash_v2_license_data', []);
        $license_data = LicenseHelpers::getCanonicalLicenseRecord(\is_array($raw_license) ? $raw_license : null)
            ?? (\is_array($raw_license) ? $raw_license : []);
        $tier_id = (string) ($license_data['deal_tier_id'] ?? '');
        $cached = [];

        if ($tier_id !== '') {
            $cache_key = "fleekdash_v2_features_{$app_name}_{$tier_id}";
            $transient_data = \get_transient($cache_key);
            if (is_array($transient_data)) {
                $cached = $transient_data;
            }
        }

        return $cached;
    }

    /**
     * Clear features cache
     */
    public function clearCache(): void
    {
        wp_cache_delete('user_features', 'fleekdash');
    }
}
