import os
from contextlib import asynccontextmanager
from fastapi import FastAPI, Request
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import JSONResponse
from slowapi import Limiter, _rate_limit_exceeded_handler
from slowapi.util import get_remote_address
from slowapi.errors import RateLimitExceeded
from apscheduler.schedulers.asyncio import AsyncIOScheduler
from loguru import logger

from app.config import settings
from app.database import init_db, check_db_connection, SessionLocal
from app.utils.logger import setup_logging
from app.routers import miners, calculate, ai, seed
from app.services.seeder import run_seeder

os.makedirs("logs", exist_ok=True)
setup_logging()

scheduler = AsyncIOScheduler()
limiter = Limiter(key_func=get_remote_address)


async def scheduled_seeder():
    """Run seeder on schedule to keep miner data fresh."""
    logger.info("Scheduled seeder triggered")
    db = SessionLocal()
    try:
        await run_seeder(db)
    except Exception as e:
        logger.error(f"Scheduled seeder failed: {e}")
    finally:
        db.close()


@asynccontextmanager
async def lifespan(app: FastAPI):
    logger.info("Starting Crypto Mining Profitability System...")

    if not check_db_connection():
        logger.error("Cannot connect to database!")
    else:
        init_db()
        logger.info("Database initialized")

    # Schedule weekly refresh of miner data (every Sunday at 2 AM)
    scheduler.add_job(scheduled_seeder, "cron", day_of_week="sun", hour=2, minute=0)
    scheduler.start()
    logger.info("Scheduler started")

    yield

    scheduler.shutdown()
    logger.info("Shutdown complete")


app = FastAPI(
    title="Crypto Mining Profitability API",
    description="نظام حساب أرباح تعدين العملات الرقمية",
    version="1.0.0",
    lifespan=lifespan,
)

# Rate limiting
app.state.limiter = limiter
app.add_exception_handler(RateLimitExceeded, _rate_limit_exceeded_handler)

# CORS
app.add_middleware(
    CORSMiddleware,
    allow_origins=["http://localhost:3000", "http://localhost:5173", "*"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)


@app.exception_handler(Exception)
async def global_exception_handler(request: Request, exc: Exception):
    logger.error(f"Unhandled exception: {exc} | Path: {request.url.path}")
    return JSONResponse(
        status_code=500,
        content={"detail": "Internal server error", "path": str(request.url.path)},
    )


# Routers
app.include_router(miners.router)
app.include_router(calculate.router)
app.include_router(ai.router)
app.include_router(seed.router)


@app.get("/")
async def root():
    return {
        "name": "Crypto Mining Profitability System",
        "version": "1.0.0",
        "status": "running",
        "docs": "/docs",
    }


@app.get("/health")
async def health():
    db_ok = check_db_connection()
    return {
        "status": "healthy" if db_ok else "degraded",
        "database": "connected" if db_ok else "disconnected",
        "scheduler": "running" if scheduler.running else "stopped",
    }
