from typing import List, Optional
from datetime import datetime, timedelta
from fastapi import APIRouter, Depends, HTTPException
from sqlmodel import Session, select, func
from pydantic import BaseModel
from database import get_session
from models import Report, User, PerformanceNickname, Profile, Rating, Review, Comment, Attendance
from schemas import ReportCreate, ReportRead, PerformanceNicknameRead
from auth import get_current_user
from dependencies import RoleChecker

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

allow_moderator = RoleChecker(["moderator", "admin"])


# ============ SCHEMAS ============

class UserLookupResult(BaseModel):
    id: int
    email: str
    username: Optional[str] = None
    role: str
    is_active: bool
    email_verified: bool
    ban_expires: Optional[datetime] = None
    stats: dict

class TempBanRequest(BaseModel):
    user_id: int
    duration_hours: int  # 0 = permanent
    reason: str

class BulkActionRequest(BaseModel):
    ids: List[int]
    action: str  # approve, reject, resolve, dismiss

class ModActionLog(BaseModel):
    id: int
    moderator_id: int
    moderator_email: str
    action_type: str
    target_type: str
    target_id: int
    reason: Optional[str] = None
    created_at: datetime


# ============ USER LOOKUP ============

@router.get("/users/lookup")
def lookup_user(
    query: str,
    session: Session = Depends(get_session),
    mod: User = Depends(allow_moderator)
):
    """Search for a user by email or username"""
    # Search by email
    user = session.exec(select(User).where(User.email.contains(query))).first()
    
    if not user:
        # Try username via profile
        profile = session.exec(select(Profile).where(Profile.username.contains(query))).first()
        if profile:
            user = session.get(User, profile.user_id)
    
    if not user:
        raise HTTPException(status_code=404, detail="User not found")
    
    profile = session.exec(select(Profile).where(Profile.user_id == user.id)).first()
    
    return {
        "id": user.id,
        "email": user.email,
        "username": profile.username if profile else None,
        "role": user.role,
        "is_active": user.is_active,
        "email_verified": user.email_verified,
        "stats": {
            "ratings": session.exec(select(func.count(Rating.id)).where(Rating.user_id == user.id)).one(),
            "reviews": session.exec(select(func.count(Review.id)).where(Review.user_id == user.id)).one(),
            "comments": session.exec(select(func.count(Comment.id)).where(Comment.user_id == user.id)).one(),
            "attendances": session.exec(select(func.count(Attendance.id)).where(Attendance.user_id == user.id)).one(),
            "reports_submitted": session.exec(select(func.count(Report.id)).where(Report.user_id == user.id)).one(),
        }
    }


@router.get("/users/{user_id}/activity")
def get_user_activity(
    user_id: int,
    limit: int = 50,
    session: Session = Depends(get_session),
    mod: User = Depends(allow_moderator)
):
    """Get recent activity for a user"""
    user = session.get(User, user_id)
    if not user:
        raise HTTPException(status_code=404, detail="User not found")
    
    # Get recent comments
    comments = session.exec(
        select(Comment).where(Comment.user_id == user_id).limit(20)
    ).all()
    
    # Get recent reviews
    reviews = session.exec(
        select(Review).where(Review.user_id == user_id).limit(20)
    ).all()
    
    # Format activity
    activity = []
    for c in comments:
        activity.append({
            "type": "comment",
            "id": c.id,
            "content": c.content[:100] if c.content else "",
            "entity_type": c.entity_type,
            "entity_id": c.entity_id,
        })
    for r in reviews:
        activity.append({
            "type": "review",
            "id": r.id,
            "content": r.content[:100] if r.content else "",
            "show_id": r.show_id,
        })
    
    return activity[:limit]


# ============ TEMP BANS ============

@router.post("/users/ban")
def ban_user(
    request: TempBanRequest,
    session: Session = Depends(get_session),
    mod: User = Depends(allow_moderator)
):
    """Ban a user (temporarily or permanently)"""
    user = session.get(User, request.user_id)
    if not user:
        raise HTTPException(status_code=404, detail="User not found")
    
    # Don't allow banning admins
    if user.role == "admin":
        raise HTTPException(status_code=400, detail="Cannot ban an admin")
    
    # Don't allow mods to ban other mods (only admins can)
    if user.role == "moderator" and mod.role != "admin":
        raise HTTPException(status_code=400, detail="Only admins can ban moderators")
    
    user.is_active = False
    session.add(user)
    session.commit()
    
    return {
        "message": "User banned",
        "user_id": user.id,
        "duration_hours": request.duration_hours,
        "reason": request.reason
    }


