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

from collections.abc import Iterator, KeysView, MutableMapping
from dataclasses import dataclass
from typing import Any, Final, TYPE_CHECKING, Union
from typing_extensions import TypeAlias
from streamlit.proto.WidgetStates_pb2 import WidgetState as WidgetStateProto, WidgetStates as WidgetStatesProto
from streamlit.runtime.state.common import RegisterWidgetResult, T, WidgetMetadata
from streamlit.runtime.state.query_params import QueryParams
from streamlit.runtime.stats import CacheStat, CacheStatsProvider
from streamlit.runtime.session_manager import SessionManager

if TYPE_CHECKING:
    ...
STREAMLIT_INTERNAL_KEY_PREFIX: Final = ...
SCRIPT_RUN_WITHOUT_ERRORS_KEY: Final = ...
@dataclass(frozen=True)
class Serialized:
    """A widget value that's serialized to a protobuf. Immutable."""
    value: WidgetStateProto
    ...


@dataclass(frozen=True)
class Value:
    """A widget value that's not serialized. Immutable."""
    value: Any
    ...


WState: TypeAlias = Union[Value, Serialized]
@dataclass
class WStates(MutableMapping[str, Any]):
    """A mapping of widget IDs to values. Widget values can be stored in
    serialized or deserialized form, but when values are retrieved from the
    mapping, they'll always be deserialized.
    """
    states: dict[str, WState] = ...
    widget_metadata: dict[str, WidgetMetadata[Any]] = ...
    def __repr__(self): # -> str:
        ...
    
    def __getitem__(self, k: str) -> Any:
        """Return the value of the widget with the given key.
        If the widget's value is currently stored in serialized form, it
        will be deserialized first.
        """
        ...
    
    def __setitem__(self, k: str, v: WState) -> None:
        ...
    
    def __delitem__(self, k: str) -> None:
        ...
    
    def __len__(self) -> int:
        ...
    
    def __iter__(self): # -> Generator[str, Any, None]:
        ...
    
    def keys(self) -> KeysView[str]:
        ...
    
    def items(self) -> set[tuple[str, Any]]:
        ...
    
    def values(self) -> set[Any]:
        ...
    
    def update(self, other: WStates) -> None:
        """Copy all widget values and metadata from 'other' into this mapping,
        overwriting any data in this mapping that's also present in 'other'.
        """
        ...
    
    def set_widget_from_proto(self, widget_state: WidgetStateProto) -> None:
        """Set a widget's serialized value, overwriting any existing value it has."""
        ...
    
    def set_from_value(self, k: str, v: Any) -> None:
        """Set a widget's deserialized value, overwriting any existing value it has."""
        ...
    
    def set_widget_metadata(self, widget_meta: WidgetMetadata[Any]) -> None:
        """Set a widget's metadata, overwriting any existing metadata it has."""
        ...
    
    def remove_stale_widgets(self, active_widget_ids: set[str], fragment_ids_this_run: list[str] | None) -> None:
        """Remove widget state for stale widgets."""
        ...
    
    def get_serialized(self, k: str) -> WidgetStateProto | None:
        """Get the serialized value of the widget with the given id.

        If the widget doesn't exist, return None. If the widget exists but
        is not in serialized form, it will be serialized first.
        """
        ...
    
    def as_widget_states(self) -> list[WidgetStateProto]:
        """Return a list of serialized widget values for each widget with a value."""
        ...
    
    def call_callback(self, widget_id: str) -> None:
        """Call the given widget's callback and return the callback's
        return value. If the widget has no callback, return None.

        If the widget doesn't exist, raise an Exception.
        """
        ...
    


@dataclass
class KeyIdMapper:
    """A mapping of user-provided keys to element IDs.
    It also maps element IDs to user-provided keys so that this reverse mapping
    does not have to be computed ad-hoc.
    All built-in dict-operations such as setting and deleting expect the key as the
    argument, not the element ID.
    """
    _key_id_mapping: dict[str, str] = ...
    _id_key_mapping: dict[str, str] = ...
    def __contains__(self, key: str) -> bool:
        ...
    
    def __setitem__(self, key: str, widget_id: Any) -> None:
        ...
    
    def __delitem__(self, key: str) -> None:
        ...
    
    @property
    def id_key_mapping(self) -> dict[str, str]:
        ...
    
    def set_key_id_mapping(self, key_id_mapping: dict[str, str]) -> None:
        ...
    
    def get_id_from_key(self, key: str, default: Any = ...) -> str:
        ...
    
    def get_key_from_id(self, widget_id: str) -> str:
        ...
    
    def update(self, other: KeyIdMapper) -> None:
        ...
    
    def clear(self): # -> None:
        ...
    
    def delete(self, key: str): # -> None:
        ...
    


