"""
NEXIUM Routing - Modern router with path parameters and type hints
Author: Juste Elysée MALANDILA
"""

from typing import Callable, List, Optional, Dict, Any
from dataclasses import dataclass
import inspect
import re


@dataclass
class RouteInfo:
    """Route information."""
    path: str
    endpoint: Callable
    methods: List[str]
    name: Optional[str] = None
    tags: Optional[List[str]] = None


class Router:
    """
    Modern router with FastAPI-like syntax.
    
    Example:
        >>> router = Router()
        >>> 
        >>> @router.get("/users/{id}")
        >>> async def get_user(id: int):
        >>>     return {"id": id}
    """
    
    def __init__(self, prefix: str = "", tags: Optional[List[str]] = None):
        """
        Initialize router.
        
        Args:
            prefix: URL prefix for all routes
            tags: Tags for grouping routes
        """
        self.prefix = prefix
        self.tags = tags or []
        self.routes: List[RouteInfo] = []
    
    def add_route(
        self,
        path: str,
        endpoint: Callable,
        methods: List[str] = ["GET"],
        name: Optional[str] = None,
        tags: Optional[List[str]] = None,
    ):
        """Add a route to the router."""
        full_path = f"{self.prefix}{path}"
        route_tags = self.tags + (tags or [])
        
        route = RouteInfo(
            path=full_path,
            endpoint=endpoint,
            methods=methods,
            name=name or endpoint.__name__,
            tags=route_tags if route_tags else None,
        )
        
        self.routes.append(route)
        return route
    
    def route(
        self,
        path: str,
        methods: List[str] = ["GET"],
        name: Optional[str] = None,
        tags: Optional[List[str]] = None,
    ):
        """Route decorator."""
        def decorator(func: Callable):
            self.add_route(path, func, methods=methods, name=name, tags=tags)
            return func
        return decorator
    
    def get(self, path: str, **kwargs):
        """GET route."""
        return self.route(path, methods=["GET"], **kwargs)
    
    def post(self, path: str, **kwargs):
        """POST route."""
        return self.route(path, methods=["POST"], **kwargs)
    
    def put(self, path: str, **kwargs):
        """PUT route."""
        return self.route(path, methods=["PUT"], **kwargs)
    
    def delete(self, path: str, **kwargs):
        """DELETE route."""
        return self.route(path, methods=["DELETE"], **kwargs)
    
    def patch(self, path: str, **kwargs):
        """PATCH route."""
        return self.route(path, methods=["PATCH"], **kwargs)
    
    def include_router(
        self,
        router: "Router",
        prefix: str = "",
        tags: Optional[List[str]] = None,
    ):
        """Include another router."""
        for route in router.routes:
            new_path = f"{prefix}{route.path}"
            new_tags = (self.tags + (tags or []) + (route.tags or []))
            self.add_route(
                new_path,
                route.endpoint,
                methods=route.methods,
                name=route.name,
                tags=new_tags if new_tags else None,
            )


# Standalone decorators (for convenience)
def route(path: str, methods: List[str] = ["GET"], **kwargs):
    """Standalone route decorator."""
    def decorator(func: Callable):
        func._route_info = {
            "path": path,
            "methods": methods,
            **kwargs,
        }
        return func
    return decorator


def get(path: str, **kwargs):
    """Standalone GET decorator."""
    return route(path, methods=["GET"], **kwargs)


def post(path: str, **kwargs):
    """Standalone POST decorator."""
    return route(path, methods=["POST"], **kwargs)


def put(path: str, **kwargs):
    """Standalone PUT decorator."""
    return route(path, methods=["PUT"], **kwargs)


def delete(path: str, **kwargs):
    """Standalone DELETE decorator."""
    return route(path, methods=["DELETE"], **kwargs)


def patch(path: str, **kwargs):
    """Standalone PATCH decorator."""
    return route(path, methods=["PATCH"], **kwargs)
