from __future__ import annotations
import sys
from typing import Any, Callable, Dict, Optional
from urllib.parse import parse_qs


class Router:
    """A simple router for Kodi add-ons."""

    def __init__(self) -> None:
        self._routes: Dict[str, Callable[[Dict[str, str]], Any]] = {}
        self._fallback: Optional[Callable[[Dict[str, str]], Any]] = None

    def route(self, action: str) -> Callable[[Callable[[Dict[str, str]], Any]], Callable[[Dict[str, str]], Any]]:
        """Decorator to register a function for a specific action."""
        def decorator(handler: Callable[[Dict[str, str]], Any]) -> Callable[[Dict[str, str]], Any]:
            self._routes[action] = handler
            return handler
        return decorator

    def fallback(self) -> Callable[[Callable[[Dict[str, str]], Any]], Callable[[Dict[str, str]], Any]]:
        """Decorator to register the fallback (default) handler."""
        def decorator(handler: Callable[[Dict[str, str]], Any]) -> Callable[[Dict[str, str]], Any]:
            self._fallback = handler
            return handler
        return decorator

    def dispatch(self, action: Optional[str] = None, params: Optional[Dict[str, str]] = None) -> Any:
        """Dispatch the request to the registered handler."""
        if params is None:
            params = {}
        
        handler = self._routes.get(action) if action else self._fallback
        if not handler:
            handler = self._fallback
            
        if handler:
            return handler(params)
        
        raise KeyError(f"No route or fallback defined for action: {action}")


def parse_params(argv: Optional[list[str]] = None) -> dict[str, str]:
    """Parst Kodi-Plugin-Parameter aus `sys.argv[2]` oder der übergebenen Liste."""
    if argv is None:
        argv = sys.argv
    if len(argv) <= 2 or not argv[2]:
        return {}
    raw_params = parse_qs(argv[2].lstrip("?"), keep_blank_values=True)
    return {key: values[0] for key, values in raw_params.items()}


def parse_positive_int(value: str, *, default: int = 1) -> int:
    try:
        parsed = int(value)
        return parsed if parsed > 0 else default
    except (ValueError, TypeError):
        return default
