#!/usr/bin/env python3
"""
Plugin Router - Dynamic API endpoints for plugins

Automatically generates routes for all discovered plugins and handles:
- Request parameter extraction and validation
- Plugin execution
- Error handling and responses
"""

from typing import Any, Callable
from quart import jsonify, request
from lib.auth import require_api_key
from lib.plugin_loader import get_plugin_registry
from lib.plugin_validator import validate_plugin_params, apply_default_values


def register_plugin_routes(url_prefix: str, app, browser_navigator_getter: Callable) -> None:
    """
    Register dynamic HTTP routes for all discovered plugins.
    
    Each plugin gets an endpoint at: {url_prefix}/<page_id>/plugin/<plugin-name>
    
    Args:
        url_prefix: API version prefix (e.g., "/api/v1")
        app: Quart app instance
        browser_navigator_getter: Function that returns the browser_navigator instance
    """
    registry = get_plugin_registry()
    plugins = registry.list_plugins()
    
    if not plugins:
        print("⚠️  No plugins registered, skipping plugin route registration")
        return
    
    print(f"\n📡 Registering plugin routes...")
    
    for plugin_name, plugin_instance in plugins.items():
        _register_plugin_route(
            app=app,
            url_prefix=url_prefix,
            plugin_name=plugin_name,
            plugin_instance=plugin_instance,
            browser_navigator_getter=browser_navigator_getter
        )
    
    # Register metadata endpoint
    _register_metadata_endpoint(app, url_prefix)
    
    print(f"✅ Registered {len(plugins)} plugin route(s)\n")


def _register_plugin_route(
    app,
    url_prefix: str,
    plugin_name: str,
    plugin_instance: Any,
    browser_navigator_getter: Callable
) -> None:
    """
    Register a single plugin route.
    
    Args:
        app: Quart app instance
        url_prefix: API version prefix
        plugin_name: Plugin name from metadata
        plugin_instance: Plugin instance
        browser_navigator_getter: Function that returns browser_navigator
    """
    route_path = f"{url_prefix}/<page_id>/plugin/{plugin_name}"
    methods = plugin_instance.metadata.methods or ["POST"]
    
    # Create handler function with closure to capture plugin_instance
    def make_handler(plugin):
        @require_api_key
        async def handler(page_id: str):
            """
            Handle plugin execution request.
            
            Args:
                page_id: Page identifier from URL path
                
            Returns:
                JSON response with plugin execution results
            """
            try:
                # Get browser navigator
                browser_navigator = browser_navigator_getter()
                if not browser_navigator:
                    return jsonify({
                        "success": False,
                        "error": "Browser not initialized"
                    }), 500
                
                # Parse request body (empty dict if no body)
                data = await request.get_json() or {}
                
                # Apply default values from parameter schema
                params = apply_default_values(plugin, data)
                
                # Validate parameters
                is_valid, error = validate_plugin_params(plugin, params, detailed=False)
                if not is_valid:
                    return jsonify({
                        "success": False,
                        "error": error
                    }), 400
                
                # Execute plugin
                result = await plugin.execute(browser_navigator, page_id, params)
                
                # Ensure result has success field
                if "success" not in result:
                    result["success"] = True
                
                return jsonify(result)
                
            except Exception as e:
                return jsonify({
                    "success": False,
                    "error": str(e),
                    "plugin": plugin_name
                }), 500
        
        return handler
    
    # Create and register the handler
    handler_func = make_handler(plugin_instance)
    handler_func.__name__ = f"plugin_{plugin_name.replace('-', '_')}"
    
    app.add_url_rule(
        route_path,
        view_func=handler_func,
        methods=methods
    )
    
    print(f"   {'/'.join(methods):8} {route_path}")


# Backward compatibility functions (deprecated, use lib.plugin_validator instead)
def _apply_defaults(plugin: Any, params: dict) -> dict:
    """
    DEPRECATED: Use lib.plugin_validator.apply_default_values instead.
    Apply default values from plugin parameter schema.
    """
    from lib.plugin_validator import apply_default_values
    return apply_default_values(plugin, params)


def _validate_params(plugin: Any, params: dict) -> str | None:
    """
    DEPRECATED: Use lib.plugin_validator.validate_plugin_params instead.
    Validate request parameters against plugin schema.
    """
    from lib.plugin_validator import validate_plugin_params
    is_valid, error = validate_plugin_params(plugin, params, detailed=False)
    return None if is_valid else error


def _register_metadata_endpoint(app, url_prefix: str) -> None:
    """
    Register endpoint that returns metadata for all plugins.
    
    Args:
        app: Quart app instance
        url_prefix: API version prefix
    """
    route_path = f"{url_prefix}/plugins"
    
    @app.route(route_path, methods=["GET"])
    async def get_plugins_metadata():
        """
        Get metadata for all registered plugins.
        
        Returns:
            JSON with plugin list and their schemas
        """
        try:
            registry = get_plugin_registry()
            plugins = registry.list_plugins()
            
            plugins_config = []
            for name, plugin in plugins.items():
                plugins_config.append({
                    "name": plugin.metadata.name,
                    "description": plugin.metadata.description,
                    "methods": plugin.metadata.methods,
                    "bg_color": plugin.metadata.bg_color,
                    "parameters": [
                        {
                            "name": p.name,
                            "type": p.type,
                            "label": p.label,
                            "required": p.required,
                            "default": p.default,
                            "placeholder": p.placeholder,
                            "options": p.options if p.options else [],
                            "help_text": p.help_text
                        }
                        for p in plugin.metadata.parameters
                    ]
                })
            
            return jsonify({
                "success": True,
                "count": len(plugins_config),
                "plugins": plugins_config
            })
            
        except Exception as e:
            return jsonify({
                "success": False,
                "error": str(e)
            }), 500
    
    print(f"   GET      {route_path}")
