"""
Festival API endpoints for multi-band festival discovery.
"""
from typing import List, Optional
from fastapi import APIRouter, Depends, HTTPException, Query
from sqlmodel import Session, select
from pydantic import BaseModel
from database import get_session
from models import Festival, ShowFestival, Show, Vertical, Venue

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


class FestivalRead(BaseModel):
    id: int
    name: str
    slug: str
    year: Optional[int]
    start_date: Optional[str]
    end_date: Optional[str]
    website_url: Optional[str]
    description: Optional[str]


class FestivalShowRead(BaseModel):
    show_id: int
    show_slug: Optional[str]
    show_date: str
    vertical_name: str
    vertical_slug: str
    stage: Optional[str]
    set_time: Optional[str]


class FestivalDetailRead(BaseModel):
    festival: FestivalRead
    shows: List[FestivalShowRead]
    bands_count: int


@router.get("/", response_model=List[FestivalRead])
def list_festivals(
    year: Optional[int] = None,
    limit: int = Query(default=50, le=100),
    offset: int = 0,
    session: Session = Depends(get_session)
):
    """List all festivals, optionally filtered by year"""
    query = select(Festival)
    if year:
        query = query.where(Festival.year == year)
    query = query.order_by(Festival.year.desc(), Festival.name).offset(offset).limit(limit)
    
    festivals = session.exec(query).all()
    return [
        FestivalRead(
            id=f.id,
            name=f.name,
            slug=f.slug,
            year=f.year,
            start_date=f.start_date.strftime("%Y-%m-%d") if f.start_date else None,
            end_date=f.end_date.strftime("%Y-%m-%d") if f.end_date else None,
            website_url=f.website_url,
            description=f.description
        )
        for f in festivals
    ]


@router.get("/{slug}", response_model=FestivalDetailRead)
def get_festival(slug: str, session: Session = Depends(get_session)):
    """Get festival details with all shows across bands"""
    festival = session.exec(
        select(Festival).where(Festival.slug == slug)
    ).first()
    
    if not festival:
        raise HTTPException(status_code=404, detail="Festival not found")
    
    # Get all shows at this festival
    show_festivals = session.exec(
        select(ShowFestival).where(ShowFestival.festival_id == festival.id)
    ).all()
    
    shows = []
    bands_seen = set()
    for sf in show_festivals:
        show = session.get(Show, sf.show_id)
        if show:
            vertical = session.get(Vertical, show.vertical_id)
            if vertical:
                bands_seen.add(vertical.id)
            shows.append(FestivalShowRead(
                show_id=show.id,
                show_slug=show.slug,
                show_date=show.date.strftime("%Y-%m-%d") if show.date else "Unknown",
                vertical_name=vertical.name if vertical else "Unknown",
                vertical_slug=vertical.slug if vertical else "unknown",
                stage=sf.stage,
                set_time=sf.set_time
            ))
    
    # Sort by date
    shows.sort(key=lambda x: x.show_date)
    
    return FestivalDetailRead(
        festival=FestivalRead(
            id=festival.id,
            name=festival.name,
            slug=festival.slug,
            year=festival.year,
            start_date=festival.start_date.strftime("%Y-%m-%d") if festival.start_date else None,
            end_date=festival.end_date.strftime("%Y-%m-%d") if festival.end_date else None,
            website_url=festival.website_url,
            description=festival.description
        ),
        shows=shows,
        bands_count=len(bands_seen)
    )


@router.get("/by-band/{vertical_slug}")
def get_festivals_by_band(vertical_slug: str, session: Session = Depends(get_session)):
    """Get all festivals a band has played"""
    vertical = session.exec(
        select(Vertical).where(Vertical.slug == vertical_slug)
    ).first()
    
    if not vertical:
        raise HTTPException(status_code=404, detail="Band not found")
    
    # Get shows for this vertical that are linked to festivals
    shows = session.exec(
        select(Show).where(Show.vertical_id == vertical.id)
    ).all()
    
    show_ids = [s.id for s in shows]
    
    if not show_ids:
        return []
    
    # Get festival links
    show_festivals = session.exec(
        select(ShowFestival).where(ShowFestival.show_id.in_(show_ids))
    ).all()
    
    festival_ids = list(set(sf.festival_id for sf in show_festivals))
    
    if not festival_ids:
        return []
    
    festivals = session.exec(
        select(Festival).where(Festival.id.in_(festival_ids))
    ).all()
    
    return [
        FestivalRead(
            id=f.id,
            name=f.name,
            slug=f.slug,
            year=f.year,
            start_date=f.start_date.strftime("%Y-%m-%d") if f.start_date else None,
            end_date=f.end_date.strftime("%Y-%m-%d") if f.end_date else None,
            website_url=f.website_url,
            description=f.description
        )
        for f in sorted(festivals, key=lambda x: x.year or 0, reverse=True)
    ]
