"""Deck management router endpoints."""
from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select, delete, update
from typing import Optional, List

from app.core.database import get_db
from app.core.security import get_current_user
from app.models.models import DecklistFile, DecklistFolder
from app.schemas.schemas import DeckCreate, DeckUpdate, DeckResponse, FolderCreate, FolderResponse

router = APIRouter()


@router.get("/", response_model=List[DeckResponse])
async def list_decks(
    folder_id: Optional[int] = None,
    page: int = 1,
    page_size: int = 50,
    db: AsyncSession = Depends(get_db),
    current_user: dict = Depends(get_current_user),
):
    """List decks for current user."""
    user_id = int(current_user["user_id"])
    
    if folder_id:
        stmt = (
            select(DecklistFile)
            .where(
                DecklistFile.owner_id == user_id,
                DecklistFile.folder_id == folder_id,
            )
            .offset((page - 1) * page_size)
            .limit(page_size)
        )
    else:
        stmt = (
            select(DecklistFile)
            .where(DecklistFile.owner_id == user_id)
            .offset((page - 1) * page_size)
            .limit(page_size)
        )
    
    result = await db.execute(stmt)
    decks = result.scalars().all()
    
    return [DeckResponse.model_validate(deck) for deck in decks]


@router.post("/", response_model=DeckResponse)
async def create_deck(
    request: DeckCreate,
    db: AsyncSession = Depends(get_db),
    current_user: dict = Depends(get_current_user),
):
    """Create a new deck."""
    user_id = int(current_user["user_id"])
    
    # Verify folder exists if specified
    if request.folder_id:
        stmt = select(DecklistFolder).where(
            DecklistFolder.id == request.folder_id,
            DecklistFolder.owner_id == user_id,
        )
        result = await db.execute(stmt)
        folder = result.scalar_one_or_none()
        if not folder:
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail="Folder not found",
            )
    
    new_deck = DecklistFile(
        owner_id=user_id,
        folder_id=request.folder_id,
        name=request.name,
        content=request.content,
        format=request.format,
    )
    db.add(new_deck)
    await db.flush()
    
    return DeckResponse.model_validate(new_deck)


@router.get("/folders", response_model=List[FolderResponse])
async def list_folders(
    parent_id: Optional[int] = None,
    db: AsyncSession = Depends(get_db),
    current_user: dict = Depends(get_current_user),
):
    """List folders for current user."""
    user_id = int(current_user["user_id"])
    
    if parent_id:
        stmt = select(DecklistFolder).where(
            DecklistFolder.parent_id == parent_id,
            DecklistFolder.owner_id == user_id,
        )
    else:
        stmt = select(DecklistFolder).where(
            DecklistFolder.parent_id == None,  # Top-level folders
            DecklistFolder.owner_id == user_id,
        )
    
    result = await db.execute(stmt)
    folders = result.scalars().all()
    
    return [FolderResponse.model_validate(folder) for folder in folders]


@router.post("/folders", response_model=FolderResponse)
async def create_folder(
    request: FolderCreate,
    db: AsyncSession = Depends(get_db),
    current_user: dict = Depends(get_current_user),
):
    """Create a new folder."""
    user_id = int(current_user["user_id"])
    
    # Verify parent folder exists if specified
    if request.parent_id:
        stmt = select(DecklistFolder).where(
            DecklistFolder.id == request.parent_id,
            DecklistFolder.owner_id == user_id,
        )
        result = await db.execute(stmt)
        parent_folder = result.scalar_one_or_none()
        if not parent_folder:
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail="Parent folder not found",
            )
    
    new_folder = DecklistFolder(
        owner_id=user_id,
        name=request.name,
        parent_id=request.parent_id,
    )
    db.add(new_folder)
    await db.flush()
    
    return FolderResponse.model_validate(new_folder)


@router.delete("/folders/{folder_id}")
async def delete_folder(
    folder_id: int,
    db: AsyncSession = Depends(get_db),
    current_user: dict = Depends(get_current_user),
):
    """Delete folder and all its contents."""
    user_id = int(current_user["user_id"])
    
    stmt = select(DecklistFolder).where(
        DecklistFolder.id == folder_id,
        DecklistFolder.owner_id == user_id,
    )
    result = await db.execute(stmt)
    folder = result.scalar_one_or_none()
    
    if not folder:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="Folder not found",
        )
    
    # Delete folder and all decks (cascading delete)
    await db.execute(delete(DecklistFolder).where(DecklistFolder.id == folder_id))
    
    return {"message": "Folder deleted successfully"}


@router.get("/{deck_id}", response_model=DeckResponse)
async def get_deck(
    deck_id: int,
    db: AsyncSession = Depends(get_db),
    current_user: dict = Depends(get_current_user),
):
    """Get deck by ID."""
    user_id = int(current_user["user_id"])
    
    stmt = select(DecklistFile).where(
        DecklistFile.id == deck_id,
        DecklistFile.owner_id == user_id,
    )
    result = await db.execute(stmt)
    deck = result.scalar_one_or_none()
    
    if not deck:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="Deck not found",
        )
    
    return DeckResponse.model_validate(deck)


@router.patch("/{deck_id}", response_model=DeckResponse)
async def update_deck(
    deck_id: int,
    request: DeckUpdate,
    db: AsyncSession = Depends(get_db),
    current_user: dict = Depends(get_current_user),
):
    """Update deck."""
    user_id = int(current_user["user_id"])
    
    stmt = select(DecklistFile).where(
        DecklistFile.id == deck_id,
        DecklistFile.owner_id == user_id,
    )
    result = await db.execute(stmt)
    deck = result.scalar_one_or_none()
    
    if not deck:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="Deck not found",
        )
    
    # Update fields
    update_data = request.model_dump(exclude_unset=True)
    
    stmt = (
        update(DecklistFile)
        .where(DecklistFile.id == deck_id)
        .values(**update_data)
    )
    await db.execute(stmt)
    await db.flush()
    
    # Fetch updated deck
    stmt = select(DecklistFile).where(DecklistFile.id == deck_id)
    result = await db.execute(stmt)
    updated_deck = result.scalar_one_or_none()
    
    return DeckResponse.model_validate(updated_deck)


@router.delete("/{deck_id}")
async def delete_deck(
    deck_id: int,
    db: AsyncSession = Depends(get_db),
    current_user: dict = Depends(get_current_user),
):
    """Delete deck."""
    user_id = int(current_user["user_id"])
    
    stmt = select(DecklistFile).where(
        DecklistFile.id == deck_id,
        DecklistFile.owner_id == user_id,
    )
    result = await db.execute(stmt)
    deck = result.scalar_one_or_none()
    
    if not deck:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="Deck not found",
        )
    
    await db.execute(delete(DecklistFile).where(DecklistFile.id == deck_id))
    
    return {"message": "Deck deleted successfully"}
