from flask import jsonify, request
from functools import wraps
from typing import Callable, Optional, Type, Any
from pydantic import BaseModel, ValidationError
import inspect


class APIRouter:
    """Helper for creating API routes"""
    
    @staticmethod
    def json_response(data, status=200):
        """Create a JSON response"""
        return jsonify(data), status
    
    @staticmethod
    def error_response(message, status=400):
        """Create an error response"""
        return jsonify({'error': message}), status
    
    @staticmethod
    def success_response(message, data=None, status=200):
        """Create a success response"""
        response = {'success': True, 'message': message}
        if data:
            response['data'] = data
        return jsonify(response), status


_routes = []


def route(path: str, methods: list = None):
    """Decorator for API routes"""
    if methods is None:
        methods = ['GET']
    
    def decorator(func: Callable):
        @wraps(func)
        def wrapper(*args, **kwargs):
            return func(*args, **kwargs)
        
        wrapper._route_path = path
        wrapper._route_methods = methods
        _routes.append(wrapper)
        return wrapper
    
    return decorator


def get(path: str):
    """Decorator for GET routes"""
    return route(path, methods=['GET'])


def post(path: str):
    """Decorator for POST routes"""
    return route(path, methods=['POST'])


def put(path: str):
    """Decorator for PUT routes"""
    return route(path, methods=['PUT'])


def delete(path: str):
    """Decorator for DELETE routes"""
    return route(path, methods=['DELETE'])


def api_handler(app):
    """Register all API routes with Flask app"""
    for route_func in _routes:
        path = route_func._route_path
        methods = route_func._route_methods
        app.add_url_rule(path, view_func=route_func, methods=methods)


def validate_request(model: Type[BaseModel]):
    """Decorator to validate request data against Pydantic model"""
    def decorator(func: Callable):
        @wraps(func)
        def wrapper(*args, **kwargs):
            try:
                if request.is_json:
                    data = request.get_json()
                else:
                    data = request.form.to_dict()
                
                validated_data = model(**data)
                
                sig = inspect.signature(func)
                if 'data' in sig.parameters:
                    kwargs['data'] = validated_data
                
                return func(*args, **kwargs)
            except ValidationError as e:
                return jsonify({'error': 'Validation failed', 'details': e.errors()}), 400
        
        return wrapper
    return decorator