@router.post("/users/{user_id}/unban")
def unban_user(
    user_id: int,
    session: Session = Depends(get_session),
    mod: User = Depends(allow_moderator)
):
    """Unban a user"""
    user = session.get(User, user_id)
    if not user:
        raise HTTPException(status_code=404, detail="User not found")
    
    user.is_active = True
    session.add(user)
    session.commit()
    
    return {"message": "User unbanned", "user_id": user.id}


# ============ BULK ACTIONS ============

@router.post("/nicknames/bulk")
def bulk_moderate_nicknames(
    request: BulkActionRequest,
    session: Session = Depends(get_session),
    mod: User = Depends(allow_moderator)
):
    """Bulk approve or reject nicknames"""
    if request.action not in ("approve", "reject"):
        raise HTTPException(status_code=400, detail="Invalid action")
    
    status = "approved" if request.action == "approve" else "rejected"
    count = 0
    
    for nickname_id in request.ids:
        nickname = session.get(PerformanceNickname, nickname_id)
        if nickname and nickname.status == "pending":
            nickname.status = status
            session.add(nickname)
            count += 1
    
    session.commit()
    return {"message": f"{count} nicknames {status}", "count": count}


@router.post("/reports/bulk")
def bulk_moderate_reports(
    request: BulkActionRequest,
    session: Session = Depends(get_session),
    mod: User = Depends(allow_moderator)
):
    """Bulk resolve or dismiss reports"""
    if request.action not in ("resolve", "dismiss"):
        raise HTTPException(status_code=400, detail="Invalid action")
    
    status = "resolved" if request.action == "resolve" else "dismissed"
    count = 0
    
    for report_id in request.ids:
        report = session.get(Report, report_id)
        if report and report.status == "pending":
            report.status = status
            session.add(report)
            count += 1
    
    session.commit()
    return {"message": f"{count} reports {status}", "count": count}


# ============ QUEUE STATS ============

@router.get("/queue/stats")
def get_queue_stats(
    session: Session = Depends(get_session),
    mod: User = Depends(allow_moderator)
):
    """Get moderation queue statistics"""
    return {
        "pending_nicknames": session.exec(
            select(func.count(PerformanceNickname.id)).where(PerformanceNickname.status == "pending")
        ).one(),
        "pending_reports": session.exec(
            select(func.count(Report.id)).where(Report.status == "pending")
        ).one(),
        "total_bans": session.exec(
            select(func.count(User.id)).where(User.is_active == False)
        ).one(),
    }


# ============ EXISTING ENDPOINTS ============

@router.post("/reports", response_model=ReportRead)
def create_report(
    report: ReportCreate,
    session: Session = Depends(get_session),
    current_user: User = Depends(get_current_user)
):
    db_report = Report.model_validate(report)
    db_report.user_id = current_user.id
    session.add(db_report)
    session.commit()
    session.refresh(db_report)
    return db_report

@router.get("/queue/nicknames", response_model=List[PerformanceNicknameRead], dependencies=[Depends(allow_moderator)])
def get_pending_nicknames(
    status: str = "pending",
    session: Session = Depends(get_session)
):
    query = select(PerformanceNickname)
    if status in ("pending", "approved", "rejected"):
        query = query.where(PerformanceNickname.status == status)
    nicknames = session.exec(query.limit(100)).all()
    return nicknames

@router.put("/nicknames/{nickname_id}/{action}", response_model=PerformanceNicknameRead, dependencies=[Depends(allow_moderator)])
def moderate_nickname(
    nickname_id: int, 
    action: str, # approve, reject
    session: Session = Depends(get_session)
):
    nickname = session.get(PerformanceNickname, nickname_id)
    if not nickname:
        raise HTTPException(status_code=404, detail="Nickname not found")
    
    if action == "approve":
        nickname.status = "approved"
    elif action == "reject":
        nickname.status = "rejected"
    else:
        raise HTTPException(status_code=400, detail="Invalid action")
        
    session.add(nickname)
    session.commit()
    session.refresh(nickname)
    return nickname

@router.get("/queue/reports", response_model=List[ReportRead], dependencies=[Depends(allow_moderator)])
def get_pending_reports(session: Session = Depends(get_session)):
    reports = session.exec(
        select(Report).where(Report.status == "pending")
    ).all()
    return reports

@router.put("/reports/{report_id}/{action}", response_model=ReportRead, dependencies=[Depends(allow_moderator)])
def moderate_report(
    report_id: int, 
    action: str, # resolve, dismiss
    session: Session = Depends(get_session)
):
    report = session.get(Report, report_id)
    if not report:
        raise HTTPException(status_code=404, detail="Report not found")
    
    if action == "resolve":
        report.status = "resolved"
    elif action == "dismiss":
        report.status = "dismissed"
    else:
        raise HTTPException(status_code=400, detail="Invalid action")
        
    session.add(report)
    session.commit()
    session.refresh(report)
    return report

