"""

    AUTHOR:

        Khushal P Soonderji

    DATE:

        Monday, 30th Dec., 2024

    OBJECTIVE:

        To handle paper trading accounts from here.

    REFERENCES:

        N/A

    DOWNLOADS:

        N/A

"""


#   *****************************************************************************************************************
#  *****                                                                                                          ****
# ***                                                   IMPORT                                                      ***
#  *****                                                                                                          ****
#   *****************************************************************************************************************


# To make sibling directories accessible for imports:
import sys
sys.path.append(".")
sys.path.append("..")

# My async utils:
from utils_v2.string import json
from utils_v2.database.async_mysql_v2 import AsyncMySQL
from utils_v2.database.async_mongo_v2 import AsyncMongo
from utils_v2.cache.async_redis_cache_v2 import AsyncRedisCache

# Controllers:
from controllers_v2.finstitutions.trading.base import TradingController

# Models:
from models.core.auth_token import CoreAuthTokenModel
from utils_v2.trading.zerodha_kite.models.auth_tokens import ZerodhaKiteAuthTokens
from models.api.finstitutions.trading.symbols.list import TradingSymbolListRequestData
from models.finstitutions.trading.symbols import TradingSymbolListBrokerResponse, TradingSymbol
from models.finstitutions.trading.oauth import TradingOAuthCallbackResponse

# To work with MongoDB:
from bson.objectid import ObjectId

# To work with datatypes:
from typing import List, Any

# To make HTTP requests:
import httpx

# To work with Zerodha's Kite platform:
from kiteconnect import KiteConnect

# To handle exceptions:
from pydantic import ValidationError


#   *****************************************************************************************************************
#  *****                                                                                                          ****
# ***                                           MACROS / ONE-TIME INIT                                              ***
#  *****                                                                                                          ****
#   *****************************************************************************************************************


# --- Nothing Yet


#   *****************************************************************************************************************
#  *****                                                                                                          ****
# ***                                                VARIABLES                                                      ***
#  *****                                                                                                          ****
#   *****************************************************************************************************************


# --- Nothing Yet


#   *****************************************************************************************************************
#  *****                                                                                                          ****
# ***                                                  FUNCTIONS                                                    ***
#  *****                                                                                                          ****
#   *****************************************************************************************************************


# --- Nothing Yet


#   *****************************************************************************************************************
#  *****                                                                                                          ****
# ***                                                   CLASSES                                                     ***
#  *****                                                                                                          ****
#   *****************************************************************************************************************


class PaperTradingController(TradingController):

    # ┏┓┓      ┓┏
    # ┃ ┃┏┓┏┏  ┃┃┏┓┏┓┏
    # ┗┛┗┗┻┛┛  ┗┛┗┻┛ ┛

    CLIENT_NAME = "paperTrading"

    # ┏┓
    # ┃ ┏┓┏┓┏╋┏┓┓┏┏╋┏┓┏┓
    # ┗┛┗┛┛┗┛┗┛ ┗┻┗┗┗┛┛

    def __init__(
            self,
            cache: AsyncRedisCache = None,
            http_client: httpx.AsyncClient = None,
            alert_url: str = None,
            debug: bool = True,
            debug_prefix: str = "Paper Trading (C) | ",
            debug_only_errors: bool = True
    ):

        """
        This is the foundational controller for Zerodha's Kite platform.
        :param cache: The object to use for caching results from database calls.
        :param http_client: The HTTP client
        :param debug: Whether, or not, you would like to print debugging messages:
        :param debug_prefix: The prefix to print with the debugging messages.
        :param debug_only_errors: Whether you would like to print only error messages or all messages.
        :return: None.
        """

        # Prepare base filter:
        this_filter = {"client": self.CLIENT_NAME}

        # Invoke the parent's constructor:
        super().__init__(
            cache = cache,
            alert_url = alert_url,
            http_client = http_client,
            base_filter = this_filter,
            debug = debug,
            debug_prefix = debug_prefix,
            debug_only_errors = debug_only_errors
        )

        # Init a variable in a parent:
        self._client = self.CLIENT_NAME

    # ┏┓   ┓
    # ┣┫┓┏╋┣┓
    # ┛┗┗┻┗┛┗

    @staticmethod
    async def get_authorization_url(
            **kwargs
    ) -> str:

        """
        To generate an authorization URL for this broker.
        :param kwargs: Any no. of things needed by your broker to generate the URL.
        :return: The authorization URL.
        """

        raise NotImplementedError

    async def handle_authorization_callback(
            self,
            sql_conn: AsyncMySQL,
            mongo_data_conn: AsyncMongo,
            inbound_data: dict,
            client_user_id: str
    ) -> TradingOAuthCallbackResponse:

        """
        Not needed for paper trading.
        :param sql_conn: The database connection to use to perform this activity.
        :param mongo_data_conn: The database connection to use to perform this activity.
        :param inbound_data: The data that came in from the broker. This could be in the JSON body, query params, etc.
        :param client_user_id: How the trading client identifies this user.
        :return: A structured response to capture the process of callback handling.
        """

        raise NotImplementedError

    # ┏┳┓     ┓•      ┏┓     ┓   ┓
    #  ┃ ┏┓┏┓┏┫┓┏┓┏┓  ┗┓┓┏┏┳┓┣┓┏┓┃┏
    #  ┻ ┛ ┗┻┗┻┗┛┗┗┫  ┗┛┗┫┛┗┗┗┛┗┛┗┛
    #              ┛     ┛

    async def list_symbols(
            self,
            mongo_data_conn: AsyncMongo,
            auth_token: CoreAuthTokenModel,
            inbound_data: TradingSymbolListRequestData
    ) -> TradingSymbolListBrokerResponse:

        """
        Not needed for paper trading.
        :param mongo_data_conn: The database connection to use to perform this activity.
        :param auth_token: The token that has to be used to fetch the data.
        :param inbound_data: The data that came in with the APi call.
        :return: The structured response form the broker.
        """

        raise NotImplementedError


#   *****************************************************************************************************************
#  *****                                                                                                          ****
# ***                                               MAIN PROGRAM                                                    ***
#  *****                                                                                                          ****
#   *****************************************************************************************************************


if __name__ == "__main__":

    pass
