from fastapi import FastAPI, Depends
from fastapi.middleware.cors import CORSMiddleware
from contextlib import asynccontextmanager
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select, func
from decimal import Decimal
from app.database import init_db, get_db
from app.routers import auth, users, wallet, bets, websocket, admin, sport_events, spread_bets, gamification, matches
from app.models import User, Wallet
from app.utils.security import get_password_hash


@asynccontextmanager
async def lifespan(app: FastAPI):
    # Startup
    await init_db()
    yield
    # Shutdown


app = FastAPI(
    title="H2H Betting Platform API",
    description="Peer-to-peer betting platform MVP",
    version="1.0.0",
    lifespan=lifespan
)

# CORS middleware
app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

# Include routers
app.include_router(auth.router)
app.include_router(users.router)
app.include_router(wallet.router)
app.include_router(bets.router)
app.include_router(websocket.router)
app.include_router(admin.router)
app.include_router(sport_events.router)
app.include_router(spread_bets.router)
app.include_router(gamification.router)
app.include_router(matches.router)


@app.get("/")
async def root():
    return {"message": "H2H Betting Platform API", "version": "1.0.0"}


@app.get("/health")
async def health():
    return {"status": "healthy"}


@app.get("/init")
async def init_admin(db: AsyncSession = Depends(get_db)):
    """
    Initialize the application with a default admin user.
    Only works if no admin users exist in the database.
    Creates: admin@test.com / password123
    """
    # Check if any admin users exist
    result = await db.execute(
        select(func.count(User.id)).where(User.is_admin == True)
    )
    admin_count = result.scalar()

    if admin_count > 0:
        return {
            "success": False,
            "message": "Admin user(s) already exist. Initialization skipped.",
            "admin_count": admin_count
        }

    # Check if user with this email already exists
    existing = await db.execute(
        select(User).where(User.email == "admin@test.com")
    )
    if existing.scalar_one_or_none():
        return {
            "success": False,
            "message": "User with email admin@test.com already exists but is not an admin."
        }

    # Create admin user
    admin_user = User(
        email="admin@test.com",
        username="admin",
        password_hash=get_password_hash("password123"),
        display_name="Administrator",
        is_admin=True,
    )
    db.add(admin_user)
    await db.flush()

    # Create wallet for admin
    wallet = Wallet(
        user_id=admin_user.id,
        balance=Decimal("10000.00"),
        escrow=Decimal("0.00"),
    )
    db.add(wallet)

    await db.commit()

    return {
        "success": True,
        "message": "Admin user created successfully",
        "credentials": {
            "email": "admin@test.com",
            "password": "password123"
        }
    }