@dataclass
class SessionState:
    """SessionState allows users to store values that persist between app
    reruns.

    Example
    -------
    >>> if "num_script_runs" not in st.session_state:
    ...     st.session_state.num_script_runs = 0
    >>> st.session_state.num_script_runs += 1
    >>> st.write(st.session_state.num_script_runs)  # writes 1

    The next time your script runs, the value of
    st.session_state.num_script_runs will be preserved.
    >>> st.session_state.num_script_runs += 1
    >>> st.write(st.session_state.num_script_runs)  # writes 2
    """
    _old_state: dict[str, Any] = ...
    _new_session_state: dict[str, Any] = ...
    _new_widget_state: WStates = ...
    _key_id_mapper: KeyIdMapper = ...
    query_params: QueryParams = ...
    def __repr__(self): # -> str:
        ...
    
    def clear(self) -> None:
        """Reset self completely, clearing all current and old values."""
        ...
    
    @property
    def filtered_state(self) -> dict[str, Any]:
        """The combined session and widget state, excluding keyless widgets."""
        ...
    
    def is_new_state_value(self, user_key: str) -> bool:
        """True if a value with the given key is in the current session state."""
        ...
    
    def __iter__(self) -> Iterator[Any]:
        """Return an iterator over the keys of the SessionState.
        This is a shortcut for `iter(self.keys())`.
        """
        ...
    
    def __len__(self) -> int:
        """Return the number of items in SessionState."""
        ...
    
    def __getitem__(self, key: str) -> Any:
        ...
    
    def __setitem__(self, user_key: str, value: Any) -> None:
        """Set the value of the session_state entry with the given user_key.

        If the key corresponds to a widget or form that's been instantiated
        during the current script run, raise a StreamlitAPIException instead.
        """
        ...
    
    def __delitem__(self, key: str) -> None:
        ...
    
    def set_widgets_from_proto(self, widget_states: WidgetStatesProto) -> None:
        """Set the value of all widgets represented in the given WidgetStatesProto."""
        ...
    
    def on_script_will_rerun(self, latest_widget_states: WidgetStatesProto) -> None:
        """Called by ScriptRunner before its script re-runs.

        Update widget data and call callbacks on widgets whose value changed
        between the previous and current script runs.
        """
        ...
    
    def on_script_finished(self, widget_ids_this_run: set[str]) -> None:
        """Called by ScriptRunner after its script finishes running.
         Updates widgets to prepare for the next script run.

        Parameters
        ----------
        widget_ids_this_run: set[str]
            The IDs of the widgets that were accessed during the script
            run. Any widget state whose ID does *not* appear in this set
            is considered "stale" and will be removed.
        """
        ...
    
    def get_widget_states(self) -> list[WidgetStateProto]:
        """Return a list of serialized widget values for each widget with a value."""
        ...
    
    def register_widget(self, metadata: WidgetMetadata[T], user_key: str | None) -> RegisterWidgetResult[T]:
        """Register a widget with the SessionState.

        Returns
        -------
        RegisterWidgetResult[T]
            Contains the widget's current value, and a bool that will be True
            if the frontend needs to be updated with the current value.
        """
        ...
    
    def __contains__(self, key: str) -> bool:
        ...
    
    def get_stats(self) -> list[CacheStat]:
        ...
    
    def maybe_check_serializable(self) -> None:
        """Verify that session state can be serialized, if the relevant config
        option is set.

        See `_check_serializable` for details.
        """
        ...
    


@dataclass
class SessionStateStatProvider(CacheStatsProvider):
    _session_mgr: SessionManager
    def get_stats(self) -> list[CacheStat]:
        ...
    


