from fastapi import APIRouter, Depends, HTTPException
from sqlmodel import Session, select
from typing import List
from database import get_session
from models import User, Vertical, UserVerticalPreference
from auth import get_current_user
from pydantic import BaseModel
from datetime import datetime

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


class VerticalRead(BaseModel):
    id: int
    name: str
    slug: str
    description: str | None = None


class UserVerticalPreferenceRead(BaseModel):
    vertical_id: int
    vertical: VerticalRead
    display_mode: str
    priority: int
    tier: str = "main_stage"
    notify_on_show: bool


class UserVerticalPreferenceCreate(BaseModel):
    vertical_id: int
    display_mode: str = "primary"  # primary, secondary, attribution_only, hidden
    priority: int = 0
    tier: str = "main_stage"
    notify_on_show: bool = True


class UserVerticalPreferenceUpdate(BaseModel):
    display_mode: str | None = None
    priority: int | None = None
    tier: str | None = None
    notify_on_show: bool | None = None


class BulkVerticalPreferencesCreate(BaseModel):
    """For onboarding - set multiple band preferences at once"""
    vertical_ids: List[int]
    display_mode: str = "primary"


# --- Public endpoints ---

@router.get("/", response_model=List[VerticalRead])
def list_verticals(
    scene: str | None = None,
    session: Session = Depends(get_session)
):
    """List all available verticals (bands), optionally filtered by scene"""
    from models import Scene, VerticalScene
    
    if scene:
        # Filter by scene
        scene_obj = session.exec(select(Scene).where(Scene.slug == scene)).first()
        if not scene_obj:
            raise HTTPException(status_code=404, detail="Scene not found")
        
        vertical_ids = session.exec(
            select(VerticalScene.vertical_id).where(VerticalScene.scene_id == scene_obj.id)
        ).all()
        
        verticals = session.exec(
            select(Vertical)
            .where(Vertical.id.in_(vertical_ids))
            .where(Vertical.is_active == True)
        ).all()
    else:
        verticals = session.exec(
            select(Vertical).where(Vertical.is_active == True)
        ).all()
    
    return verticals


class SceneRead(BaseModel):
    id: int
    name: str
    slug: str
    description: str | None = None


@router.get("/scenes", response_model=List[SceneRead])
def list_scenes(session: Session = Depends(get_session)):
    """List all scenes (genres)"""
    from models import Scene
    scenes = session.exec(select(Scene)).all()
    return scenes


@router.get("/{slug}", response_model=VerticalRead)
def get_vertical(slug: str, session: Session = Depends(get_session)):
    """Get a specific vertical by slug"""
    vertical = session.exec(select(Vertical).where(Vertical.slug == slug)).first()
    if not vertical:
        raise HTTPException(status_code=404, detail="Vertical not found")
    return vertical


# --- User preference endpoints ---

@router.get("/preferences/me", response_model=List[UserVerticalPreferenceRead])
def get_my_vertical_preferences(
    session: Session = Depends(get_session),
    current_user: User = Depends(get_current_user)
):
    """Get current user's band preferences"""
    prefs = session.exec(
        select(UserVerticalPreference)
        .where(UserVerticalPreference.user_id == current_user.id)
        .order_by(UserVerticalPreference.priority)
    ).all()
    
    # Enrich with vertical data
    result = []
    for pref in prefs:
        vertical = session.get(Vertical, pref.vertical_id)
        if vertical:
            result.append({
                "vertical_id": pref.vertical_id,
                "vertical": vertical,
                "display_mode": pref.display_mode,
                "priority": pref.priority,
                "tier": pref.tier,
                "notify_on_show": pref.notify_on_show
            })
    return result


