"""
Binance Derivatives Trading Options WebSocket Market Streams

OpenAPI Specification for the Binance Derivatives Trading Options WebSocket Market Streams
The version of the OpenAPI document: 1.0.0
Generated by OpenAPI Generator (https://openapi-generator.tech)

Do not edit the class manually.
"""

from pydantic import BaseModel
from typing import Callable, Optional, TypeVar, Union

from binance_common.configuration import ConfigurationWebSocketStreams
from binance_common.websocket import (
    WebSocketStreamBase,
    WebSocketConnection,
    RequestStreamHandle,
    RequestStream,
)

from .models import UserDataStreamEventsResponse


from .streams.websocket_market_streams_api import WebsocketMarketStreamsApi


T = TypeVar("T", bound=BaseModel)


class DerivativesTradingOptionsWebSocketStreams(WebSocketStreamBase):
    def __init__(
        self,
        configuration: ConfigurationWebSocketStreams,
    ) -> None:

        super().__init__(configuration, True)
        self.configuration = configuration

        self._websocketMarketStreamsApi = WebsocketMarketStreamsApi(self)

    async def ping_server(self, connection: WebSocketConnection):
        """Sends a ping message to the WebSocket server to check the connection status.

        Args:
            connection (WebSocketConnection): The WebSocket connection to send the ping message to.
        """

        if self.session:
            await super().ping_ws_stream(connection=connection)
        else:
            raise ValueError("WebSocket session is not initialized.")

    async def subscribe(self, streams, response_model: Optional[T] = None):
        """Subscribes to the specified WebSocket streams.

        Args:
            streams (list): A list of WebSocket streams to subscribe to.
            response_model (Optional[T]): The Pydantic model to validate the response against.
        """

        await super().subscribe(streams, response_model=response_model)

    async def unsubscribe(self, streams):
        """Unsubscribes from the specified WebSocket streams.

        Args:
            streams (list): A list of WebSocket streams to unsubscribe from.
        """

        await super().unsubscribe(streams)

    def on(self, event: str, callback: Callable[[T], None], stream: str):
        """Registers a callback function for a specific WebSocket event.

        Args:
            event (str): The event type to listen for (e.g., 'message', 'error').
            callback (Callable[[T], None]): The callback function to be called when the event occurs.
            stream (str): The specific WebSocket stream to listen to.
        """

        super().on(event, callback, stream)

    async def list_subscribe(self) -> dict:
        """Lists all currently subscribed WebSocket streams.

        Returns:
            dict: A dictionary containing the current subscriptions.
        """

        return await super().list_subscribe()

    async def close_connection(
        self, connection: WebSocketConnection = None, close_session: bool = True
    ):
        """Closes the WebSocket connection and optionally the session.

        Args:
            connection (WebSocketConnection, optional): The WebSocket connection to close. If None, the current session's connection is used.
            close_session (bool, optional): Whether to close the session after closing the connection. Defaults to True.
        """

        await super().close_connection(connection, close_session)

    async def user_data(self, listenKey: str) -> RequestStreamHandle:
        """Subscribe to User Data Stream (USER_STREAM)

        Args:
            listenKey (str): The listen key for the user data stream.
        Returns:
            RequestStreamHandle: An instance of RequestStream that provides the on() and unsubscribe() methods.
        """

        return await RequestStream(
            self, listenKey, response_model=UserDataStreamEventsResponse
        )

    async def index_price_streams(
        self,
        symbol: Union[str, None],
        id: Optional[int] = None,
    ) -> RequestStreamHandle:
        r"""
                Index Price Streams

                Underlying(e.g ETHUSDT) index stream.

        Update Speed: 1000ms

                Args:
                    symbol (Union[str, None]): The symbol parameter
                    id (Optional[int] = None): Unique WebSocket request ID.

                Returns:
                    RequestStreamHandle

                Raises:
                    RequiredError: If a required parameter is missing.

        """

        return await self._websocketMarketStreamsApi.index_price_streams(symbol, id)

    async def kline_candlestick_streams(
        self,
        symbol: Union[str, None],
        interval: Union[str, None],
        id: Optional[int] = None,
    ) -> RequestStreamHandle:
        r"""
                Kline/Candlestick Streams

                The Kline/Candlestick Stream push updates to the current klines/candlestick every 1000 milliseconds (if existing).

        Update Speed: 1000ms

                Args:
                    symbol (Union[str, None]): The symbol parameter
                    interval (Union[str, None]): The interval parameter
                    id (Optional[int] = None): Unique WebSocket request ID.

                Returns:
                    RequestStreamHandle

                Raises:
                    RequiredError: If a required parameter is missing.

        """

        return await self._websocketMarketStreamsApi.kline_candlestick_streams(
            symbol, interval, id
        )

    async def mark_price(
        self,
        underlying_asset: Union[str, None],
        id: Optional[int] = None,
    ) -> RequestStreamHandle:
        r"""
                Mark Price

                The mark price for all option symbols on specific underlying asset. E.g.[ETH@markPrice](wss://nbstream.binance.com/eoptions/stream?streams=ETH@markPrice)

        Update Speed: 1000ms

                Args:
                    underlying_asset (Union[str, None]): The underlyingAsset parameter
                    id (Optional[int] = None): Unique WebSocket request ID.

                Returns:
                    RequestStreamHandle

                Raises:
                    RequiredError: If a required parameter is missing.

        """

        return await self._websocketMarketStreamsApi.mark_price(underlying_asset, id)

    async def new_symbol_info(
        self,
        id: Optional[int] = None,
    ) -> RequestStreamHandle:
        r"""
                New Symbol Info

                New symbol listing stream.

        Update Speed: 50ms

                Args:
                    id (Optional[int] = None): Unique WebSocket request ID.

                Returns:
                    RequestStreamHandle

                Raises:
                    RequiredError: If a required parameter is missing.

        """

        return await self._websocketMarketStreamsApi.new_symbol_info(id)

    async def open_interest(
        self,
        underlying_asset: Union[str, None],
        expiration_date: Union[str, None],
        id: Optional[int] = None,
    ) -> RequestStreamHandle:
        r"""
                Open Interest

                Option open interest for specific underlying asset on specific expiration date. E.g.[ETH@openInterest@221125](wss://nbstream.binance.com/eoptions/stream?streams=ETH@openInterest@221125)

        Update Speed: 60s

                Args:
                    underlying_asset (Union[str, None]): The underlyingAsset parameter
                    expiration_date (Union[str, None]): The expirationDate parameter
                    id (Optional[int] = None): Unique WebSocket request ID.

                Returns:
                    RequestStreamHandle

                Raises:
                    RequiredError: If a required parameter is missing.

        """

        return await self._websocketMarketStreamsApi.open_interest(
            underlying_asset, expiration_date, id
        )

    async def partial_book_depth_streams(
        self,
        symbol: Union[str, None],
        levels: Union[int, None],
        id: Optional[int] = None,
        update_speed: Optional[str] = None,
    ) -> RequestStreamHandle:
        r"""
                Partial Book Depth Streams

                Top **<levels\>** bids and asks, Valid levels are **<levels\>** are 10, 20, 50, 100.

        Update Speed: 100ms or 1000ms, 500ms(default when update speed isn't used)

                Args:
                    symbol (Union[str, None]): The symbol parameter
                    levels (Union[int, None]): The levels parameter
                    id (Optional[int] = None): Unique WebSocket request ID.
                    update_speed (Optional[str] = None): WebSocket stream update speed

                Returns:
                    RequestStreamHandle

                Raises:
                    RequiredError: If a required parameter is missing.

        """

        return await self._websocketMarketStreamsApi.partial_book_depth_streams(
            symbol, levels, id, update_speed
        )

    async def ticker24_hour(
        self,
        symbol: Union[str, None],
        id: Optional[int] = None,
    ) -> RequestStreamHandle:
        r"""
                24-hour TICKER

                24hr ticker info for all symbols. Only symbols whose ticker info changed will be sent.

        Update Speed: 1000ms

                Args:
                    symbol (Union[str, None]): The symbol parameter
                    id (Optional[int] = None): Unique WebSocket request ID.

                Returns:
                    RequestStreamHandle

                Raises:
                    RequiredError: If a required parameter is missing.

        """

        return await self._websocketMarketStreamsApi.ticker24_hour(symbol, id)

    async def ticker24_hour_by_underlying_asset_and_expiration_data(
        self,
        underlying_asset: Union[str, None],
        expiration_date: Union[str, None],
        id: Optional[int] = None,
    ) -> RequestStreamHandle:
        r"""
                24-hour TICKER by underlying asset and expiration data

                24hr ticker info by underlying asset and expiration date. E.g.[ETH@ticker@220930](wss://nbstream.binance.com/eoptions/stream?streams=ETH@ticker@220930)

        Update Speed: 1000ms

                Args:
                    underlying_asset (Union[str, None]): The underlyingAsset parameter
                    expiration_date (Union[str, None]): The expirationDate parameter
                    id (Optional[int] = None): Unique WebSocket request ID.

                Returns:
                    RequestStreamHandle

                Raises:
                    RequiredError: If a required parameter is missing.

        """

        return await self._websocketMarketStreamsApi.ticker24_hour_by_underlying_asset_and_expiration_data(
            underlying_asset, expiration_date, id
        )

    async def trade_streams(
        self,
        symbol: Union[str, None],
        id: Optional[int] = None,
    ) -> RequestStreamHandle:
        r"""
                Trade Streams

                The Trade Streams push raw trade information for specific symbol or underlying asset. E.g.[ETH@trade](wss://nbstream.binance.com/eoptions/stream?streams=ETH@trade)

        Update Speed: 50ms

                Args:
                    symbol (Union[str, None]): The symbol parameter
                    id (Optional[int] = None): Unique WebSocket request ID.

                Returns:
                    RequestStreamHandle

                Raises:
                    RequiredError: If a required parameter is missing.

        """

        return await self._websocketMarketStreamsApi.trade_streams(symbol, id)
