"""
Centralized permission checks for ResolutionFlow.

Role hierarchy: super_admin > owner > engineer > viewer

- super_admin: is_super_admin=True, full system access
- owner:       account_role='owner', manage account resources
- engineer:    account_role='engineer' (default), CRUD own trees/steps
- viewer:      account_role='viewer', read-only (can browse, run sessions, rate steps)
"""
from __future__ import annotations
from typing import Optional, TYPE_CHECKING
from uuid import UUID

if TYPE_CHECKING:
    from app.models.user import User
    from app.models.tree import Tree
    from app.models.step_library import StepLibrary
    from app.models.category import TreeCategory
    from app.models.step_category import StepCategory

ROLE_HIERARCHY = {
    "super_admin": 4,
    "owner": 3,
    "engineer": 2,
    "viewer": 1,
}


def get_effective_role(user: User) -> str:
    """Get the effective role considering is_super_admin and account_role."""
    if user.is_super_admin:
        return "super_admin"
    if user.account_role == "owner":
        return "owner"
    return user.account_role  # "engineer" or "viewer"


def has_minimum_role(user: User, minimum_role: str) -> bool:
    """Check if user has at least the specified role level."""
    effective = get_effective_role(user)
    return ROLE_HIERARCHY.get(effective, 0) >= ROLE_HIERARCHY.get(minimum_role, 0)


def can_create_content(user: User) -> bool:
    """Can the user create trees, steps, or other content? Viewers cannot."""
    return has_minimum_role(user, "engineer")


def can_edit_tree(user: User, tree: Tree) -> bool:
    """Can the user edit this specific tree?"""
    if user.is_super_admin:
        return True
    if not can_create_content(user):
        return False
    if tree.author_id == user.id:
        return True
    if user.account_role == "owner" and tree.account_id == user.account_id and user.account_id is not None:
        return True
    return False


def can_delete_tree(user: User, tree: Tree) -> bool:
    """Can the user delete this tree? Super admin only."""
    return user.is_super_admin


def can_edit_step(user: User, step: StepLibrary) -> bool:
    """Can the user edit/delete this step?"""
    if user.is_super_admin:
        return True
    if not can_create_content(user):
        return False
    return step.created_by == user.id


def can_manage_category(user: User, category: TreeCategory) -> bool:
    """Can the user edit/delete this category?"""
    if user.is_super_admin:
        return True
    if user.account_role == "owner" and category.account_id == user.account_id and user.account_id is not None:
        return True
    return False


def can_manage_tree_tags(user: User, tree: Tree) -> bool:
    """Can the user add/remove tags on this tree?"""
    if user.is_super_admin:
        return True
    if not can_create_content(user):
        return False
    if tree.author_id == user.id:
        return True
    if user.account_role == "owner" and tree.account_id == user.account_id and user.account_id is not None:
        return True
    return False


def can_access_tree(user: User, tree: Tree) -> bool:
    """Can the user access (view) this tree?"""
    if tree.is_default or tree.is_public:
        return True
    if tree.author_id == user.id:
        return True
    if tree.account_id == user.account_id and user.account_id is not None:
        return True
    if user.is_super_admin:
        return True
    return False


def can_view_step(user: User, step: StepLibrary) -> bool:
    """Can the user view this step based on its visibility?"""
    if step.visibility == "public":
        return True
    if step.visibility == "private":
        return step.created_by == user.id
    if step.visibility == "team":
        return (step.account_id == user.account_id and user.account_id is not None) or user.is_super_admin
    return False


def can_create_tag(user: User, account_id: Optional[UUID]) -> bool:
    """Can the user create a tag for the given scope?

    - Super admins can create global tags (account_id=None) or any account's tags
    - Engineers can create account tags for their own account
    - Viewers cannot create tags
    """
    if user.is_super_admin:
        return True
    if not can_create_content(user):
        return False
    if account_id is not None and account_id == user.account_id:
        return True
    return False


def can_create_category(user: User, account_id: Optional[UUID]) -> bool:
    """Can the user create a category for the given account?

    - Super admins can create global or any account's categories
    - Account owners can create categories for their own account
    """
    if user.is_super_admin:
        return True
    if user.account_role == "owner" and account_id == user.account_id and user.account_id is not None:
        return True
    return False


def can_manage_step_category(user: User, category: StepCategory) -> bool:
    """Can the user edit/delete this step category?"""
    if user.is_super_admin:
        return True
    if user.account_role == "owner" and category.account_id == user.account_id and user.account_id is not None:
        return True
    return False


def can_create_step_category(user: User, account_id: Optional[UUID]) -> bool:
    """Can the user create a step category for the given account?

    - Super admins can create global or any account's step categories
    - Account owners can create step categories for their own account
    """
    if user.is_super_admin:
        return True
    if user.account_role == "owner" and account_id == user.account_id and user.account_id is not None:
        return True
    return False
