from typing import TYPE_CHECKING, Literal, TypedDict

import discord
from discord import Emoji, PartialEmoji, ui
from discord.interactions import Interaction

from ..utils import call_any_function  # noqa: TID252

if TYPE_CHECKING:
    from ..types import InteractionCallback  # noqa: TID252


class _ButtonStyleRequired(TypedDict):
    color: Literal["blurple", "grey", "green", "red"]


class ButtonStyle(_ButtonStyleRequired, total=False):
    disabled: bool
    emoji: str | Emoji | PartialEmoji | None
    row: Literal[0, 1, 2, 3, 4]


class Button(ui.Button):
    def __init__(
        self,
        label: str | None = None,
        /,
        *,
        style: ButtonStyle,
        custom_id: str | None = None,
        on_click: "InteractionCallback | None" = None,
    ) -> None:
        __style = discord.ButtonStyle[style.get("color", "grey")]
        __disabled = style.get("disabled", False)
        __emoji = style.get("emoji", None)
        __row = style.get("row", None)
        self.__callback_fn = on_click
        super().__init__(
            style=__style,
            disabled=__disabled,
            emoji=__emoji,
            row=__row,
            label=label,
            custom_id=custom_id,
        )

    async def callback(self, interaction: Interaction) -> None:
        if self.__callback_fn:
            await call_any_function(self.__callback_fn, interaction)


class LinkButton(ui.Button):
    def __init__(self, label: str | None = None, /, *, url: str, custom_id: str | None = None) -> None:
        super().__init__(
            style=discord.ButtonStyle.link,
            url=url,
            label=label,
            custom_id=custom_id,
        )

    async def callback(self, interaction: Interaction) -> None:
        pass
