"""
Ticket Permissions Utility
==========================
Centralized permission logic for the ticket system.
"""
import disnake
from typing import TYPE_CHECKING, Optional

if TYPE_CHECKING:
    from ..data.models import GuildTicketConfig, TicketCategory

def is_staff(interaction: disnake.Interaction, config: 'GuildTicketConfig', category: Optional['TicketCategory'] = None) -> bool:
    """
    Check if the user has staff permissions.
    
    If a category is provided and has specific staff_roles defined,
    only those roles (and admins) are considered staff for this check.
    Otherwise, global staff roles from the config are used.
    """
    # Get user and permissions based on object type
    user = getattr(interaction, "author", getattr(interaction, "user", None))
    if not user:
        return False

    if user.guild_permissions.administrator:
        return True

    # Check specific users (always allowed)
    if user.id in config.staff_users:
        return True
        
    # If category has specific roles, only those are allowed
    if category and category.staff_roles:
        for role_id in category.staff_roles:
            try:
                role = interaction.guild.get_role(int(role_id))
                if role and role in user.roles:
                    return True
            except (ValueError, TypeError):
                continue
        return False

    # Check global roles
    for role_id in config.staff_roles:
        try:
            role = interaction.guild.get_role(int(role_id))
            if role and role in user.roles:
                return True
        except (ValueError, TypeError):
            continue
            
    return False

def can_access_config(interaction: disnake.Interaction, config: 'GuildTicketConfig') -> bool:
    """
    Check if the user can access the configuration.
    
    Checks:
    1. Administrator permission
    2. Config roles
    3. Config users
    4. Staff permissions (staff can often access basic config or view panels)
       Note: This function is strictly for CONFIG access.
             If staff should access config, add them to config roles or check is_staff too.
             In this implementation, we check specific config permissions.
    """
    # Get user and permissions based on object type
    user = getattr(interaction, "author", getattr(interaction, "user", None))
    if not user:
        return False
        
    if user.guild_permissions.administrator:
        return True
    
    # Check specific users
    if user.id in config.config_users:
        return True
        
    # Check config roles
    for role_id in config.config_roles:
        role = interaction.guild.get_role(int(role_id))
        if role and role in user.roles:
            return True

    # Also check legacy/migrated staff roles if they imply config access?
    # For now, we keep it strict: config access requires explicit config permission.
    
    return False

def is_whitelisted(interaction: disnake.Interaction, config: 'GuildTicketConfig', bot) -> bool:
    """
    Check if user is whitelisted or has staff/config permissions.
    """
    # Staff and config users are always whitelisted
    if is_staff(interaction, config) or can_access_config(interaction, config):
        return True
        
    # Check whitelist cog
    whitelist_cog = bot.get_cog("WhitelistMonitor")
    if not whitelist_cog:
        # If whitelist system not available, deny unless staff/config
        return False
        
    return whitelist_cog.is_whitelisted(interaction.guild.id, interaction.user.id)
