"""Application factory and lifespan wiring for the transcription app."""

from __future__ import annotations

from contextlib import asynccontextmanager
from threading import Event, Thread

from fastapi import FastAPI

from transcription.api.errors import register_error_handlers
from transcription.api.health import router as health_router
from transcription.api.routes import router as transcription_router
from transcription.config import get_settings, setup_logging
from transcription.db import (
    create_all,
    dispose_database_runtime,
    initialize_database_runtime,
    should_bootstrap_schema,
)
from transcription.ui import register_pages
from transcription.worker import run_worker_loop


def _start_worker(app: FastAPI) -> None:
    stop_event = Event()
    worker_thread = Thread(
        target=run_worker_loop,
        kwargs={
            "engine": app.state.db_runtime.engine,
            "stop_event": stop_event,
            "poll_interval_seconds": 1.0,
        },
        daemon=True,
    )
    worker_thread.start()
    app.state.worker_stop_event = stop_event
    app.state.worker_thread = worker_thread


def _stop_worker(app: FastAPI) -> None:
    stop_event = getattr(app.state, "worker_stop_event", None)
    worker_thread = getattr(app.state, "worker_thread", None)

    if stop_event is not None:
        stop_event.set()
    if worker_thread is not None:
        worker_thread.join(timeout=2.0)


@asynccontextmanager
async def _lifespan(app: FastAPI):
    setup_logging()

    settings = get_settings()
    app.state.settings = settings
    app.state.db_runtime = initialize_database_runtime(settings=settings)

    if should_bootstrap_schema(settings):
        create_all(engine=app.state.db_runtime.engine)

    settings.upload_dir.mkdir(parents=True, exist_ok=True)
    settings.prompt_dir.mkdir(parents=True, exist_ok=True)

    _start_worker(app)
    try:
        yield
    finally:
        _stop_worker(app)
        dispose_database_runtime()


def create_app() -> FastAPI:
    """Create and configure the FastAPI application."""
    app = FastAPI(title="Transcription", lifespan=_lifespan)
    register_error_handlers(app)
    register_pages(app)
    app.include_router(health_router)
    app.include_router(transcription_router)
    return app

