"""
This type stub file was generated by pyright.
"""

from collections.abc import Iterator, MutableMapping, Sequence
from dataclasses import dataclass
from enum import Enum
from typing import Any, Literal, TYPE_CHECKING, overload
from streamlit.elements.lib.image_utils import AtomicImage
from streamlit.elements.lib.utils import Key
from streamlit.proto.Common_pb2 import ChatInputValue as ChatInputValueProto
from streamlit.runtime.metrics_util import gather_metrics
from streamlit.runtime.state import WidgetArgs, WidgetCallback, WidgetKwargs
from streamlit.runtime.uploaded_file_manager import UploadedFile
from streamlit.delta_generator import DeltaGenerator

if TYPE_CHECKING:
    ...
@dataclass
class ChatInputValue(MutableMapping[str, Any]):
    text: str
    files: list[UploadedFile]
    def __len__(self) -> int:
        ...
    
    def __iter__(self) -> Iterator[str]:
        ...
    
    def __getitem__(self, item: str) -> str | list[UploadedFile]:
        ...
    
    def __setitem__(self, key: str, value: Any) -> None:
        ...
    
    def __delitem__(self, key: str) -> None:
        ...
    
    def to_dict(self) -> dict[str, str | list[UploadedFile]]:
        ...
    


class PresetNames(str, Enum):
    USER = ...
    ASSISTANT = ...
    AI = ...
    HUMAN = ...


@dataclass
class ChatInputSerde:
    accept_files: bool = ...
    allowed_types: Sequence[str] | None = ...
    def deserialize(self, ui_value: ChatInputValueProto | None, widget_id: str = ...) -> str | ChatInputValue | None:
        ...
    
    def serialize(self, v: str | None) -> ChatInputValueProto:
        ...
    


