from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy.orm import Session
from typing import List
from uuid import UUID
from ..database import get_db
from ..models.tag import Tag, StreamTag
from ..models.stream import Stream
from ..models.user import User
from ..schemas.tag import TagCreate, TagResponse
from ..auth import get_current_active_user, require_permission, require_any_permission

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


@router.get("", response_model=List[TagResponse])
async def list_tags(
    skip: int = 0,
    limit: int = 50,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_active_user)
):
    tags = db.query(Tag).offset(skip).limit(limit).all()
    return tags


@router.post("", response_model=TagResponse, status_code=status.HTTP_201_CREATED)
async def create_tag(
    tag_data: TagCreate,
    db: Session = Depends(get_db),
    current_user: User = Depends(require_permission("tag:create"))
):
    existing_tag = db.query(Tag).filter(Tag.name == tag_data.name).first()
    if existing_tag:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="Tag already exists"
        )
    
    new_tag = Tag(name=tag_data.name)
    db.add(new_tag)
    db.commit()
    db.refresh(new_tag)
    
    return new_tag


@router.post("/streams/{stream_id}/{tag_id}", status_code=status.HTTP_201_CREATED)
async def add_tag_to_stream(
    stream_id: UUID,
    tag_id: UUID,
    db: Session = Depends(get_db),
    current_user: User = Depends(require_permission("tag:create"))
):
    stream = db.query(Stream).filter(Stream.id == stream_id).first()
    if not stream:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="Stream not found"
        )
    
    if stream.created_by != current_user.id:
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="Access denied"
        )
    
    tag = db.query(Tag).filter(Tag.id == tag_id).first()
    if not tag:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="Tag not found"
        )
    
    existing = db.query(StreamTag).filter(
        StreamTag.stream_id == stream_id,
        StreamTag.tag_id == tag_id
    ).first()
    
    if existing:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="Tag already added to stream"
        )
    
    stream_tag = StreamTag(stream_id=stream_id, tag_id=tag_id)
    db.add(stream_tag)
    db.commit()
    
    return {"message": "Tag added successfully"}


@router.delete("/streams/{stream_id}/{tag_id}", status_code=status.HTTP_204_NO_CONTENT)
async def remove_tag_from_stream(
    stream_id: UUID,
    tag_id: UUID,
    db: Session = Depends(get_db),
    current_user: User = Depends(require_permission("tag:delete"))
):
    stream = db.query(Stream).filter(Stream.id == stream_id).first()
    if not stream:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="Stream not found"
        )
    
    if stream.created_by != current_user.id:
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="Access denied"
        )
    
    stream_tag = db.query(StreamTag).filter(
        StreamTag.stream_id == stream_id,
        StreamTag.tag_id == tag_id
    ).first()
    
    if not stream_tag:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="Tag not found on stream"
        )
    
    db.delete(stream_tag)
    db.commit()
    
    return None


@router.get("/streams/{stream_id}", response_model=List[TagResponse])
async def get_stream_tags(
    stream_id: UUID,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_active_user)
):
    stream = db.query(Stream).filter(Stream.id == stream_id).first()
    if not stream:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="Stream not found"
        )
    
    stream_tags = db.query(StreamTag).filter(StreamTag.stream_id == stream_id).all()
    tags = [db.query(Tag).filter(Tag.id == st.tag_id).first() for st in stream_tags]
    return [t for t in tags if t]
