from typing import List, Optional
from fastapi import APIRouter, Depends, HTTPException, Query
from sqlmodel import Session, select, col
from sqlalchemy.orm import selectinload
from database import get_session
from models import Show, Song, Venue, Tour, Group, Performance, PerformanceNickname, Comment, Review, Vertical

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

@router.get("/")
def global_search(
    q: str, 
    session: Session = Depends(get_session),
    limit: int = 5
):
    if len(q) < 2:
        return {}
        
    q_str = f"%{q}%"
    
    # Search Songs
    songs = session.exec(
        select(Song)
        .where(col(Song.title).ilike(q_str))
        .limit(limit)
    ).all()
    
    # Search Venues
    venues = session.exec(
        select(Venue)
        .where(col(Venue.name).ilike(q_str))
        .limit(limit)
    ).all()
    
    # Search Tours
    tours = session.exec(
        select(Tour)
        .where(col(Tour.name).ilike(q_str))
        .limit(limit)
    ).all()
    
    # Search Groups
    groups = session.exec(
        select(Group)
        .where(col(Group.name).ilike(q_str))
        .limit(limit)
    ).all()

    # Search Verticals (Bands)
    verticals = session.exec(
        select(Vertical)
        .where(col(Vertical.name).ilike(q_str))
        .limit(limit)
    ).all()
    
    # Search Nicknames
    nicknames_raw = session.exec(
        select(PerformanceNickname)
        .options(
            selectinload(PerformanceNickname.performance)
            .selectinload(Performance.song),
            selectinload(PerformanceNickname.performance)
            .selectinload(Performance.show)
        )
        .where(col(PerformanceNickname.nickname).ilike(q_str))
        .where(PerformanceNickname.status == "approved")
        .limit(limit)
    ).all()
    
    # Serialize nicknames with nested data
    nicknames = []
    for n in nicknames_raw:
        nicknames.append({
            "id": n.id,
            "nickname": n.nickname,
            "description": n.description,
            "performance": {
                "id": n.performance.id if n.performance else None,
                "song": {"id": n.performance.song.id, "title": n.performance.song.title} if n.performance and n.performance.song else None,
                "show": {"slug": n.performance.show.slug, "date": str(n.performance.show.date.date()) if n.performance.show else None} if n.performance and n.performance.show else None
            } if n.performance else None
        })
    
    # Search Performances by notes
    performances_raw = session.exec(
        select(Performance)
        .options(selectinload(Performance.song), selectinload(Performance.show))
        .where(col(Performance.notes).ilike(q_str))
        .limit(limit)
    ).all()
    
    # Serialize performances with nested song/show data
    performances = []
    for p in performances_raw:
        performances.append({
            "id": p.id,
            "slug": p.slug,
            "notes": p.notes,
            "song": {"id": p.song.id, "title": p.song.title, "slug": p.song.slug} if p.song else None,
            "show": {"slug": p.show.slug, "date": str(p.show.date.date()) if p.show else None} if p.show else None
        })

    # Search Reviews
    reviews = session.exec(
        select(Review)
        .where(
            (col(Review.blurb).ilike(q_str)) | 
            (col(Review.content).ilike(q_str))
        )
        .limit(limit)
    ).all()

    # Search Comments
    comments = session.exec(
        select(Comment)
        .where(col(Comment.content).ilike(q_str))
        .limit(limit)
    ).all()
    
    return {
        "songs": songs,
        "venues": venues,
        "tours": tours,
        "groups": groups,
        "verticals": verticals,
        "nicknames": nicknames,
        "performances": performances,
        "reviews": reviews,
        "comments": comments
    }
