"""
Show Discovery API - smart routing for finding shows.
"""
from datetime import date, timedelta
from typing import List, Optional
from fastapi import APIRouter, Depends, Query
from sqlmodel import Session, select, desc
from pydantic import BaseModel
from database import get_session
from models import Show, Venue, Vertical, Tour

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


class DiscoverShow(BaseModel):
    id: int
    date: str
    slug: str | None
    venue_name: str | None
    venue_city: str | None
    vertical_name: str
    vertical_slug: str
    tour_name: str | None = None


class DiscoverResponse(BaseModel):
    shows: List[DiscoverShow]
    total: int
    filters_applied: dict


@router.get("/shows", response_model=DiscoverResponse)
def discover_shows(
    vertical: Optional[str] = None,
    year: Optional[int] = None,
    month: Optional[int] = None,
    venue: Optional[str] = None,
    tour: Optional[str] = None,
    city: Optional[str] = None,
    state: Optional[str] = None,
    limit: int = 50,
    offset: int = 0,
    sort: str = "date_desc",
    session: Session = Depends(get_session)
):
    """
    Discover shows with smart filtering.
    
    Sort options: date_desc, date_asc
    """
    query = select(Show).where(Show.date.isnot(None))
    
    filters = {}
    
    # Filter by vertical (band)
    if vertical:
        v = session.exec(select(Vertical).where(Vertical.slug == vertical)).first()
        if v:
            query = query.where(Show.vertical_id == v.id)
            filters["vertical"] = vertical
    
    # Filter by year
    if year:
        start = date(year, 1, 1)
        end = date(year, 12, 31)
        query = query.where(Show.date >= start).where(Show.date <= end)
        filters["year"] = year
    
    # Filter by month (requires year)
    if month and year:
        start = date(year, month, 1)
        if month == 12:
            end = date(year + 1, 1, 1) - timedelta(days=1)
        else:
            end = date(year, month + 1, 1) - timedelta(days=1)
        query = query.where(Show.date >= start).where(Show.date <= end)
        filters["month"] = month
    
    # Filter by tour
    if tour:
        t = session.exec(select(Tour).where(Tour.slug == tour)).first()
        if t:
            query = query.where(Show.tour_id == t.id)
            filters["tour"] = tour
    
    # Apply sorting
    if sort == "date_asc":
        query = query.order_by(Show.date)
    else:
        query = query.order_by(desc(Show.date))
    
    # Get total count before pagination
    all_shows = session.exec(query).all()
    total = len(all_shows)
    
    # Apply pagination
    paginated = all_shows[offset:offset + limit]
    
    # Filter by venue/city/state in Python (more flexible)
    results = []
    for show in paginated:
        venue_obj = session.get(Venue, show.venue_id) if show.venue_id else None
        vert_obj = session.get(Vertical, show.vertical_id)
        tour_obj = session.get(Tour, show.tour_id) if show.tour_id else None
        
        # City/state filters
        if city and venue_obj and city.lower() not in venue_obj.city.lower():
            continue
        if state and venue_obj and venue_obj.state and state.lower() not in venue_obj.state.lower():
            continue
        if venue and venue_obj and venue.lower() not in venue_obj.name.lower():
            continue
        
        results.append(DiscoverShow(
            id=show.id,
            date=show.date.strftime("%Y-%m-%d") if show.date else "",
            slug=show.slug,
            venue_name=venue_obj.name if venue_obj else None,
            venue_city=venue_obj.city if venue_obj else None,
            vertical_name=vert_obj.name if vert_obj else "Unknown",
            vertical_slug=vert_obj.slug if vert_obj else "unknown",
            tour_name=tour_obj.name if tour_obj else None
        ))
    
    if city:
        filters["city"] = city
    if state:
        filters["state"] = state
    if venue:
        filters["venue"] = venue
    
    return DiscoverResponse(
        shows=results,
        total=total,
        filters_applied=filters
    )


@router.get("/years")
def get_available_years(
    vertical: Optional[str] = None,
    session: Session = Depends(get_session)
):
    """Get list of years with shows for filtering UI"""
    query = select(Show).where(Show.date.isnot(None))
    
    if vertical:
        v = session.exec(select(Vertical).where(Vertical.slug == vertical)).first()
        if v:
            query = query.where(Show.vertical_id == v.id)
    
    shows = session.exec(query).all()
    years = sorted(set(s.date.year for s in shows if s.date), reverse=True)
    
    return {"years": years}


@router.get("/recent", response_model=List[DiscoverShow])
def get_recent_shows(
    limit: int = 10,
    vertical: Optional[str] = None,
    session: Session = Depends(get_session)
):
    """Get most recent shows for quick discovery"""
    query = select(Show).where(Show.date.isnot(None))
    
    if vertical:
        v = session.exec(select(Vertical).where(Vertical.slug == vertical)).first()
        if v:
            query = query.where(Show.vertical_id == v.id)
    
    query = query.order_by(desc(Show.date)).limit(limit)
    shows = session.exec(query).all()
    
    results = []
    for show in shows:
        venue = session.get(Venue, show.venue_id) if show.venue_id else None
        vert = session.get(Vertical, show.vertical_id)
        
        results.append(DiscoverShow(
            id=show.id,
            date=show.date.strftime("%Y-%m-%d") if show.date else "",
            slug=show.slug,
            venue_name=venue.name if venue else None,
            venue_city=venue.city if venue else None,
            vertical_name=vert.name if vert else "Unknown",
            vertical_slug=vert.slug if vert else "unknown"
        ))
    
    return results
