import logging
import os
from contextlib import asynccontextmanager
from pathlib import Path

import uvicorn
from fastapi import FastAPI
from fastapi.staticfiles import StaticFiles

import vna_system.core.singletons as singletons
from vna_system.api.endpoints import acquisition, health, settings, web_ui
from vna_system.api.websockets import processing as ws_processing
from vna_system.core.config import API_HOST, API_PORT
from vna_system.core.logging.logger import get_component_logger, setup_logging

PROJECT_ROOT = Path(__file__).resolve().parents[1]
LOG_DIR = PROJECT_ROOT / "logs"
setup_logging(log_level=os.getenv("VNA_LOG_LEVEL", "INFO"), log_dir=LOG_DIR)

for noisy in (
    "uvicorn.error",
    "uvicorn.access",
):
    logging.getLogger(noisy).setLevel(logging.ERROR)

logger = get_component_logger(__file__)


@asynccontextmanager
async def lifespan(app: FastAPI):
    logger.info("Starting VNA API Server")
    try:
        logger.info("Starting data acquisition")
        singletons.vna_data_acquisition_instance.start()

        logger.info("Starting processor system")
        singletons.processor_manager.start_processing()
        logger.info(
            "Processor system started",
            processors=singletons.processor_manager.list_processors(),
        )

        logger.info("VNA API Server started successfully")
        yield
    except Exception as exc:
        logger.error("Error during startup", error=repr(exc))
        raise
    logger.info("Shutting down VNA API Server")

    if singletons.processor_manager:
        singletons.processor_manager.stop_processing()
        logger.info("Processor system stopped")

    if getattr(singletons, "vna_data_acquisition_instance", None) and singletons.vna_data_acquisition_instance._running:
        singletons.vna_data_acquisition_instance.stop()
        logger.info("Acquisition stopped")

    logger.info("VNA API Server shutdown complete")


app = FastAPI(
    title="VNA System API",
    description="Real-time VNA data acquisition and processing API",
    version="1.0.0",
    lifespan=lifespan,
)

WEB_UI_DIR = Path(__file__).parent / "web_ui"
STATIC_DIR = WEB_UI_DIR / "static"
if STATIC_DIR.exists():
    app.mount("/static", StaticFiles(directory=str(STATIC_DIR)), name="static")
    logger.info("Mounted static files", directory=str(STATIC_DIR))
else:
    logger.warning("Static directory not found", directory=str(STATIC_DIR))

app.include_router(web_ui.router)
app.include_router(health.router)
app.include_router(acquisition.router)
app.include_router(settings.router)
app.include_router(ws_processing.router)


def main() -> None:
    host = os.getenv("VNA_HOST", API_HOST)
    port_env = os.getenv("VNA_PORT")
    if port_env is not None:
        try:
            port = int(port_env)
        except ValueError:
            logger.warning("Invalid VNA_PORT, falling back to config", VNA_PORT=port_env)
            port = API_PORT
    else:
        port = API_PORT

    logger.info("Launching Uvicorn", host=host, port=port)
    uvicorn.run(
        "vna_system.main:app",
        host=host,
        port=port,
        log_level="info",
        reload=False,
    )


if __name__ == "__main__":
    main()