@router.post("/preferences", response_model=UserVerticalPreferenceRead)
def add_vertical_preference(
    pref: UserVerticalPreferenceCreate,
    session: Session = Depends(get_session),
    current_user: User = Depends(get_current_user)
):
    """Add a band to user's preferences"""
    # Check vertical exists
    vertical = session.get(Vertical, pref.vertical_id)
    if not vertical:
        raise HTTPException(status_code=404, detail="Vertical not found")
    
    # Check if already exists
    existing = session.exec(
        select(UserVerticalPreference)
        .where(UserVerticalPreference.user_id == current_user.id)
        .where(UserVerticalPreference.vertical_id == pref.vertical_id)
    ).first()
    
    if existing:
        raise HTTPException(status_code=400, detail="Preference already exists")
    
    db_pref = UserVerticalPreference(
        user_id=current_user.id,
        vertical_id=pref.vertical_id,
        display_mode=pref.display_mode,
        priority=pref.priority,
        tier=pref.tier,
        notify_on_show=pref.notify_on_show
    )
    session.add(db_pref)
    session.commit()
    session.refresh(db_pref)
    
    return {
        "vertical_id": db_pref.vertical_id,
        "vertical": vertical,
        "display_mode": db_pref.display_mode,
        "priority": db_pref.priority,
        "tier": db_pref.tier,
        "notify_on_show": db_pref.notify_on_show
    }


@router.post("/preferences/bulk", response_model=List[UserVerticalPreferenceRead])
def set_vertical_preferences_bulk(
    data: BulkVerticalPreferencesCreate,
    session: Session = Depends(get_session),
    current_user: User = Depends(get_current_user)
):
    """Set multiple band preferences at once (for onboarding)"""
    result = []
    
    for idx, vid in enumerate(data.vertical_ids):
        vertical = session.get(Vertical, vid)
        if not vertical:
            continue
        
        # Upsert
        existing = session.exec(
            select(UserVerticalPreference)
            .where(UserVerticalPreference.user_id == current_user.id)
            .where(UserVerticalPreference.vertical_id == vid)
        ).first()
        
        if existing:
            existing.display_mode = data.display_mode
            existing.priority = idx
            session.add(existing)
            pref = existing
        else:
            pref = UserVerticalPreference(
                user_id=current_user.id,
                vertical_id=vid,
                display_mode=data.display_mode,
                priority=idx,
                notify_on_show=True
            )
            session.add(pref)
        
        result.append({
            "vertical_id": vid,
            "vertical": vertical,
            "display_mode": data.display_mode,
            "priority": idx,
            "notify_on_show": True
        })
    
    session.commit()
    return result


@router.put("/preferences/{vertical_id}", response_model=UserVerticalPreferenceRead)
def update_vertical_preference(
    vertical_id: int,
    data: UserVerticalPreferenceUpdate,
    session: Session = Depends(get_session),
    current_user: User = Depends(get_current_user)
):
    """Update a specific band preference"""
    pref = session.exec(
        select(UserVerticalPreference)
        .where(UserVerticalPreference.user_id == current_user.id)
        .where(UserVerticalPreference.vertical_id == vertical_id)
    ).first()
    
    if not pref:
        raise HTTPException(status_code=404, detail="Preference not found")
    
    vertical = session.get(Vertical, vertical_id)
    
    update_data = data.model_dump(exclude_unset=True)
    for key, value in update_data.items():
        setattr(pref, key, value)
    
    session.add(pref)
    session.commit()
    session.refresh(pref)
    
    return {
        "vertical_id": pref.vertical_id,
        "vertical": vertical,
        "display_mode": pref.display_mode,
        "priority": pref.priority,
        "tier": pref.tier,
        "notify_on_show": pref.notify_on_show
    }


@router.delete("/preferences/{vertical_id}")
def delete_vertical_preference(
    vertical_id: int,
    session: Session = Depends(get_session),
    current_user: User = Depends(get_current_user)
):
    """Remove a band from user's preferences"""
    pref = session.exec(
        select(UserVerticalPreference)
        .where(UserVerticalPreference.user_id == current_user.id)
        .where(UserVerticalPreference.vertical_id == vertical_id)
    ).first()
    
    if not pref:
        raise HTTPException(status_code=404, detail="Preference not found")
    
    session.delete(pref)
    session.commit()
    
    return {"ok": True}
