from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select, update
from typing import List
from datetime import datetime
from decimal import Decimal

from app.database import get_db
from app.models import User, SportEvent, SpreadBet, AdminSettings, EventStatus
from app.schemas.sport_event import SportEventCreate, SportEventUpdate, SportEvent as SportEventSchema
from app.routers.auth import get_current_user

router = APIRouter(prefix="/api/v1/admin", tags=["admin"])


# Dependency to check if user is admin
async def get_admin_user(current_user: User = Depends(get_current_user)) -> User:
    if not current_user.is_admin:
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="Admin access required"
        )
    return current_user


@router.get("/settings")
async def get_admin_settings(
    db: AsyncSession = Depends(get_db),
    admin: User = Depends(get_admin_user)
):
    result = await db.execute(select(AdminSettings).limit(1))
    settings = result.scalar_one_or_none()
    if not settings:
        settings = AdminSettings()
        db.add(settings)
        await db.commit()
        await db.refresh(settings)
    return settings


@router.patch("/settings")
async def update_admin_settings(
    updates: dict,
    db: AsyncSession = Depends(get_db),
    admin: User = Depends(get_admin_user)
):
    result = await db.execute(select(AdminSettings).limit(1))
    settings = result.scalar_one_or_none()
    if not settings:
        settings = AdminSettings()
        db.add(settings)

    for key, value in updates.items():
        if hasattr(settings, key):
            setattr(settings, key, value)

    await db.commit()
    await db.refresh(settings)
    return settings


@router.post("/events", response_model=SportEventSchema)
async def create_event(
    event_data: SportEventCreate,
    db: AsyncSession = Depends(get_db),
    admin: User = Depends(get_admin_user)
):
    event = SportEvent(
        **event_data.model_dump(),
        created_by=admin.id
    )
    db.add(event)
    await db.commit()
    await db.refresh(event)
    return event


@router.get("/events", response_model=List[SportEventSchema])
async def list_events(
    skip: int = 0,
    limit: int = 50,
    db: AsyncSession = Depends(get_db),
    admin: User = Depends(get_admin_user)
):
    result = await db.execute(
        select(SportEvent).offset(skip).limit(limit).order_by(SportEvent.game_time.desc())
    )
    return result.scalars().all()


@router.patch("/events/{event_id}", response_model=SportEventSchema)
async def update_event(
    event_id: int,
    updates: SportEventUpdate,
    db: AsyncSession = Depends(get_db),
    admin: User = Depends(get_admin_user)
):
    result = await db.execute(select(SportEvent).where(SportEvent.id == event_id))
    event = result.scalar_one_or_none()
    if not event:
        raise HTTPException(status_code=404, detail="Event not found")

    update_data = updates.model_dump(exclude_unset=True)
    for key, value in update_data.items():
        setattr(event, key, value)

    await db.commit()
    await db.refresh(event)
    return event


@router.delete("/events/{event_id}")
async def delete_event(
    event_id: int,
    db: AsyncSession = Depends(get_db),
    admin: User = Depends(get_admin_user)
):
    result = await db.execute(select(SportEvent).where(SportEvent.id == event_id))
    event = result.scalar_one_or_none()
    if not event:
        raise HTTPException(status_code=404, detail="Event not found")

    # Check if there are any matched bets
    bets_result = await db.execute(
        select(SpreadBet).where(
            SpreadBet.event_id == event_id,
            SpreadBet.status != "open"
        )
    )
    if bets_result.scalar_one_or_none():
        raise HTTPException(
            status_code=400,
            detail="Cannot delete event with matched bets"
        )

    await db.delete(event)
    await db.commit()
    return {"message": "Event deleted"}
