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.auth_routes import router as auth_router
from api.test_chat_route import router as test_router
from api.team_routes import router as team_router
from api.inbound_webhook_routes import router as webhook_router
from api.documents.documents_routes import router as documents_router  # DOCX/PDF management
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")

    # SQLite initialization (required)
    from common.sqlite_client import init_sqlite
    await init_sqlite()
    logger.info("✅ SQLite 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.sqlite_client import close_sqlite
        await close_sqlite()
        logger.info("SQLite connection closed")
    except Exception as e:
        logger.debug(f"Error closing SQLite: {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(auth_router)
app.include_router(chatbot_router)
app.include_router(memos_router)
app.include_router(team_router)
app.include_router(webhook_router)  # Inbound webhooks
app.include_router(documents_router)  # DOCX/PDF document management

# ==========================================
# 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",
    )
