"""
Sequences Router - API endpoints for managing song sequences.
"""
from typing import List, Optional
from fastapi import APIRouter, Depends, HTTPException
from sqlmodel import Session, select
from pydantic import BaseModel
from database import get_session
from models import Sequence, SequenceSong, Song
from slugify import generate_slug as slugify
from auth import get_current_user
from models import User

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

# --- Schemas ---
class SequenceRead(BaseModel):
    id: int
    name: str
    slug: str
    description: Optional[str] = None
    notes: Optional[str] = None
    songs: List[dict] = []  # [{position, song_id, song_title}]

class SequenceCreate(BaseModel):
    name: str
    description: Optional[str] = None
    notes: Optional[str] = None
    song_ids: List[int] = []  # Ordered list of song IDs

class SequenceUpdate(BaseModel):
    name: Optional[str] = None
    description: Optional[str] = None
    notes: Optional[str] = None
    song_ids: Optional[List[int]] = None

# --- Public Endpoints ---

@router.get("", response_model=List[SequenceRead])
def list_sequences(
    search: Optional[str] = None,
    limit: int = 100,
    session: Session = Depends(get_session)
):
    """List all sequences"""
    query = select(Sequence)
    if search:
        query = query.where(Sequence.name.icontains(search))
    query = query.order_by(Sequence.name).limit(limit)
    sequences = session.exec(query).all()
    
    result = []
    for seq in sequences:
        # Get songs for this sequence
        songs_query = select(SequenceSong).where(SequenceSong.sequence_id == seq.id).order_by(SequenceSong.position)
        seq_songs = session.exec(songs_query).all()
        
        song_list = []
        for ss in seq_songs:
            song = session.get(Song, ss.song_id)
            song_list.append({
                "position": ss.position,
                "song_id": ss.song_id,
                "song_title": song.title if song else "Unknown"
            })
        
        result.append({
            "id": seq.id,
            "name": seq.name,
            "slug": seq.slug,
            "description": seq.description,
            "notes": seq.notes,
            "songs": song_list
        })
    
    return result

@router.get("/{slug}")
def get_sequence(slug: str, session: Session = Depends(get_session)):
    """Get sequence details with songs"""
    sequence = session.exec(select(Sequence).where(Sequence.slug == slug)).first()
    if not sequence:
        raise HTTPException(status_code=404, detail="Sequence not found")
    
    # Get songs
    songs_query = select(SequenceSong).where(SequenceSong.sequence_id == sequence.id).order_by(SequenceSong.position)
    seq_songs = session.exec(songs_query).all()
    
    song_list = []
    for ss in seq_songs:
        song = session.get(Song, ss.song_id)
        song_list.append({
            "position": ss.position,
            "song_id": ss.song_id,
            "song_title": song.title if song else "Unknown",
            "song_slug": song.slug if song else None
        })
    
    return {
        "id": sequence.id,
        "name": sequence.name,
        "slug": sequence.slug,
        "description": sequence.description,
        "notes": sequence.notes,
        "songs": song_list
    }

# --- Admin Endpoints ---

@router.post("", response_model=SequenceRead)
def create_sequence(
    data: SequenceCreate,
    session: Session = Depends(get_session),
    user: User = Depends(get_current_user)
):
    """Create a new sequence"""
    if user.role != "admin":
        raise HTTPException(status_code=403, detail="Admin access required")
    
    slug = slugify(data.name)
    
    # Check for existing
    existing = session.exec(select(Sequence).where(Sequence.slug == slug)).first()
    if existing:
        raise HTTPException(status_code=400, detail="Sequence with this name already exists")
    
    sequence = Sequence(
        name=data.name,
        slug=slug,
        description=data.description,
        notes=data.notes
    )
    session.add(sequence)
    session.commit()
    session.refresh(sequence)
    
    # Add songs
    for i, song_id in enumerate(data.song_ids, start=1):
        ss = SequenceSong(sequence_id=sequence.id, song_id=song_id, position=i)
        session.add(ss)
    session.commit()
    
    return {
        "id": sequence.id,
        "name": sequence.name,
        "slug": sequence.slug,
        "description": sequence.description,
        "notes": sequence.notes,
        "songs": [{"position": i+1, "song_id": sid, "song_title": ""} for i, sid in enumerate(data.song_ids)]
    }

@router.patch("/{sequence_id}")
def update_sequence(
    sequence_id: int,
    data: SequenceUpdate,
    session: Session = Depends(get_session),
    user: User = Depends(get_current_user)
):
    """Update a sequence"""
    if user.role != "admin":
        raise HTTPException(status_code=403, detail="Admin access required")
    
    sequence = session.get(Sequence, sequence_id)
    if not sequence:
        raise HTTPException(status_code=404, detail="Sequence not found")
    
    if data.name is not None:
        sequence.name = data.name
        sequence.slug = slugify(data.name)
    if data.description is not None:
        sequence.description = data.description
    if data.notes is not None:
        sequence.notes = data.notes
    
    session.add(sequence)
    
    # Update songs if provided
    if data.song_ids is not None:
        # Delete existing
        existing = session.exec(select(SequenceSong).where(SequenceSong.sequence_id == sequence_id)).all()
        for e in existing:
            session.delete(e)
        
        # Add new
        for i, song_id in enumerate(data.song_ids, start=1):
            ss = SequenceSong(sequence_id=sequence_id, song_id=song_id, position=i)
            session.add(ss)
    
    session.commit()
    return {"message": "Sequence updated", "id": sequence_id}

@router.delete("/{sequence_id}")
def delete_sequence(
    sequence_id: int,
    session: Session = Depends(get_session),
    user: User = Depends(get_current_user)
):
    """Delete a sequence"""
    if user.role != "admin":
        raise HTTPException(status_code=403, detail="Admin access required")
    
    sequence = session.get(Sequence, sequence_id)
    if not sequence:
        raise HTTPException(status_code=404, detail="Sequence not found")
    
    # Delete songs first
    existing = session.exec(select(SequenceSong).where(SequenceSong.sequence_id == sequence_id)).all()
    for e in existing:
        session.delete(e)
    
    session.delete(sequence)
    session.commit()
    return {"message": "Sequence deleted"}
