"""
Binance Derivatives Trading Portfolio Margin WebSocket Market Streams

OpenAPI Specification for the Binance Derivatives Trading Portfolio Margin 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

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

from .models import UserDataStreamEventsResponse


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


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

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

    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
        )
