"""
Authorization helpers for multi-event system
Ensures users can only access events they are members of
"""
from fastapi import Depends, HTTPException, status
from sqlalchemy.orm import Session
from uuid import UUID
import crud
from database import get_db


class AuthzError(HTTPException):
    """Authorization error"""
    def __init__(self, detail: str = "Not authorized"):
        super().__init__(status_code=status.HTTP_403_FORBIDDEN, detail=detail)


async def verify_event_access(
    event_id: UUID,
    db: Session = Depends(get_db),
    current_user_id: UUID = Depends(lambda: None)
) -> dict:
    """
    Verify that current user is a member of the event
    
    Returns:
        dict with event and member info
        
    Raises:
        HTTPException 403 if user is not a member
    """
    # This is a helper - actual implementation depends on how you handle auth
    # You'll need to implement get_current_user_id() based on your auth system
    # (JWT, session cookies, etc.)
    
    event = crud.get_event(db, event_id)
    if not event:
        raise HTTPException(status_code=404, detail="Event not found")
    
    if not current_user_id:
        raise HTTPException(status_code=401, detail="Not authenticated")
    
    member = crud.get_event_member(db, event_id, current_user_id)
    if not member:
        raise AuthzError("You are not a member of this event")
    
    return {
        "event": event,
        "member": member,
        "role": member.role,
        "user_id": current_user_id
    }


async def verify_event_admin(
    event_id: UUID,
    db: Session = Depends(get_db),
    current_user_id: UUID = Depends(lambda: None)
) -> dict:
    """
    Verify that current user is an admin of the event
    
    Raises:
        HTTPException 403 if user is not admin
    """
    authz = await verify_event_access(event_id, db, current_user_id)
    
    if authz["role"] not in ("admin",):
        raise AuthzError("Only event admins can perform this action")
    
    return authz


async def verify_event_editor(
    event_id: UUID,
    db: Session = Depends(get_db),
    current_user_id: UUID = Depends(lambda: None)
) -> dict:
    """
    Verify that current user is at least an editor of the event
    
    Raises:
        HTTPException 403 if user is not editor or admin
    """
    authz = await verify_event_access(event_id, db, current_user_id)
    
    if authz["role"] not in ("admin", "editor"):
        raise AuthzError("Only event editors and admins can perform this action")
    
    return authz


async def verify_guest_belongs_to_event(
    guest_id: UUID,
    event_id: UUID,
    db: Session = Depends(get_db)
) -> None:
    """
    Verify that guest belongs to the specified event
    
    Raises:
        HTTPException 404 if guest doesn't belong to event
    """
    guest = crud.get_guest(db, guest_id, event_id)
    if not guest:
        raise HTTPException(status_code=404, detail="Guest not found in this event")


# Role-based access control enum
class Role:
    ADMIN = "admin"
    EDITOR = "editor"
    VIEWER = "viewer"
    
    @classmethod
    def is_admin(cls, role: str) -> bool:
        return role == cls.ADMIN
    
    @classmethod
    def is_editor(cls, role: str) -> bool:
        return role in (cls.ADMIN, cls.EDITOR)
    
    @classmethod
    def is_viewer(cls, role: str) -> bool:
        return role in (cls.ADMIN, cls.EDITOR, cls.VIEWER)


# Permission definitions
class Permission:
    """Define permissions for each role"""
    
    @staticmethod
    def can_edit_event(role: str) -> bool:
        """Can modify event details"""
        return Role.is_admin(role)
    
    @staticmethod
    def can_delete_event(role: str) -> bool:
        """Can delete event"""
        return Role.is_admin(role)
    
    @staticmethod
    def can_manage_members(role: str) -> bool:
        """Can add/remove members"""
        return Role.is_admin(role)
    
    @staticmethod
    def can_add_guests(role: str) -> bool:
        """Can add guests to event"""
        return Role.is_editor(role)
    
    @staticmethod
    def can_edit_guests(role: str) -> bool:
        """Can edit guest details"""
        return Role.is_editor(role)
    
    @staticmethod
    def can_delete_guests(role: str) -> bool:
        """Can delete guests"""
        return Role.is_admin(role)
    
    @staticmethod
    def can_import_guests(role: str) -> bool:
        """Can bulk import guests"""
        return Role.is_editor(role)
    
    @staticmethod
    def can_send_messages(role: str) -> bool:
        """Can send WhatsApp messages"""
        return Role.is_viewer(role)  # All members can send
    
    @staticmethod
    def can_view_guests(role: str) -> bool:
        """Can view guests list"""
        return Role.is_viewer(role)
