# pylint: disable=broad-exception-caught
import logging
from typing import List, get_args
from fastapi import FastAPI, HTTPException, status

from mini_videorag import __version__
from mini_videorag.temporal.api.routes_base import RouteHandler
from mini_videorag.temporal.api.routes import system_router, workflows_router, storage_router
from mini_videorag.core.exceptions import ProcessorError

logger = logging.getLogger(__name__)


def create_app(routes: List[RouteHandler]) -> FastAPI:
    """
    Create and configure FastAPI application.

    Args:
        routes: List of route handlers to expose

    Returns:
        Configured FastAPI application
    """
    app = FastAPI(
        title="Video RAG API",
        description="""REST API for triggering temporal video processing workflow""",
        version=__version__,
        docs_url="/docs",
        redoc_url="/redoc",
        openapi_url="/openapi.json",
    )

    app.include_router(system_router)
    app.include_router(workflows_router)
    app.include_router(storage_router)

    logger.info(f"Setting up {len(routes)} dynamic service routes")

    for route_obj in routes:
        logger.info(f"Setting up route {route_obj.__class__.__name__} at {route_obj.route}")

        try:
            generic_args = get_args(route_obj.__class__.__orig_bases__[0])
            if generic_args:
                input_type, output_type = generic_args
            else:
                raise RuntimeError(f"Route {route_obj} is not properly typed")
        except Exception as e:
            logger.error(f"Failed to get types for route {route_obj.__class__.__name__}: {e}")
            continue

        def create_route_handler(current_route, current_input_type, current_output_type):
            async def endpoint_handler(
                input_data: current_input_type,
            ) -> current_output_type:
                """Execute the service via HTTP."""
                try:
                    logger.info(f"Handling request for {current_route.__class__.__name__}")
                    result = current_route.handle(input_data)
                    logger.info(f"Request {current_route.__class__.__name__} completed")
                    return result
                except HTTPException:
                    raise
                except ProcessorError as e:
                    logger.error(f"Request {current_route.__class__.__name__} failed: {e}")
                    raise HTTPException(
                        status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
                        detail=f"Request failed: {str(e)}",
                    ) from e
                except (ValueError, TypeError, RuntimeError) as e:
                    logger.error(f"Request {current_route.__class__.__name__} failed: {e}")
                    raise HTTPException(
                        status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
                        detail=f"Request failed: {str(e)}",
                    ) from e
                except Exception as e:
                    logger.error(f"Request {current_route.__class__.__name__} failed: {e}")
                    raise HTTPException(
                        status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
                        detail=f"Request failed: {str(e)}",
                    ) from e

            return endpoint_handler

        endpoint = create_route_handler(route_obj, input_type, output_type)
        app.add_api_route(
            path=route_obj.route,
            endpoint=endpoint,
            methods=["POST"],
            response_model=output_type,
            tags=["Services"],
            summary=f"Execute {route_obj.__class__.__name__}",
            description=route_obj.__class__.__doc__ or f"Execute {route_obj.__class__.__name__}",
        )

        logger.info(f"✅ Route {route_obj.__class__.__name__} registered at POST {route_obj.route}")

    logger.info(f"FastAPI application ready with {len(routes)} dynamic service routes")

    return app
