from typing import TypeVar

from telethon.utils import is_audio, is_gif, is_image, is_video

from _garnet.events.filter import Filter
from _garnet.patched_events import NewMessage

from ..helpers import var

E = TypeVar("E", bound=NewMessage.Event)
FE = Filter[E]


class _FilterVar(var.Var):  # type: ignore
    def __set_name__(self, owner, val: str):  # type: ignore
        if not self.value:
            self.value = Filter(
                lambda e: e.file is not None and val == e.file.ext,
                event_builder=NewMessage,
            )


class File:
    """
    Namespace for file extension filters.

    Usage:

    >>> from garnet.filters import File
    ...
    >>> @router.message(File.is_video & (File.mp4 | File.mov))
    ... async def handle_video(event): pass
    >>>
    >>> @router.message(File.is_audio)
    ... async def handle_audio(): pass
    """

    is_video: FE = Filter(lambda event: is_video(event.media))
    is_image: FE = Filter(lambda event: is_image(event.media))
    is_gif: FE = Filter(lambda event: is_gif(event.document))
    is_audio: FE = Filter(lambda event: is_audio(event.media))

    # generated by extensions
    # Image extensions
    png: FE = _FilterVar()
    jpeg: FE = _FilterVar()
    webp: FE = _FilterVar()
    gif: FE = _FilterVar()
    bmp: FE = _FilterVar()
    tga: FE = _FilterVar()
    tiff: FE = _FilterVar()
    psd: FE = _FilterVar()

    # Video extensions
    mp4: FE = _FilterVar()
    mov: FE = _FilterVar()
    avi: FE = _FilterVar()

    # Audio extensions
    mp2: FE = _FilterVar()  # a.k.a. ISO/IEC 13818-2
    mp3: FE = _FilterVar()
    m4a: FE = _FilterVar()
    aac: FE = _FilterVar()
    ogg: FE = _FilterVar()
    flac: FE = _FilterVar()

    # Win executable extension
    exe: FE = _FilterVar()
