"""
Musicians Router - API endpoints for managing musicians and band memberships.
"""
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 Musician, BandMembership, PerformanceGuest, Artist, Performance
from slugify import generate_slug as slugify

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

# --- Schemas ---
class MusicianRead(BaseModel):
    id: int
    name: str
    slug: str
    bio: Optional[str] = None
    image_url: Optional[str] = None
    primary_instrument: Optional[str] = None

class MusicianCreate(BaseModel):
    name: str
    bio: Optional[str] = None
    image_url: Optional[str] = None
    primary_instrument: Optional[str] = None

class BandMembershipRead(BaseModel):
    id: int
    musician_id: int
    artist_id: int
    artist_name: Optional[str] = None
    role: Optional[str] = None
    start_date: Optional[str] = None
    end_date: Optional[str] = None

class GuestAppearanceRead(BaseModel):
    id: int
    performance_id: int
    song_title: Optional[str] = None
    show_date: Optional[str] = None
    instrument: Optional[str] = None

# --- Public Endpoints ---

@router.get("", response_model=List[MusicianRead])
def list_musicians(
    search: Optional[str] = None,
    limit: int = 50,
    session: Session = Depends(get_session)
):
    """List all musicians"""
    query = select(Musician)
    if search:
        query = query.where(Musician.name.icontains(search))
    query = query.order_by(Musician.name).limit(limit)
    return session.exec(query).all()

@router.get("/{slug}")
def get_musician(slug: str, session: Session = Depends(get_session)):
    """Get musician details with band memberships and guest appearances"""
    from models import Show, Song, Vertical
    
    musician = session.exec(select(Musician).where(Musician.slug == slug)).first()
    if not musician:
        raise HTTPException(status_code=404, detail="Musician not found")
    
    # Get band memberships
    memberships = session.exec(
        select(BandMembership).where(BandMembership.musician_id == musician.id)
    ).all()
    
    bands = []
    primary_band_ids = set()
    for m in memberships:
        artist = session.get(Artist, m.artist_id)
        primary_band_ids.add(m.artist_id)
        bands.append({
            "id": m.id,
            "artist_id": m.artist_id,
            "artist_name": artist.name if artist else None,
            "artist_slug": artist.slug if artist else None,
            "role": m.role,
            "start_date": str(m.start_date) if m.start_date else None,
            "end_date": str(m.end_date) if m.end_date else None,
            "is_current": m.end_date is None,
        })
    
    # Get guest appearances with full context
    appearances = session.exec(
        select(PerformanceGuest).where(PerformanceGuest.musician_id == musician.id)
    ).all()
    
    guests = []
    sit_in_verticals = {}  # Track which bands they've sat in with
    
    for g in appearances:
        perf = session.get(Performance, g.performance_id)
        if not perf:
            continue
            
        show = session.get(Show, perf.show_id) if perf else None
        song = session.get(Song, perf.song_id) if perf else None
        vertical = session.get(Vertical, show.vertical_id) if show else None
        
        if vertical:
            if vertical.id not in sit_in_verticals:
                sit_in_verticals[vertical.id] = {
                    "vertical_id": vertical.id,
                    "vertical_name": vertical.name,
                    "vertical_slug": vertical.slug,
                    "count": 0
                }
            sit_in_verticals[vertical.id]["count"] += 1
        
        guests.append({
            "id": g.id,
            "performance_id": g.performance_id,
            "performance_slug": perf.slug if perf else None,
            "song_title": song.title if song else None,
            "show_date": str(show.date.date()) if show and show.date else None,
            "vertical_name": vertical.name if vertical else None,
            "vertical_slug": vertical.slug if vertical else None,
            "instrument": g.instrument,
        })
    
    return {
        "musician": {
            "id": musician.id,
            "name": musician.name,
            "slug": musician.slug,
            "bio": musician.bio,
            "image_url": musician.image_url,
            "primary_instrument": musician.primary_instrument,
        },
        "bands": bands,
        "guest_appearances": guests,
        "sit_in_summary": list(sit_in_verticals.values()),
        "stats": {
            "total_bands": len(bands),
            "current_bands": len([b for b in bands if b.get("is_current")]),
            "total_sit_ins": len(guests),
            "bands_sat_in_with": len(sit_in_verticals),
        }
    }

# --- Admin Endpoints (for now, no auth check - can be added later) ---

@router.post("", response_model=MusicianRead)
def create_musician(
    musician_data: MusicianCreate,
    session: Session = Depends(get_session)
):
    """Create a new musician"""
    slug = slugify(musician_data.name)
    
    # Check for existing
    existing = session.exec(select(Musician).where(Musician.slug == slug)).first()
    if existing:
        raise HTTPException(status_code=400, detail="Musician with this name already exists")
    
    musician = Musician(
        name=musician_data.name,
        slug=slug,
        bio=musician_data.bio,
        image_url=musician_data.image_url,
        primary_instrument=musician_data.primary_instrument,
    )
    session.add(musician)
    session.commit()
    session.refresh(musician)
    return musician
