"""
Unified API module for Hindsight.

Provides both HTTP REST API and MCP (Model Context Protocol) server.
"""

import logging
from contextlib import asynccontextmanager

from fastapi import FastAPI

from hindsight_api import MemoryEngine

logger = logging.getLogger(__name__)


def create_app(
    memory: MemoryEngine,
    http_api_enabled: bool = True,
    mcp_api_enabled: bool = False,
    mcp_mount_path: str = "/mcp",
    initialize_memory: bool = True,
) -> FastAPI:
    """
    Create and configure the unified Hindsight API application.

    Args:
        memory: MemoryEngine instance (already initialized with required parameters).
                Migrations are controlled by the MemoryEngine's run_migrations parameter.
        http_api_enabled: Whether to enable HTTP REST API endpoints (default: True)
        mcp_api_enabled: Whether to enable MCP server (default: False)
        mcp_mount_path: Path to mount MCP server (default: /mcp)
        initialize_memory: Whether to initialize memory system on startup (default: True)

    Returns:
        Configured FastAPI application with enabled APIs

    Example:
        # HTTP only
        app = create_app(memory)

        # MCP only
        app = create_app(memory, http_api_enabled=False, mcp_api_enabled=True)

        # Both HTTP and MCP
        app = create_app(memory, mcp_api_enabled=True)
    """
    mcp_servers = None

    # Create MCP servers first if enabled (we need their lifespans for chaining)
    if mcp_api_enabled:
        try:
            from .mcp import MCPMiddleware, create_mcp_servers

            mcp_servers = create_mcp_servers(memory=memory)
        except ImportError as e:
            logger.error(f"MCP server requested but dependencies not available: {e}")
            logger.error("Install with: pip install hindsight-api[mcp]")
            raise

    # Import and create HTTP API if enabled
    if http_api_enabled:
        from .http import create_app as create_http_app

        app = create_http_app(memory=memory, initialize_memory=initialize_memory)
        logger.info("HTTP REST API enabled")
    else:
        # Create minimal FastAPI app
        app = FastAPI(title="Hindsight API", version="0.0.7")
        logger.info("HTTP REST API disabled")

    # Add MCP middleware and chain its lifespan if enabled
    if mcp_servers is not None:
        multi_bank_server, single_bank_server, multi_bank_starlette_app, single_bank_starlette_app = mcp_servers

        # Store the original lifespan
        original_lifespan = app.router.lifespan_context

        @asynccontextmanager
        async def chained_lifespan(app_instance: FastAPI):
            """Chain both MCP lifespans with the main app lifespan."""
            # Start both MCP lifespans (multi-bank and single-bank)
            async with multi_bank_starlette_app.router.lifespan_context(multi_bank_starlette_app):
                async with single_bank_starlette_app.router.lifespan_context(single_bank_starlette_app):
                    logger.info("MCP lifespans started (multi-bank and single-bank)")
                    # Then start the original app lifespan
                    async with original_lifespan(app_instance):
                        yield
                logger.info("MCP lifespans stopped")

        # Replace the app's lifespan with the chained version
        app.router.lifespan_context = chained_lifespan

        # Add MCP as a wrapping middleware — intercepts /mcp* requests directly,
        # passes everything else through to the FastAPI app. No Starlette Mount
        # means no 307 redirect for /mcp (no trailing slash).
        app.add_middleware(
            MCPMiddleware,
            memory=memory,
            prefix=mcp_mount_path,
            multi_bank_app=multi_bank_starlette_app,
            single_bank_app=single_bank_starlette_app,
            multi_bank_server=multi_bank_server,
            single_bank_server=single_bank_server,
        )

        logger.info(f"MCP server enabled at {mcp_mount_path}/")

    return app


# Re-export commonly used items for backwards compatibility
from .http import (
    CreateBankRequest,
    DispositionTraits,
    MemoryItem,
    RecallRequest,
    RecallResponse,
    RecallResult,
    ReflectRequest,
    ReflectResponse,
    RetainRequest,
)

__all__ = [
    "create_app",
    "RecallRequest",
    "RecallResult",
    "RecallResponse",
    "MemoryItem",
    "RetainRequest",
    "ReflectRequest",
    "ReflectResponse",
    "CreateBankRequest",
    "DispositionTraits",
]
