from typing import List, Union
from fastapi import APIRouter, Depends, Query
from sqlmodel import Session, select, desc
from database import get_session
from models import Review, Attendance, GroupPost, User, Profile, Performance, Show, Song
from schemas import ReviewRead, AttendanceRead, GroupPostRead
from datetime import datetime
from auth import get_current_user_optional

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

# We need a unified schema for the feed
from pydantic import BaseModel

class FeedItem(BaseModel):
    type: str # review, attendance, post
    timestamp: datetime
    data: Union[ReviewRead, AttendanceRead, GroupPostRead, dict]
    user: dict # Basic user info
    entity: dict | None = None  # Linked entity info

def get_user_display(session: Session, user_id: int) -> dict:
    """Get consistent user display info using Profile username"""
    user = session.get(User, user_id)
    if not user:
        return {"id": 0, "username": "Deleted User", "avatar_bg_color": "#666", "avatar_text": None}
    
    profile = session.exec(
        select(Profile).where(Profile.user_id == user_id)
    ).first()
    
    return {
        "id": user.id,
        "username": profile.username if profile else f"User {user_id}",
        "display_name": profile.display_name if profile else None,
        "avatar_bg_color": user.avatar_bg_color or "#0F4C81",
        "avatar_text": user.avatar_text,
    }

def get_entity_info(session: Session, review: Review) -> dict | None:
    """Get entity link info for a review"""
    if review.performance_id:
        perf = session.get(Performance, review.performance_id)
        if perf:
            song = session.get(Song, perf.song_id)
            show = session.get(Show, perf.show_id)
            return {
                "type": "performance",
                "slug": perf.slug,
                "title": song.title if song else "Unknown Song",
                "date": show.date.isoformat() if show and show.date else None,
            }
    elif review.show_id:
        show = session.get(Show, review.show_id)
        if show:
            return {
                "type": "show",
                "slug": show.slug,
                "title": show.date.strftime("%Y-%m-%d") if show.date else "Unknown Date",
            }
    elif review.song_id:
        song = session.get(Song, review.song_id)
        if song:
            return {
                "type": "song",
                "slug": song.slug,
                "title": song.title,
            }
    return None

@router.get("/", response_model=List[FeedItem])
def get_global_feed(
    limit: int = 20,
    session: Session = Depends(get_session)
):
    # Fetch latest reviews
    reviews = session.exec(
        select(Review).order_by(desc(Review.created_at)).limit(limit)
    ).all()
    
    # Fetch latest attendance
    attendance = session.exec(
        select(Attendance).order_by(desc(Attendance.created_at)).limit(limit)
    ).all()
    
    # Fetch latest group posts
    posts = session.exec(
        select(GroupPost).order_by(desc(GroupPost.created_at)).limit(limit)
    ).all()
    
    feed_items = []
    
    for r in reviews:
        feed_items.append(FeedItem(
            type="review",
            timestamp=r.created_at or datetime.utcnow(),
            data=r,
            user=get_user_display(session, r.user_id),
            entity=get_entity_info(session, r)
        ))
        
    for a in attendance:
        show = session.get(Show, a.show_id) if a.show_id else None
        entity_info = None
        if show:
            entity_info = {
                "type": "show",
                "slug": show.slug,
                "title": show.date.strftime("%Y-%m-%d") if show.date else "Unknown",
            }
        
        feed_items.append(FeedItem(
            type="attendance",
            timestamp=a.created_at,
            data=a,
            user=get_user_display(session, a.user_id),
            entity=entity_info
        ))
        
    for p in posts:
        feed_items.append(FeedItem(
            type="post",
            timestamp=p.created_at,
            data=p,
            user=get_user_display(session, p.user_id),
            entity=None
        ))
        
    # Sort by timestamp desc
    feed_items.sort(key=lambda x: x.timestamp, reverse=True)
    
    return feed_items[:limit]


@router.get("/me", response_model=List[FeedItem])
def get_personalized_feed(
    limit: int = 20,
    session: Session = Depends(get_session),
    current_user: User = Depends(get_current_user_optional)
):
    """Get feed filtered by user's band preferences (or all bands if not logged in)"""
    from models import UserVerticalPreference, Vertical
    
    # Get user's preferred vertical IDs
    preferred_vertical_ids = None
    if current_user:
        prefs = session.exec(
            select(UserVerticalPreference)
            .where(UserVerticalPreference.user_id == current_user.id)
            .where(UserVerticalPreference.display_mode != "hidden")
        ).all()
        if prefs:
            preferred_vertical_ids = [p.vertical_id for p in prefs]
    
    # Fetch reviews (filtered by vertical if user has preferences)
    review_query = select(Review).order_by(desc(Review.created_at)).limit(limit * 2)
    reviews = session.exec(review_query).all()
    
    # Fetch attendance (filtered by show's vertical)
    attendance_query = select(Attendance).order_by(desc(Attendance.created_at)).limit(limit * 2)
    attendance = session.exec(attendance_query).all()
    
    feed_items = []
    
    for r in reviews:
        # Filter by vertical if user has preferences
        vertical_id = None
        if r.performance_id:
            perf = session.get(Performance, r.performance_id)
            if perf:
                show = session.get(Show, perf.show_id)
                if show:
                    vertical_id = show.vertical_id
        elif r.show_id:
            show = session.get(Show, r.show_id)
            if show:
                vertical_id = show.vertical_id
        elif r.song_id:
            song = session.get(Song, r.song_id)
            if song:
                vertical_id = song.vertical_id
        
        if preferred_vertical_ids and vertical_id and vertical_id not in preferred_vertical_ids:
            continue
        
        feed_items.append(FeedItem(
            type="review",
            timestamp=r.created_at or datetime.utcnow(),
            data=r,
            user=get_user_display(session, r.user_id),
            entity=get_entity_info(session, r)
        ))
        
    for a in attendance:
        show = session.get(Show, a.show_id) if a.show_id else None
        
        # Filter by vertical
        if preferred_vertical_ids and show and show.vertical_id not in preferred_vertical_ids:
            continue
        
        entity_info = None
        if show:
            entity_info = {
                "type": "show",
                "slug": show.slug,
                "title": show.date.strftime("%Y-%m-%d") if show.date else "Unknown",
            }
        
        feed_items.append(FeedItem(
            type="attendance",
            timestamp=a.created_at,
            data=a,
            user=get_user_display(session, a.user_id),
            entity=entity_info
        ))
        
    # Sort by timestamp desc
    feed_items.sort(key=lambda x: x.timestamp, reverse=True)
    
    return feed_items[:limit]

