<?php
namespace WooNooW\Compat;

if ( ! defined('ABSPATH') ) exit;

/**
 * Route Registry
 * 
 * Manages SPA route registration for addons. Allows addons to register
 * custom routes that will be dynamically loaded in the React SPA.
 * 
 * @since 1.0.0
 */
class RouteRegistry {
    const ROUTES_OPTION = 'wnw_spa_routes';
    const ROUTES_VERSION = '1.0.0';
    
    /**
     * Initialize hooks
     */
    public static function init() {
        add_action('plugins_loaded', [__CLASS__, 'collect_routes'], 25);
        add_action('activated_plugin', [__CLASS__, 'flush']);
        add_action('deactivated_plugin', [__CLASS__, 'flush']);
    }
    
    /**
     * Collect and validate routes from addons
     */
    public static function collect_routes() {
        // Start with empty routes
        $routes = [];
        
        /**
         * Filter: woonoow/spa_routes
         * 
         * Allows addons to register SPA routes.
         * 
         * @param array $routes Array of route configurations
         * 
         * Example:
         * add_filter('woonoow/spa_routes', function($routes) {
         *     $routes[] = [
         *         'path'          => '/subscriptions',
         *         'component_url' => plugin_dir_url(__FILE__) . 'dist/SubscriptionsList.js',
         *         'capability'    => 'manage_woocommerce',
         *         'title'         => 'Subscriptions',
         *         'exact'         => false,
         *     ];
         *     return $routes;
         * });
         */
        $routes = apply_filters('woonoow/spa_routes', $routes);
        
        // Validate and normalize each route
        $validated = [];
        foreach ($routes as $route) {
            $validated_route = self::validate_route($route);
            if ($validated_route) {
                $validated[] = $validated_route;
            }
        }
        
        // Store in option
        update_option(self::ROUTES_OPTION, [
            'version' => self::ROUTES_VERSION,
            'routes'  => $validated,
            'updated' => time(),
        ], false);
    }
    
    /**
     * Validate and normalize route configuration
     * 
     * @param array $route Route configuration
     * @return array|null Validated route or null if invalid
     */
    private static function validate_route(array $route): ?array {
        // Path is required
        if (empty($route['path'])) {
            return null;
        }
        
        // Component URL is required
        if (empty($route['component_url'])) {
            return null;
        }
        
        // Normalize path (must start with /)
        $path = $route['path'];
        if (substr($path, 0, 1) !== '/') {
            $path = '/' . $path;
        }
        
        $defaults = [
            'path'          => $path,
            'component_url' => '',
            'capability'    => 'manage_woocommerce',
            'title'         => '',
            'exact'         => false,
            'props'         => [],
        ];
        
        $validated = wp_parse_args($route, $defaults);
        
        // Sanitize
        $validated['path'] = sanitize_text_field($validated['path']);
        $validated['component_url'] = esc_url_raw($validated['component_url']);
        $validated['capability'] = sanitize_text_field($validated['capability']);
        $validated['title'] = sanitize_text_field($validated['title']);
        $validated['exact'] = (bool) $validated['exact'];
        
        return $validated;
    }
    
    /**
     * Get all registered routes
     * 
     * @param bool $check_capability Filter by current user capability
     * @return array Array of route configurations
     */
    public static function get_routes(bool $check_capability = false): array {
        $data = get_option(self::ROUTES_OPTION, []);
        $routes = $data['routes'] ?? [];
        
        if ($check_capability) {
            $routes = array_filter($routes, function($route) {
                return current_user_can($route['capability'] ?? 'manage_woocommerce');
            });
        }
        
        return array_values($routes);
    }
    
    /**
     * Get a route by path
     * 
     * @param string $path Route path
     * @return array|null Route configuration or null if not found
     */
    public static function get_route(string $path): ?array {
        $routes = self::get_routes();
        foreach ($routes as $route) {
            if ($route['path'] === $path) {
                return $route;
            }
        }
        return null;
    }
    
    /**
     * Check if a route exists
     * 
     * @param string $path Route path
     * @return bool True if route exists
     */
    public static function has_route(string $path): bool {
        return self::get_route($path) !== null;
    }
    
    /**
     * Flush the routes cache
     */
    public static function flush() {
        delete_option(self::ROUTES_OPTION);
    }
    
    /**
     * Get routes for frontend (filtered by capability)
     * 
     * @return array Array suitable for JSON encoding
     */
    public static function get_frontend_routes(): array {
        return self::get_routes(true);
    }
}
