from fastapi import Depends, HTTPException, status
from fastapi.security import OAuth2PasswordBearer
from sqlalchemy.orm import Session
from jose import JWTError
from .database import get_db
from .models import User, UserPermission, RolePagePermission
from .auth import decode_token

oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/api/auth/login")


def get_current_user(
    token: str = Depends(oauth2_scheme),
    db: Session = Depends(get_db),
) -> User:
    exc = HTTPException(
        status_code=status.HTTP_401_UNAUTHORIZED,
        detail="Invalid or expired token",
        headers={"WWW-Authenticate": "Bearer"},
    )
    try:
        payload = decode_token(token)
        user_id = int(payload.get("sub"))
    except (JWTError, TypeError, ValueError):
        raise exc

    user = db.query(User).filter(User.id == user_id, User.is_active == True).first()
    if not user:
        raise exc
    return user


def require_owner(current_user: User = Depends(get_current_user)) -> User:
    if current_user.role not in ('OWNER', 'SUPER_ADMIN'):
        raise HTTPException(status_code=403, detail="Owner access required")
    return current_user


def require_super_admin(current_user: User = Depends(get_current_user)) -> User:
    if current_user.role != 'SUPER_ADMIN':
        raise HTTPException(status_code=403, detail="Super Admin access required")
    return current_user


def require_permission(module: str, action: str = 'can_view'):
    """Returns a dependency that checks role_page_permissions (all roles) and user_permissions (MANAGER)."""
    def checker(
        user: User = Depends(get_current_user),
        db: Session = Depends(get_db),
    ) -> User:
        if user.role == 'SUPER_ADMIN':
            return user
        # Role-level gate (OWNER and MANAGER)
        rp = db.query(RolePagePermission).filter_by(role=user.role, module=module).first()
        if rp is not None and not rp.can_access:
            raise HTTPException(status_code=403, detail=f"Role {user.role} cannot access {module}")
        if user.role == 'OWNER':
            return user
        # MANAGER: also check individual UserPermission
        perm = db.query(UserPermission).filter_by(user_id=user.id, module=module).first()
        if not perm or not getattr(perm, action, False):
            raise HTTPException(status_code=403, detail=f"No {action} permission for {module}")
        return user
    return checker
