"""
Card search router for MTG card database.

Provides endpoints for searching and retrieving MTG card data
from the MTG PostgreSQL database with Redis caching.
"""
from fastapi import APIRouter, Depends, HTTPException, Query
from sqlalchemy.ext.asyncio import AsyncSession

from app.core.database import mtg_get_db
from app.core.redis_client import cache_get, cache_set
from app.services.card_database import (
    search_cards,
    get_card_by_name,
    get_cards_by_set,
    get_card_types,
    get_card_rarities,
    get_sets,
    get_set_by_code,
    get_card_statistics,
)

router = APIRouter(prefix="/mtg/cards", tags=["MTG Cards"])


@router.get("/search")
async def search_cards_endpoint(
    q: str = Query(..., min_length=1, description="Search query"),
    limit: int = Query(100, ge=1, le=500, description="Maximum results"),
    offset: int = Query(0, ge=0, description="Number of results to skip"),
    db: AsyncSession = Depends(mtg_get_db),
):
    """
    Search cards by name, type, or mana cost.
    
    Uses Redis cache to improve performance for repeated searches.
    """
    cache_key = f"card_search:{q}:{limit}:{offset}"
    
    # Check cache first
    cached = await cache_get(cache_key)
    if cached:
        return {"cached": True, "results": cached}
    
    # Query database
    results = await search_cards(q, db, limit, offset)
    
    # Cache results for 5 minutes
    await cache_set(cache_key, str(results), ttl=300)
    
    return {"cached": False, "results": results}


@router.get("/sets")
async def get_sets_endpoint(
    db: AsyncSession = Depends(mtg_get_db),
):
    """
    Get all sets.
    """
    cache_key = "all_sets:all"
    
    cached = await cache_get(cache_key)
    if cached:
        return {"cached": True, "results": cached}
    
    sets = await get_sets(db)
    
    # Cache for 1 hour
    await cache_set(cache_key, str(sets), ttl=3600)
    
    return {"cached": False, "results": sets}


@router.get("/sets/{set_code}")
async def get_set_endpoint(
    set_code: str,
    db: AsyncSession = Depends(mtg_get_db),
):
    """
    Get a specific set by code.
    """
    cache_key = f"set_by_code:{set_code}"
    
    cached = await cache_get(cache_key)
    if cached:
        return {"cached": True, "results": cached}
    
    mtg_set = await get_set_by_code(set_code, db)
    
    if not mtg_set:
        raise HTTPException(status_code=404, detail="Set not found")
    
    # Cache for 1 hour
    await cache_set(cache_key, str(mtg_set), ttl=3600)
    
    return {"cached": False, "results": mtg_set}


@router.get("/{card_name}")
async def get_card_endpoint(
    card_name: str,
    set_code: str | None = Query(None, description="Filter by set code"),
    db: AsyncSession = Depends(mtg_get_db),
):
    """
    Get a specific card by name.
    
    Optional set_code filter to get a specific printing.
    """
    cache_key = f"card_by_name:{card_name}:{set_code or 'all'}"
    
    cached = await cache_get(cache_key)
    if cached:
        return {"cached": True, "results": cached}
    
    card = await get_card_by_name(card_name, db, set_code)
    
    if not card:
        raise HTTPException(status_code=404, detail="Card not found")
    
    # Cache for 10 minutes
    await cache_set(cache_key, str(card), ttl=600)
    
    return {"cached": False, "results": card}


@router.get("/set/{set_code}")
async def get_cards_by_set_endpoint(
    set_code: str,
    limit: int = Query(1000, ge=1, le=5000, description="Maximum results"),
    offset: int = Query(0, ge=0, description="Number of results to skip"),
    db: AsyncSession = Depends(mtg_get_db),
):
    """
    Get all cards in a specific set.
    """
    cache_key = f"set_cards:{set_code}:{limit}:{offset}"
    
    cached = await cache_get(cache_key)
    if cached:
        return {"cached": True, "results": cached}
    
    results = await get_cards_by_set(set_code, db, limit, offset)
    
    # Cache for 15 minutes
    await cache_set(cache_key, str(results), ttl=900)
    
    return {"cached": False, "results": results}


@router.get("/types")
async def get_card_types_endpoint(
    db: AsyncSession = Depends(mtg_get_db),
):
    """
    Get all unique card types.
    """
    cache_key = "card_types:all"
    
    cached = await cache_get(cache_key)
    if cached:
        return {"cached": True, "results": cached}
    
    types = await get_card_types(db)
    
    # Cache for 30 minutes
    await cache_set(cache_key, str(types), ttl=1800)
    
    return {"cached": False, "results": types}


@router.get("/rarities")
async def get_card_rarities_endpoint(
    db: AsyncSession = Depends(mtg_get_db),
):
    """
    Get all unique card rarities.
    """
    cache_key = "card_rarities:all"
    
    cached = await cache_get(cache_key)
    if cached:
        return {"cached": True, "results": cached}
    
    rarities = await get_card_rarities(db)
    
    # Cache for 30 minutes
    await cache_set(cache_key, str(rarities), ttl=1800)
    
    return {"cached": False, "results": rarities}


@router.get("/sets")
async def get_sets_endpoint(
    db: AsyncSession = Depends(mtg_get_db),
):
    """
    Get all sets.
    """
    cache_key = "all_sets:all"
    
    cached = await cache_get(cache_key)
    if cached:
        return {"cached": True, "results": cached}
    
    sets = await get_sets(db)
    
    # Cache for 1 hour
    await cache_set(cache_key, str(sets), ttl=3600)
    
    return {"cached": False, "results": sets}


@router.get("/sets/{set_code}")
async def get_set_endpoint(
    set_code: str,
    db: AsyncSession = Depends(mtg_get_db),
):
    """
    Get a specific set by code.
    """
    cache_key = f"set_by_code:{set_code}"
    
    cached = await cache_get(cache_key)
    if cached:
        return {"cached": True, "results": cached}
    
    mtg_set = await get_set_by_code(set_code, db)
    
    if not mtg_set:
        raise HTTPException(status_code=404, detail="Set not found")
    
    # Cache for 1 hour
    await cache_set(cache_key, str(mtg_set), ttl=3600)
    
    return {"cached": False, "results": mtg_set}


@router.get("/statistics")
async def get_card_statistics_endpoint(
    db: AsyncSession = Depends(mtg_get_db),
):
    """
    Get overall card database statistics.
    """
    cache_key = "card_statistics:all"
    
    cached = await cache_get(cache_key)
    if cached:
        return {"cached": True, "results": cached}
    
    stats = await get_card_statistics(db)
    
    # Cache for 1 hour
    await cache_set(cache_key, str(stats), ttl=3600)
    
    return {"cached": False, "results": stats}
