"""

    AUTHOR:

        Khushal P Soonderji

    DATE:

        Friday, 6th Dec., 2024

    OBJECTIVE:

        To register a telegram bot with our system and send a request to Telegram to set it up the webhook.

    REFERENCES:

        N/A

    DOWNLOADS:

        N/A

    NOTES:

        N/A

"""


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


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

# For using Quart:
from quart import Blueprint, current_app, request, render_template

# My utils:
from utils_v2.string import json
from utils_v2.api.codes import StatusCodes, HttpCodes
from utils_v2.api.response import ResponseModel
from utils_v2.api.async_quart import (
    set_api_version,
    read_input,
    get_session_info,
    log_request_to_mongo,
    log_chain_to_mongo,
    should_not_be_under_maintenance,
    only_whitelisted_ips,
    limit_rate,
    validate_input,
    handle_cancelled_request
)

# Data Models:
from models.data.api.chat.auth import ChatAuthRequestHeaders, ChatAuthRequestData

# Common:
from shared import constants

# For asynchronous activities:
import asyncio

# For random choices:
import random


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


# Related to Quart:
chat_auth_bp = Blueprint("chat_auth_bp", __name__)


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


# --- Nothing Yet


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


@chat_auth_bp.record_once
def init(blueprint_setup_state):

    # This gets called when the blueprint is registered.
    # Consider this to be a one-time setup for the whole blueprint:
    pass


# ---------------------------------------------------------------------------------------------------------------------


async def set_telegram_webhook(
        bot_token: str,
        webhook_url: str
) -> dict:

    """
    To set a webhook to receive messages via a bot.
    :param bot_token: The token granted by BotFather when creating the bot.
    :param webhook_url: Your endpoint where you will receive messages that people send to your bot.
    :return: The JSON response from Telegram.
    """

    # Register the webhook with Telegram:
    api_response = await current_app.http_client.post(
        url = f"https://api.telegram.org/bot{bot_token}/setWebhook",
        data = {"url": webhook_url}
    )

    # Done here:
    return api_response.json()


# ---------------------------------------------------------------------------------------------------------------------


async def get_telegram_bot_info(
        bot_token: str,
) -> dict | None:

    """
    To get a bot's basic info.
    :param bot_token: The token granted by BotFather when creating the bot.
    :return: The JSON response from Telegram.
    """

    # Start by assuming failure:
    bot_info = None

    # Register the webhook with Telegram:
    api_response = await current_app.http_client.get(
        url = f"https://api.telegram.org/bot{bot_token}/getMe",
    )

    # If the call succeeds:
    if api_response.status_code in [200]:
        if api_response.json()["ok"]:
            api_result = api_response.json()["result"]
            bot_info = {
                "id": api_result["id"],
                "displayName": api_result["first_name"],
                "username": api_result["username"],
            }

    # Done here:
    return bot_info


# ---------------------------------------------------------------------------------------------------------------------


@chat_auth_bp.route("/auth", methods = ["POST"])
@set_api_version(api_version = "1.0.0")
@read_input(sanitize_headers = False, sanitize_data = False)
@get_session_info(key = "X-Session-Token", session_coro = "get_session")
@log_request_to_mongo(
    attr_name = "logs_mongo",
    project = constants.PROJECT_NAME,
    log_type = constants.MODULE_NAME,
    operation = "chatAuthApi",
    log_input = True,
    log_output = True,
    sensitive_keys = None
)
@log_chain_to_mongo(attr_name = "logs_mongo")
@should_not_be_under_maintenance(attr_name = "is_under_maintenance")
@validate_input(
    header_validator = lambda x: ChatAuthRequestHeaders(**x).model_dump(),
    data_validator = lambda x: ChatAuthRequestData(**x)
)
@handle_cancelled_request()
async def callback_test(
        inbound_headers: dict | ChatAuthRequestHeaders = None,
        inbound_data: dict | ChatAuthRequestData = None,
        inbound_files: dict = None,
        **kwargs
):

    # ┏┓
    # ┃┃┏┓┏┓┏┓┏┓┏┓┏┏┓┏┏
    # ┣┛┛ ┗ ┣┛┛ ┗┛┗┗ ┛┛
    #       ┛

    # If the session token is invalid/expired:
    if kwargs.get("session_info") is None:
        return ResponseModel(
            status_code = StatusCodes.FAILED,
            http_code = HttpCodes.UNAUTHORIZED
        )

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

    if inbound_data.chatClient == "telegram":

        # client_response = await get_telegram_bot_info(bot_token = inbound_data.auth.botToken)
        # print("TG BOT:", json.to_string(client_response))
        client_response = await set_telegram_webhook(
            bot_token = inbound_data.auth.botToken,
            webhook_url = f"https://api.thecaoffice.com/converse/chat/webhook/{inbound_data.auth.botToken}"
        )
        print("WEBHOOK JSON:", json.to_string(client_response))

    return "ok"


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


if __name__ == "__main__":

    pass
