from typing import Optional
from fastapi import APIRouter, Depends, HTTPException, Query
from sqlalchemy import select, func
from sqlalchemy.ext.asyncio import AsyncSession

from ..database import get_db
from ..db_models import Background, Difficulty
from ..schemas import (
    BackgroundCreate,
    BackgroundUpdate,
    BackgroundResponse,
    BackgroundListResponse,
)

router = APIRouter(prefix="/backgrounds", tags=["backgrounds"])


@router.get("", response_model=BackgroundListResponse)
async def list_backgrounds(
    skip: int = Query(0, ge=0),
    limit: int = Query(100, ge=1, le=500),
    difficulty: Optional[Difficulty] = None,
    search: Optional[str] = None,
    db: AsyncSession = Depends(get_db),
):
    """List all backgrounds with pagination and filtering."""
    query = select(Background)

    if difficulty:
        query = query.where(Background.difficulty == difficulty)
    if search:
        query = query.where(Background.name.ilike(f"%{search}%"))

    # Count total
    count_query = select(func.count(Background.id))
    if difficulty:
        count_query = count_query.where(Background.difficulty == difficulty)
    if search:
        count_query = count_query.where(Background.name.ilike(f"%{search}%"))
    total_result = await db.execute(count_query)
    total = total_result.scalar()

    # Get items
    query = query.order_by(Background.difficulty, Background.name)
    query = query.offset(skip).limit(limit)
    result = await db.execute(query)
    backgrounds = result.scalars().all()

    return BackgroundListResponse(backgrounds=backgrounds, total=total)


@router.get("/{background_id}", response_model=BackgroundResponse)
async def get_background(background_id: int, db: AsyncSession = Depends(get_db)):
    """Get a single background by ID."""
    query = select(Background).where(Background.id == background_id)
    result = await db.execute(query)
    background = result.scalar_one_or_none()

    if not background:
        raise HTTPException(status_code=404, detail="Background not found")

    return background


@router.post("", response_model=BackgroundResponse, status_code=201)
async def create_background(data: BackgroundCreate, db: AsyncSession = Depends(get_db)):
    """Create a new background."""
    background = Background(
        name=data.name,
        video_file=data.video_file,
        difficulty=data.difficulty,
    )

    db.add(background)
    await db.commit()
    await db.refresh(background)

    return background


@router.put("/{background_id}", response_model=BackgroundResponse)
async def update_background(
    background_id: int,
    data: BackgroundUpdate,
    db: AsyncSession = Depends(get_db),
):
    """Update a background."""
    query = select(Background).where(Background.id == background_id)
    result = await db.execute(query)
    background = result.scalar_one_or_none()

    if not background:
        raise HTTPException(status_code=404, detail="Background not found")

    # Update fields
    if data.name is not None:
        background.name = data.name
    if data.video_file is not None:
        background.video_file = data.video_file
    if data.difficulty is not None:
        background.difficulty = data.difficulty

    await db.commit()
    await db.refresh(background)

    return background


@router.delete("/{background_id}", status_code=204)
async def delete_background(background_id: int, db: AsyncSession = Depends(get_db)):
    """Delete a background."""
    query = select(Background).where(Background.id == background_id)
    result = await db.execute(query)
    background = result.scalar_one_or_none()

    if not background:
        raise HTTPException(status_code=404, detail="Background not found")

    await db.delete(background)
    await db.commit()


@router.get("/by-difficulty/{difficulty}", response_model=BackgroundListResponse)
async def get_backgrounds_by_difficulty(
    difficulty: Difficulty,
    db: AsyncSession = Depends(get_db),
):
    """Get all backgrounds for a specific difficulty."""
    query = select(Background).where(Background.difficulty == difficulty)
    query = query.order_by(Background.name)
    result = await db.execute(query)
    backgrounds = result.scalars().all()

    return BackgroundListResponse(backgrounds=backgrounds, total=len(backgrounds))
