from fastapi import FastAPI, Request
from fastapi.responses import JSONResponse
from fastapi.middleware.cors import CORSMiddleware
from app.api.endpoints import router
from app.api.websocket import router as ws_router
from app.api.shopify import router as shopify_router
from app.api.sources import router as sources_router
from app.api.catalog import router as catalog_router
from app.core.config import settings
from app.services.infra.quotas import QuotaExceededError
from app.services.infra.redis import redis_pool
import uvicorn
import logging
import time

# Setup production-grade logging
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger("main")

app = FastAPI(title="Strategist AI Service")

# Configurable CORS
origins = [o.strip() for o in settings.ALLOWED_ORIGINS.split(",")]
app.add_middleware(
    CORSMiddleware,
    allow_origins=origins,
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

# Global Quota Exception Handler
@app.exception_handler(QuotaExceededError)
async def quota_exception_handler(request: Request, exc: QuotaExceededError):
    logger.warning(f"Quota exceeded: {exc.message}")
    return JSONResponse(
        status_code=403,
        content={"status": "error", "message": exc.message}
    )

# Global Exception Handler
@app.exception_handler(Exception)
async def global_exception_handler(request: Request, exc: Exception):
    logger.error(f"Unhandled exception: {exc}", exc_info=True)
    return JSONResponse(
        status_code=500,
        content={"status": "error", "message": "An internal server error occurred."}
    )

# Simple timing middleware (Commented out to prevent WebSocket interference)
# @app.middleware("http")
# async def add_process_time_header(request: Request, call_next):
#     start_time = time.time()
#     response = await call_next(request)
#     process_time = time.time() - start_time
#     response.headers["X-Process-Time"] = str(process_time)
#     logger.info(f"Path: {request.url.path} | Method: {request.method} | Time: {process_time:.4f}s")
#     return response

@app.on_event("startup")
async def startup_event():
    # The Redis pool is built at import time. Under gunicorn's pre-fork model
    # that can happen in the master, leaving every worker holding the same
    # cached sockets -- two processes writing to one connection is seen by the
    # server as a corrupt stream, and it hangs up with "Connection reset by
    # peer". Startup runs per worker, after the fork, so dropping the cached
    # connections here guarantees each worker dials its own.
    redis_pool.reset()

    logger.info("Starting Strategist AI Service...")
    logger.info(f"CORS Allowed Origins: {settings.ALLOWED_ORIGINS}")
    logger.info(f"Database Host: {settings.DB_HOST}")
    logger.info(f"LLM Model: {settings.LLM_MODEL}")
    logger.info(f"Embedding Model: {settings.EMBED_MODEL}")
    logger.info("Production readiness audit: OK")

app.include_router(router)
app.include_router(ws_router)
app.include_router(shopify_router)
app.include_router(sources_router)
app.include_router(catalog_router)

@app.get("/")
@app.get("/health")
async def health_check():
    return {
        "status": "healthy",
        "service": "Strategist AI",
        "timestamp": time.time(),
        "version": "1.0.0"
    }

@app.get("/debug-path")
async def debug_path(request: Request):
    return {
        "path": request.url.path,
        "full_url": str(request.url)
    }

if __name__ == "__main__":
    uvicorn.run("app.main:app", host="0.0.0.0", port=8001, reload=True)
