import uuid
from datetime import datetime, timezone

from fastapi import FastAPI
from sqlalchemy import text

from app.core.config import settings
from app.core.database import SessionLocal, init_db
from app.core.errors import AppError, app_error_handler
from app.core.logging_config import setup_logging
from app.core.security import hash_password
from app.i18n.loader import load_strings
from app.models.catalog import UserAccount

# setup_logging() is called inside on_startup to avoid conflicting with uvicorn


def _ensure_default_user(db, username: str, password: str, role: str, display_name: str) -> None:
    existing = db.query(UserAccount).filter(UserAccount.username == username).first()
    if existing:
        return
    now = datetime.now(timezone.utc).isoformat()
    user = UserAccount(
        id=str(uuid.uuid4()),
        username=username,
        display_name=display_name,
        password_hash=hash_password(password),
        role=role,
        is_active=1,
        created_at=now,
        updated_at=now,
    )
    db.add(user)
    db.commit()


# 앱 로드 시점에 DB 테이블 보장 (서버 시작 전에 실행)
init_db()


def create_app() -> FastAPI:
    app = FastAPI(title=settings.app_name, docs_url="/api/docs", openapi_url="/api/openapi.json")

    @app.on_event("startup")
    def on_startup():
        setup_logging()
        load_strings()
        db = SessionLocal()
        try:
            _ensure_default_user(
                db,
                settings.default_admin_username,
                settings.default_admin_password,
                "admin",
                "관리자",
            )
            _ensure_default_user(
                db,
                settings.default_creator_username,
                settings.default_creator_password,
                "creator",
                "크리에이터",
            )

            # Recover stale pipeline progress from previous crash/restart
            from app.core.task_registry import recover_stale_progress
            recovered = recover_stale_progress(db)
            if recovered:
                import logging
                logging.getLogger(__name__).warning(
                    "Recovered %d stale pipeline progress entries on startup", recovered
                )
        finally:
            db.close()

    app.add_exception_handler(AppError, app_error_handler)

    # Register routers
    from app.api.v1.auth import router as auth_router
    from app.api.v1.users import router as users_router
    from app.api.v1.projects import router as projects_router, activity_router
    from app.api.v1.episodes import router as episodes_router
    from app.api.v1.entities import router as entities_router
    from app.api.v1.images import router as images_router
    from app.api.v1.exports import router as exports_router, import_router as project_import_router
    from app.api.v1.operations import router as operations_router
    app.include_router(auth_router)
    app.include_router(users_router)
    app.include_router(projects_router)
    app.include_router(activity_router)
    app.include_router(episodes_router)
    app.include_router(entities_router)
    app.include_router(images_router)
    app.include_router(exports_router)
    app.include_router(project_import_router)
    app.include_router(operations_router)

    @app.get("/api/v1/health")
    def health_check():
        from app.core.database import SessionLocal
        from app.modules.llm.gemini_key_pool import key_count
        db_ok = False
        try:
            db = SessionLocal()
            db.execute(text("SELECT 1"))
            db_ok = True
            db.close()
        except Exception:
            pass
        return {
            "status": "ok" if db_ok else "degraded",
            "db": "ok" if db_ok else "error",
            "gemini_keys": key_count(),
            "openai_key": bool(settings.openai_api_key),
        }

    return app


app = create_app()
