# ========= Copyright 2023-2024 @ CAMEL-AI.org. All Rights Reserved. =========
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ========= Copyright 2023-2024 @ CAMEL-AI.org. All Rights Reserved. =========
from typing import Optional

from pydantic import BaseModel


class SlackAuthProfile(BaseModel):
    r"""Represents the authorization profile within a Slack event.

    Events will contain a single, compact authorizations field that shows one
    installation of your app that the event is visible to.
    In other words, lists of authorizations will be truncated to one element.

    If there's more than one installing party that your app is keeping track
    of, it's best not to rely on the single party listed in authorizations to
    be any particular one.

    To get a full list of who can see events, call the apps.event.
    authorizations.list method after obtaining an app-level token. Read more on
    the changes here; they have taken effect for existing apps as of
    February 24, 2021.

    References:

    - https://api.slack.com/apis/events-api#authorizations
    - https://api.slack.com/changelog/2020-09-15-events-api-truncate-authed-users#no_context
    """

    enterprise_id: Optional[str] = None
    """The ID of the enterprise associated with the authorization."""

    team_id: str
    """The ID of the team associated with the authorization."""

    user_id: str
    """The ID of the user associated with the authorization."""

    is_bot: bool
    """Whether the authorized user is a bot."""

    is_enterprise_install: bool
    """Whether the authorization is for an enterprise installation."""


class SlackEventProfile(BaseModel):
    r"""Represents the detailed profile of a Slack event, including user,
    message, and context data.
    """

    user: str
    """The ID of the user associated with the event."""

    type: str
    """The type of the event (e.g., 'message')."""

    ts: str
    """A timestamp representing when the event was triggered."""

    thread_ts: Optional[str] = None
    """The timestamp of the parent message in a thread."""

    client_msg_id: str
    """A unique ID generated by the client for the message (if available)."""

    text: str
    """The message content text."""

    team: str
    """The ID of the team that the event is associated with."""

    blocks: list
    """The list of message blocks, providing structured information."""

    channel: str
    """The ID of the Slack channel where the event happened."""

    event_ts: str
    """The event-specific timestamp when it occurred."""

    channel_type: Optional[str]
    """The type of Slack channel (e.g., 'channel', 'im')."""


class SlackEventBody(BaseModel):
    r"""Represents the entire body of a Slack event, including the event
    profile, authorization, and context.
    """

    token: str
    """The token to verify the source of the event."""

    team_id: str
    """The ID of the team where the event is happening."""

    context_team_id: Optional[str]
    """The team ID for the shared channel context, if applicable."""

    context_enterprise_id: Optional[str] = None
    """The enterprise ID for the shared channel context, if applicable."""

    api_app_id: str
    """The unique identifier for the Slack app that received the event."""

    event: SlackEventProfile
    """A detailed profile of the event"""

    type: str
    """The overall type of event received (e.g., 'event_callback')."""

    event_id: str
    """A unique identifier assigned to this event by Slack."""

    event_time: int
    """The timestamp (in seconds) representing when the event was triggered."""

    authorizations: Optional[list[SlackAuthProfile]] = None
    """An optional list of authorizations that describe which installation can 
    see the event."""

    is_ext_shared_channel: bool
    """Indicates if the event is part of a shared channel between different 
    organizations."""

    event_context: str
    """A unique string representing the context of the event."""


class SlackAppMentionEventProfile(SlackEventProfile):
    r"""Represents the detailed profile of a Slack event where the app was
    mentioned in a message.
    """

    channel_type: Optional[str] = None
    """The type of Slack channel. it's None for app mentions."""


class SlackAppMentionEventBody(SlackEventBody):
    r"""Represents the entire body of a Slack event where the app was mentioned
    in a message.
    """

    context_team_id: Optional[str] = None
    """A detailed profile of the event. it's None for app mentions."""

    event: SlackAppMentionEventProfile
    """A detailed profile of the event"""
