import logging
import os

from fastapi import FastAPI, Request
from fastapi.exceptions import RequestValidationError
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import JSONResponse
from fastapi.staticfiles import StaticFiles

from src.api.config import config_profiles_router, user_config_router
from src.api.project import git_repositories_router, projects_router
from src.api.system import (
    dashboard_router,
    events_router,
    health_router,
    instance_proxy_router,
    notifications_router,
    terminal_router,
)
from src.api.tool import (
    sessions_router,
    tool_definitions_router,
    tool_instances_router,
    tool_lifecycle_router,
    tool_types_router,
)
from src.api.user import auth_router, ssh_keys_router, users_router
from src.api.workspace import (
    all_workspaces_router,
    workspace_files_router,
    workspace_git_router,
    workspace_instances_router,
    workspaces_router,
)
from src.config import Settings
from src.models import Notification  # noqa: F401 – Alembic model discovery
from src.models import TerminalSessionModel  # noqa: F401 – Alembic model discovery
from src.database import init_database
from src.logging_config import (
    ExceptionLoggingMiddleware,
    RequestLoggingMiddleware,
    configure_logging,
)
from src.seeds.builtin_tool_types import seed_builtin_tool_types
from src.services.instance import InstanceEventBus, HealthMonitor
from src.services.shared import CorrelationIdMiddleware

# Configure logging early
log_level = os.getenv("LOG_LEVEL", "INFO").upper()
configure_logging(level=getattr(logging, log_level, logging.INFO))

logger = logging.getLogger(__name__)
settings = Settings()
app = FastAPI(title="Headquarter API")

# Configure CORS - must be before other middleware
# Build allowed origins list including web and api domains
cors_origins = [settings.web_base_url]
if settings.api_base_url != settings.web_base_url:
    cors_origins.append(settings.api_base_url)
logger.info("CORS configured with origins: %s", cors_origins)

app.add_middleware(
    CORSMiddleware,
    allow_origins=cors_origins,
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

app.add_middleware(CorrelationIdMiddleware)
app.add_middleware(RequestLoggingMiddleware)
app.add_middleware(ExceptionLoggingMiddleware)


def _sanitize_validation_errors(errors):
    """Convert validation errors to JSON-safe format."""
    sanitized = []
    for error in errors:
        safe_error = {
            "type": error.get("type"),
            "loc": error.get("loc"),
            "msg": error.get("msg"),
            "input": str(error.get("input"))
            if error.get("input") is not None
            else None,
        }
        # Convert ctx to safe format
        ctx = error.get("ctx")
        if ctx:
            safe_ctx = {}
            for key, value in ctx.items():
                if isinstance(value, Exception):
                    safe_ctx[key] = str(value)
                elif isinstance(value, (str, int, float, bool, type(None))):
                    safe_ctx[key] = value
                else:
                    safe_ctx[key] = str(value)
            safe_error["ctx"] = safe_ctx
        sanitized.append(safe_error)
    return sanitized


@app.exception_handler(RequestValidationError)
async def validation_exception_handler(request: Request, exc: RequestValidationError):
    """Log validation errors and return detailed response."""
    errors = exc.errors()
    logger.warning(
        "Validation error for %s %s: %s",
        request.method,
        request.url.path,
        errors,
    )
    safe_errors = _sanitize_validation_errors(errors)
    return JSONResponse(
        status_code=422,
        content={"detail": safe_errors},
    )


# Global services
_event_bus = InstanceEventBus()
_health_monitor = HealthMonitor(_event_bus)


@app.on_event("startup")
async def on_startup():
    logger.info("Starting up Headquarter API...")

    # Initialize database (run migrations)
    db_ready = await init_database()
    if not db_ready:
        logger.error("Database initialization failed. Shutting down.")
        import sys

        sys.exit(1)

    # Start background health monitor
    _health_monitor.start()
    logger.info("Health monitor started")

    # Seed built-in tool types
    await seed_builtin_tool_types()
    logger.info("Built-in tool types seeded")

    logger.info("Startup complete.")


@app.on_event("shutdown")
async def on_shutdown():
    logger.info("Shutting down Headquarter API...")
    _health_monitor.stop()
    logger.info("Health monitor stopped")
    logger.info("Shutdown complete.")


app.include_router(health_router)
app.include_router(auth_router)
app.include_router(dashboard_router)
app.include_router(projects_router)
app.include_router(users_router)
app.include_router(ssh_keys_router)
app.include_router(git_repositories_router)
app.include_router(user_config_router)
app.include_router(tool_types_router)
app.include_router(tool_definitions_router)
app.include_router(config_profiles_router)
app.include_router(tool_instances_router)
app.include_router(tool_lifecycle_router)
app.include_router(sessions_router)
app.include_router(instance_proxy_router)
app.include_router(terminal_router)
app.include_router(events_router)
app.include_router(notifications_router)
app.include_router(all_workspaces_router)
app.include_router(workspaces_router)
app.include_router(workspace_files_router)
app.include_router(workspace_git_router)
app.include_router(workspace_instances_router)
app.mount("/uploads", StaticFiles(directory="uploads"), name="uploads")
