"""
Velmu Intent Flags

Bitfield flags for Gateway intents.
"""


class BaseFlags:
    """Base class for bitfield flags."""
    
    def __init__(self, value=0):
        self.value = value

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.value == other.value

    def __ne__(self, other):
        return not self.__eq__(other)

    def __hash__(self):
        return hash(self.value)

    def __iter__(self):
        for name, value in self.__class__.__dict__.items():
            if isinstance(value, int) and not name.startswith('_'):
                yield name, (self.value & value) == value
    
    def __repr__(self):
        enabled = [name for name, enabled in self if enabled]
        return f'<{self.__class__.__name__} value={self.value} enabled={enabled}>'

    def _set_flag(self, flag, value):
        if value:
            self.value |= flag
        else:
            self.value &= ~flag


class Intents(BaseFlags):
    """Gateway intents for subscribing to events.
    
    Intents control which events your bot receives from the Gateway.
    Some intents are **privileged** and must be enabled in the Developer Portal.
    
    Privileged Intents
    ------------------
    - GUILD_MEMBERS (1 << 1): Required for member join/leave events
    - GUILD_PRESENCES (1 << 8): Required for presence updates
    - MESSAGE_CONTENT (1 << 15): Required to read message content
    
    Example
    -------
    ```python
    # Default intents (most common use case)
    intents = Intents.default()
    
    # Enable a privileged intent
    intents.message_content = True
    intents.members = True
    
    # All intents (requires all privileged intents enabled in portal)
    intents = Intents.all()
    ```
    """
    
    # Guild-related
    GUILDS = 1 << 0
    GUILD_MEMBERS = 1 << 1  # PRIVILEGED
    GUILD_MODERATION = 1 << 2
    GUILD_EMOJIS_AND_STICKERS = 1 << 3
    GUILD_INTEGRATIONS = 1 << 4
    GUILD_WEBHOOKS = 1 << 5
    GUILD_INVITES = 1 << 6
    GUILD_VOICE_STATES = 1 << 7
    GUILD_PRESENCES = 1 << 8  # PRIVILEGED
    
    # Message-related
    GUILD_MESSAGES = 1 << 9
    GUILD_MESSAGE_REACTIONS = 1 << 10
    GUILD_MESSAGE_TYPING = 1 << 11
    
    # DM-related
    DIRECT_MESSAGES = 1 << 12
    DIRECT_MESSAGE_REACTIONS = 1 << 13
    DIRECT_MESSAGE_TYPING = 1 << 14
    
    # Content
    MESSAGE_CONTENT = 1 << 15  # PRIVILEGED
    
    # Scheduled Events
    GUILD_SCHEDULED_EVENTS = 1 << 16
    
    # Auto Moderation
    AUTO_MODERATION_CONFIGURATION = 1 << 20
    AUTO_MODERATION_EXECUTION = 1 << 21

    # =========================================
    # Factory Methods
    # =========================================

    @classmethod
    def default(cls) -> 'Intents':
        """Create intents with common non-privileged intents enabled.
        
        Includes: GUILDS, GUILD_MESSAGES, GUILD_MESSAGE_REACTIONS,
        DIRECT_MESSAGES, DIRECT_MESSAGE_REACTIONS
        """
        self = cls(0)
        self.value = (
            cls.GUILDS |
            cls.GUILD_MESSAGES |
            cls.GUILD_MESSAGE_REACTIONS |
            cls.DIRECT_MESSAGES |
            cls.DIRECT_MESSAGE_REACTIONS
        )
        return self

    @classmethod
    def all(cls) -> 'Intents':
        """Create intents with ALL intents enabled.
        
        ⚠️ Warning: This includes privileged intents that must be
        enabled in the Developer Portal.
        """
        self = cls(0)
        all_bits = 0
        for name, value in cls.__dict__.items():
            if isinstance(value, int) and not name.startswith('_'):
                all_bits |= value
        self.value = all_bits
        return self
    
    @classmethod
    def none(cls) -> 'Intents':
        """Create intents with no intents enabled."""
        return cls(0)
    
    @classmethod
    def privileged(cls) -> 'Intents':
        """Create intents with only privileged intents enabled."""
        self = cls(0)
        self.value = cls.GUILD_MEMBERS | cls.GUILD_PRESENCES | cls.MESSAGE_CONTENT
        return self

    # =========================================
    # Guild Properties
    # =========================================

    @property
    def guilds(self) -> bool:
        """Whether GUILDS intent is enabled."""
        return (self.value & self.GUILDS) == self.GUILDS
    
    @guilds.setter
    def guilds(self, v: bool):
        self._set_flag(self.GUILDS, v)

    @property
    def members(self) -> bool:
        """Whether GUILD_MEMBERS intent is enabled. (PRIVILEGED)"""
        return (self.value & self.GUILD_MEMBERS) == self.GUILD_MEMBERS
    
    @members.setter
    def members(self, v: bool):
        self._set_flag(self.GUILD_MEMBERS, v)

    @property
    def moderation(self) -> bool:
        """Whether GUILD_MODERATION intent is enabled."""
        return (self.value & self.GUILD_MODERATION) == self.GUILD_MODERATION
    
    @moderation.setter
    def moderation(self, v: bool):
        self._set_flag(self.GUILD_MODERATION, v)

    @property
    def emojis(self) -> bool:
        """Whether GUILD_EMOJIS_AND_STICKERS intent is enabled."""
        return (self.value & self.GUILD_EMOJIS_AND_STICKERS) == self.GUILD_EMOJIS_AND_STICKERS
    
    @emojis.setter
    def emojis(self, v: bool):
        self._set_flag(self.GUILD_EMOJIS_AND_STICKERS, v)

    @property
    def integrations(self) -> bool:
        """Whether GUILD_INTEGRATIONS intent is enabled."""
        return (self.value & self.GUILD_INTEGRATIONS) == self.GUILD_INTEGRATIONS
    
    @integrations.setter
    def integrations(self, v: bool):
        self._set_flag(self.GUILD_INTEGRATIONS, v)

    @property
    def webhooks(self) -> bool:
        """Whether GUILD_WEBHOOKS intent is enabled."""
        return (self.value & self.GUILD_WEBHOOKS) == self.GUILD_WEBHOOKS
    
    @webhooks.setter
    def webhooks(self, v: bool):
        self._set_flag(self.GUILD_WEBHOOKS, v)

    @property
    def invites(self) -> bool:
        """Whether GUILD_INVITES intent is enabled."""
        return (self.value & self.GUILD_INVITES) == self.GUILD_INVITES
    
    @invites.setter
    def invites(self, v: bool):
        self._set_flag(self.GUILD_INVITES, v)

    @property
    def voice_states(self) -> bool:
        """Whether GUILD_VOICE_STATES intent is enabled."""
        return (self.value & self.GUILD_VOICE_STATES) == self.GUILD_VOICE_STATES
    
    @voice_states.setter
    def voice_states(self, v: bool):
        self._set_flag(self.GUILD_VOICE_STATES, v)

    @property
    def presences(self) -> bool:
        """Whether GUILD_PRESENCES intent is enabled. (PRIVILEGED)"""
        return (self.value & self.GUILD_PRESENCES) == self.GUILD_PRESENCES
    
    @presences.setter
    def presences(self, v: bool):
        self._set_flag(self.GUILD_PRESENCES, v)

    # =========================================
    # Message Properties
    # =========================================

    @property
    def guild_messages(self) -> bool:
        """Whether GUILD_MESSAGES intent is enabled."""
        return (self.value & self.GUILD_MESSAGES) == self.GUILD_MESSAGES
    
    @guild_messages.setter
    def guild_messages(self, v: bool):
        self._set_flag(self.GUILD_MESSAGES, v)

    @property
    def guild_reactions(self) -> bool:
        """Whether GUILD_MESSAGE_REACTIONS intent is enabled."""
        return (self.value & self.GUILD_MESSAGE_REACTIONS) == self.GUILD_MESSAGE_REACTIONS
    
    @guild_reactions.setter
    def guild_reactions(self, v: bool):
        self._set_flag(self.GUILD_MESSAGE_REACTIONS, v)

    @property
    def guild_typing(self) -> bool:
        """Whether GUILD_MESSAGE_TYPING intent is enabled."""
        return (self.value & self.GUILD_MESSAGE_TYPING) == self.GUILD_MESSAGE_TYPING
    
    @guild_typing.setter
    def guild_typing(self, v: bool):
        self._set_flag(self.GUILD_MESSAGE_TYPING, v)

    @property
    def dm_messages(self) -> bool:
        """Whether DIRECT_MESSAGES intent is enabled."""
        return (self.value & self.DIRECT_MESSAGES) == self.DIRECT_MESSAGES
    
    @dm_messages.setter
    def dm_messages(self, v: bool):
        self._set_flag(self.DIRECT_MESSAGES, v)

    @property
    def dm_reactions(self) -> bool:
        """Whether DIRECT_MESSAGE_REACTIONS intent is enabled."""
        return (self.value & self.DIRECT_MESSAGE_REACTIONS) == self.DIRECT_MESSAGE_REACTIONS
    
    @dm_reactions.setter
    def dm_reactions(self, v: bool):
        self._set_flag(self.DIRECT_MESSAGE_REACTIONS, v)

    @property
    def dm_typing(self) -> bool:
        """Whether DIRECT_MESSAGE_TYPING intent is enabled."""
        return (self.value & self.DIRECT_MESSAGE_TYPING) == self.DIRECT_MESSAGE_TYPING
    
    @dm_typing.setter
    def dm_typing(self, v: bool):
        self._set_flag(self.DIRECT_MESSAGE_TYPING, v)

    @property
    def message_content(self) -> bool:
        """Whether MESSAGE_CONTENT intent is enabled. (PRIVILEGED)"""
        return (self.value & self.MESSAGE_CONTENT) == self.MESSAGE_CONTENT
    
    @message_content.setter
    def message_content(self, v: bool):
        self._set_flag(self.MESSAGE_CONTENT, v)

    # =========================================
    # Other Properties
    # =========================================

    @property
    def scheduled_events(self) -> bool:
        """Whether GUILD_SCHEDULED_EVENTS intent is enabled."""
        return (self.value & self.GUILD_SCHEDULED_EVENTS) == self.GUILD_SCHEDULED_EVENTS
    
    @scheduled_events.setter
    def scheduled_events(self, v: bool):
        self._set_flag(self.GUILD_SCHEDULED_EVENTS, v)

    @property
    def auto_moderation_configuration(self) -> bool:
        """Whether AUTO_MODERATION_CONFIGURATION intent is enabled."""
        return (self.value & self.AUTO_MODERATION_CONFIGURATION) == self.AUTO_MODERATION_CONFIGURATION
    
    @auto_moderation_configuration.setter
    def auto_moderation_configuration(self, v: bool):
        self._set_flag(self.AUTO_MODERATION_CONFIGURATION, v)

    @property
    def auto_moderation_execution(self) -> bool:
        """Whether AUTO_MODERATION_EXECUTION intent is enabled."""
        return (self.value & self.AUTO_MODERATION_EXECUTION) == self.AUTO_MODERATION_EXECUTION
    
    @auto_moderation_execution.setter
    def auto_moderation_execution(self, v: bool):
        self._set_flag(self.AUTO_MODERATION_EXECUTION, v)
