import asyncio
import os
import platform
import logging
from contextlib import asynccontextmanager

import uvicorn
from fastapi import FastAPI
from fastapi.staticfiles import StaticFiles
from fastapi.responses import RedirectResponse, ORJSONResponse

from api.chatbot import router as chatbot_router
from api.memos import router as memos_router
from api.test_chat_route import router as test_router
from api.team_routes import router as team_router
from common.cache import redis_cache
from common.langfuse_client import get_langfuse_client
from common.meili_service import meili_service
from common.middleware import middleware_manager
from config import PORT, CORS_ORIGINS


# Windows event loop handling
if platform.system() == "Windows":
    print("Windows detected: Applying SelectorEventLoopPolicy globally...")
    asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())

# Configure Logging
logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s [%(levelname)s] %(name)s: %(message)s",
    handlers=[logging.StreamHandler()],
)
logger = logging.getLogger(__name__)


# =============================================================================
# LIFESPAN - Initialize & cleanup resources (replaces deprecated on_event)
# =============================================================================
@asynccontextmanager
async def lifespan(app: FastAPI):
    """Startup & shutdown lifecycle manager."""
    # --- STARTUP ---
    # Initialize Redis (optional - will continue without cache if unavailable)
    redis_client = await redis_cache.initialize()
    if redis_client:
        logger.info("✅ Redis cache initialized for message limit")
    else:
        logger.info("⚠️  Redis cache unavailable - continuing without cache")

    # MongoDB initialization (required)
    from common.mongo_client import init_mongodb
    await init_mongodb()
    logger.info("✅ MongoDB connection initialized")

    # Meilisearch initialization (optional)
    meili_ok = await meili_service.initialize()
    if meili_ok:
        synced = await meili_service.sync_all_memos()
        logger.info("✅ Meilisearch ready (%d memos indexed)", synced)
    else:
        logger.warning("⚠️  Meilisearch unavailable — keyword search disabled")

    # Langfuse initialization (optional)
    langfuse_client = get_langfuse_client()
    if langfuse_client:
        logger.info("✅ Langfuse client ready")
    else:
        logger.warning("⚠️  Langfuse client not available (missing keys or disabled)")

    yield  # App is running

    # --- SHUTDOWN ---
    try:
        redis_client = redis_cache.get_client()
        if redis_client:
            await redis_client.aclose()
            logger.info("Redis connection closed")
    except Exception as e:
        logger.debug(f"Error closing Redis: {e}")

    try:
        from common.mongo_client import close_mongodb
        await close_mongodb()
        logger.info("MongoDB connection closed")
    except Exception as e:
        logger.debug(f"Error closing MongoDB: {e}")


app = FastAPI(
    title="CuCu Note API",
    description="API for CuCu Note - Privacy-First Note-Taking Application",
    version="1.0.0",
    lifespan=lifespan,
    default_response_class=ORJSONResponse,
)


# =============================================================================
# MIDDLEWARE SETUP - Gom Auth + RateLimit + CORS vào một chỗ
# =============================================================================
middleware_manager.setup(
    app,
    enable_auth=True,        # bật/tắt Auth
    enable_rate_limit=False,  # SlowAPI not installed; chat rate limit handled by CuCuAuthMiddleware
    enable_cors=True,         # bật CORS
    cors_origins=CORS_ORIGINS,  # từ environment variable
)

app.include_router(test_router)   # No-auth test endpoints
app.include_router(chatbot_router)
app.include_router(memos_router)
app.include_router(team_router)

# ==========================================
# Mount static HTML
# ==========================================
try:
    static_dir = os.path.join(os.path.dirname(__file__), "static")
    if not os.path.exists(static_dir):
        os.makedirs(static_dir)
    app.mount("/static", StaticFiles(directory=static_dir, html=True), name="static")
    print(f"Static files mounted at /static (Dir: {static_dir})")
except Exception as e:
    print(f"Failed to mount static files: {e}")


@app.get("/")
async def root():
    return RedirectResponse(url="/static/index.html")


if __name__ == "__main__":
    print("=" * 60)
    print("CuCu Note API Starting...")
    print("=" * 60)
    print(f"REST API: http://localhost:{PORT}")
    print(f"Test Chatbot: http://localhost:{PORT}/static/index.html")
    print(f"API Docs: http://localhost:{PORT}/docs")
    print("=" * 60)

    ENABLE_RELOAD = False
    print(f"Hot reload: {ENABLE_RELOAD}")

    reload_dirs = ["common", "api", "agent"]

    if ENABLE_RELOAD:
        os.environ["PYTHONUNBUFFERED"] = "1"

    uvicorn.run(
        "server:app",
        host="0.0.0.0",
        port=PORT,
        reload=ENABLE_RELOAD,
        reload_dirs=reload_dirs,
        log_level="info",
    )