class ChatMixin:
    @gather_metrics("chat_message")
    def chat_message(self, name: Literal["user", "assistant", "ai", "human"] | str, *, avatar: Literal["user", "assistant"] | str | AtomicImage | None = ...) -> DeltaGenerator:
        """Insert a chat message container.

        To add elements to the returned container, you can use ``with`` notation
        (preferred) or just call methods directly on the returned object. See the
        examples below.

        Parameters
        ----------
        name : "user", "assistant", "ai", "human", or str
            The name of the message author. Can be "human"/"user" or
            "ai"/"assistant" to enable preset styling and avatars.

            Currently, the name is not shown in the UI but is only set as an
            accessibility label. For accessibility reasons, you should not use
            an empty string.

        avatar : Anything supported by st.image (except list), str, or None
            The avatar shown next to the message.

            If ``avatar`` is ``None`` (default), the icon will be determined
            from ``name`` as follows:

            - If ``name`` is ``"user"`` or ``"human"``, the message will have a
              default user icon.

            - If ``name`` is ``"ai"`` or ``"assistant"``, the message will have
              a default bot icon.

            - For all other values of ``name``, the message will show the first
              letter of the name.

            In addition to the types supported by |st.image|_ (except list),
            the following strings are valid:

            - A single-character emoji. For example, you can set ``avatar="🧑‍💻"``
              or ``avatar="🦖"``. Emoji short codes are not supported.

            - An icon from the Material Symbols library (rounded style) in the
              format ``":material/icon_name:"`` where "icon_name" is the name
              of the icon in snake case.

              For example, ``icon=":material/thumb_up:"`` will display the
              Thumb Up icon. Find additional icons in the `Material Symbols \
              <https://fonts.google.com/icons?icon.set=Material+Symbols&icon.style=Rounded>`_
              font library.

            .. |st.image| replace:: ``st.image``
            .. _st.image: https://docs.streamlit.io/develop/api-reference/media/st.image

        Returns
        -------
        Container
            A single container that can hold multiple elements.

        Examples
        --------
        You can use ``with`` notation to insert any element into an expander

        >>> import streamlit as st
        >>> import numpy as np
        >>>
        >>> with st.chat_message("user"):
        ...     st.write("Hello 👋")
        ...     st.line_chart(np.random.randn(30, 3))

        .. output ::
            https://doc-chat-message-user.streamlit.app/
            height: 450px

        Or you can just call methods directly in the returned objects:

        >>> import streamlit as st
        >>> import numpy as np
        >>>
        >>> message = st.chat_message("assistant")
        >>> message.write("Hello human")
        >>> message.bar_chart(np.random.randn(30, 3))

        .. output ::
            https://doc-chat-message-user1.streamlit.app/
            height: 450px

        """
        ...
    
    @overload
    def chat_input(self, placeholder: str = ..., *, key: Key | None = ..., max_chars: int | None = ..., accept_file: Literal[False] = ..., file_type: str | Sequence[str] | None = ..., disabled: bool = ..., on_submit: WidgetCallback | None = ..., args: WidgetArgs | None = ..., kwargs: WidgetKwargs | None = ...) -> str | None:
        ...
    
    @overload
    def chat_input(self, placeholder: str = ..., *, key: Key | None = ..., max_chars: int | None = ..., accept_file: Literal[True, "multiple"], file_type: str | Sequence[str] | None = ..., disabled: bool = ..., on_submit: WidgetCallback | None = ..., args: WidgetArgs | None = ..., kwargs: WidgetKwargs | None = ...) -> ChatInputValue | None:
        ...
    
    @gather_metrics("chat_input")
    def chat_input(self, placeholder: str = ..., *, key: Key | None = ..., max_chars: int | None = ..., accept_file: bool | Literal["multiple"] = ..., file_type: str | Sequence[str] | None = ..., disabled: bool = ..., on_submit: WidgetCallback | None = ..., args: WidgetArgs | None = ..., kwargs: WidgetKwargs | None = ...) -> str | ChatInputValue | None:
        """Display a chat input widget.

        Parameters
        ----------
        placeholder : str
            A placeholder text shown when the chat input is empty. This
            defaults to ``"Your message"``. For accessibility reasons, you
            should not use an empty string.

        key : str or int
            An optional string or integer to use as the unique key for the widget.
            If this is omitted, a key will be generated for the widget based on
            its content. No two widgets may have the same key.

        max_chars : int or None
            The maximum number of characters that can be entered. If this is
            ``None`` (default), there will be no maximum.

        accept_file : bool or str
            Whether the chat input should accept files. This can be one of the
            following values:

            - ``False`` (default): No files are accepted and the user can only
              submit a message.
            - ``True``: The user can add a single file to their submission.
            - ``"multiple"``: The user can add multiple files to their
              submission.

            When the widget is configured to accept files, the accepted file
            types can be configured with the ``file_type`` parameter.

            By default, uploaded files are limited to 200 MB each. You can
            configure this using the ``server.maxUploadSize`` config option.
            For more information on how to set config options, see
            |config.toml|_.

            .. |config.toml| replace:: ``config.toml``
            .. _config.toml: https://docs.streamlit.io/develop/api-reference/configuration/config.toml

        file_type : str, Sequence[str], or None
            The allowed file extension(s) for uploaded files. This can be one
            of the following types:

            - ``None`` (default): All file extensions are allowed.
            - A string: A single file extension is allowed. For example, to
              only accept CSV files, use ``"csv"``.
            - A sequence of strings: Multiple file extensions are allowed. For
              example, to only accept JPG/JPEG and PNG files, use
              ``["jpg", "jpeg", "png"]``.

        disabled : bool
            Whether the chat input should be disabled. This defaults to
            ``False``.

        on_submit : callable
            An optional callback invoked when the chat input's value is submitted.

        args : tuple
            An optional tuple of args to pass to the callback.

        kwargs : dict
            An optional dict of kwargs to pass to the callback.

        Returns
        -------
        None, str, or dict-like
            The user's submission. This is one of the following types:

            - ``None``: If the user didn't submit a message or file in the last
              rerun, the widget returns ``None``.
            - A string: When the widget is not configured to accept files and
              the user submitted a message in the last rerun, the widget
              returns the user's message as a string.
            - A dict-like object: When the widget is configured to accept files
              and the user submitted a message and/or file(s) in the last
              rerun, the widget returns a dict-like object with two attributes,
              ``text`` and ``files``.

            When the widget is configured to accept files and the user submits
            something in the last rerun, you can access the user's submission
            with key or attribute notation from the dict-like object. This is
            shown in Example 3 below.

            The ``text`` attribute holds a string, which is the user's message.
            This is an empty string if the user only submitted one or more
            files.

            The ``files`` attribute holds a list of UploadedFile objects.
            The list is empty if the user only submitted a message. Unlike
            ``st.file_uploader``, this attribute always returns a list, even
            when the widget is configured to accept only one file at a time.

            The UploadedFile class is a subclass of BytesIO, and therefore is
            "file-like". This means you can pass an instance of it anywhere a
            file is expected.

        Examples
        --------
        **Example 1: Pin the chat input widget to the bottom of your app**

        When ``st.chat_input`` is used in the main body of an app, it will be
        pinned to the bottom of the page.

        >>> import streamlit as st
        >>>
        >>> prompt = st.chat_input("Say something")
        >>> if prompt:
        ...     st.write(f"User has sent the following prompt: {prompt}")

        .. output ::
            https://doc-chat-input.streamlit.app/
            height: 350px

        **Example 2: Use the chat input widget inline**

        The chat input can also be used inline by nesting it inside any layout
        container (container, columns, tabs, sidebar, etc) or fragment. Create
        chat interfaces embedded next to other content, or have multiple
        chatbots!

        >>> import streamlit as st
        >>>
        >>> with st.sidebar:
        >>>     messages = st.container(height=300)
        >>>     if prompt := st.chat_input("Say something"):
        >>>         messages.chat_message("user").write(prompt)
        >>>         messages.chat_message("assistant").write(f"Echo: {prompt}")

        .. output ::
            https://doc-chat-input-inline.streamlit.app/
            height: 350px

        **Example 3: Let users upload files**

        When you configure your chat input widget to allow file attachments, it
        will return a dict-like object when the user sends a submission. You
        can access the user's message through the ``text`` attribute of this
        dictionary. You can access a list of the user's submitted file(s)
        through the ``files`` attribute. Similar to ``st.session_state``, you
        can use key or attribute notation.

        >>> import streamlit as st
        >>>
        >>> prompt = st.chat_input(
        >>>     "Say something and/or attach an image",
        >>>     accept_file=True,
        >>>     file_type=["jpg", "jpeg", "png"],
        >>> )
        >>> if prompt and prompt.text:
        >>>     st.markdown(prompt.text)
        >>> if prompt and prompt["files"]:
        >>>     st.image(prompt["files"][0])

        .. output ::
            https://doc-chat-input-file-uploader.streamlit.app/
            height: 350px

        """
        ...
    
    @property
    def dg(self) -> DeltaGenerator:
        """Get our DeltaGenerator."""
        ...
    


