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

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 common.cache import redis_cache
from common.langfuse_client import get_langfuse_client
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")

    # 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="Contract AI Service",
    description="API for Contract AI Service",
    version="1.0.0",
    lifespan=lifespan,
)


# =============================================================================
# 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,  # tắt slowapi business rate limit
    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)

# ==========================================
# 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("Contract AI Service 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",
    )
