# from _rest import AsyncHTTPClient, SyncHTTPClient
import asyncio
import os
from typing import Optional
from qyrusai._rest import AsyncHTTPClient, SyncHTTPClient
from qyrusai.configs import Configurations
from qyrusai._types import CreateScenariosResponse, JiraDetails
from urllib.parse import urljoin


class AsyncNovaJira:

    def __init__(self, api_key: str):
        self.api_key = api_key
        # token_valid = asyncio.run(Configurations.verifyToken(api_key)) # If True is stored, well and good otherwise an Exception will have been raised already if something goes wrong.
        token_valid = Configurations.verifyToken(api_key) # If True is stored, well and good otherwise an Exception will have been raised already if something goes wrong.
        if not token_valid:
            raise Exception("401")
        gatewayDetails = Configurations.getDefaultGateway(api_key)
        # gatewayDetails = asyncio.run(Configurations.getDefaultGateway(api_key))
        self.base_url = gatewayDetails.get("gatewayUrl")
        self.gateway_token = gatewayDetails.get("gatewayToken")

    async def create(self, jira_endpoint: str,
                                      jira_api_token: str, jira_username: str,
                                      jira_id: str) -> CreateScenariosResponse:
        
        """Creates Test Scenarios using a JIRA ID
        Connects to a JIRA instance using provided credentials and domain URL, then generates test scenarios based on the specified JIRA Ticket ID.

        Args:
            jira_details (JiraDetails): A model containing the parameters
                required for connecting to JIRA.

        Returns:
            CreateScenariosResponse: A model representing the response of the operation with
                the success status, message, and a list of scenarios if successful.
        """
        # print(jira_api_token, jira_endpoint, jira_id, jira_username)
        
        # Join the base URL and the context path
        url = urljoin(self.base_url,Configurations.getNovaContextPath("jira"))

        data = {
            "jira_endpoint": jira_endpoint,
            "jira_api_token": jira_api_token,
            "jira_username": jira_username,
            "jira_id": jira_id
        }
        
        # JiraDetails.validate(data)
        headers = {
            'Content-Type': 'application/json',
            'Authorization': f"Bearer "+self.gateway_token,
            'Custom': self.api_key
        }

        async_client = AsyncHTTPClient()
        response_data = await async_client.post(url, data, headers)
        # print(f"response_data (createScenariosFromJira) : {response_data}")
        # print(
        #     f"response_data (createScenariosFromJira) TYPE == >> : {type(response_data)}"
        # )

        return CreateScenariosResponse(**response_data)
        
class SyncNovaJira:

    def __init__(self, api_key: str):
        self.api_key = api_key
        # token_valid = asyncio.run(Configurations.verifyToken(api_key)) # If True is stored, well and good otherwise an Exception will have been raised already if something goes wrong.
        token_valid = Configurations.verifyToken(api_key) # If True is stored, well and good otherwise an Exception will have been raised already if something goes wrong.
        if not token_valid:
            raise Exception("401")
        gatewayDetails = Configurations.getDefaultGateway(api_key)
        # gatewayDetails = asyncio.run(Configurations.getDefaultGateway(api_key))
        self.base_url = gatewayDetails.get("gatewayUrl")
        self.gateway_token = gatewayDetails.get("gatewayToken")

    def create(self, jira_endpoint: str,
                                      jira_api_token: str, jira_username: str,
                                      jira_id: str) -> CreateScenariosResponse:
        """Creates Test Scenarios using a JIRA ID
        Connects to a JIRA instance using provided credentials and domain URL, then generates test scenarios based on the specified JIRA Ticket ID.

        Args:
            jira_details (JiraDetails): A model containing the parameters
                required for connecting to JIRA.

        Returns:
            CreateScenariosResponse: A model representing the response of the operation with
                the success status, message, and a list of scenarios if successful.
        """
        # print(jira_api_token, jira_endpoint, jira_id, jira_username)
        
        # Join the base URL and the context path
        url = urljoin(self.base_url,Configurations.getNovaContextPath("jira"))

        data = {
            "jira_endpoint": jira_endpoint,
            "jira_api_token": jira_api_token,
            "jira_username": jira_username,
            "jira_id": jira_id
        }
        
        # JiraDetails.validate(data)
        headers = {
            'Content-Type': 'application/json',
            'Authorization': "Bearer "+self.gateway_token,
            'Custom': self.api_key
        }  # Headers if required

        sync_client = SyncHTTPClient()
        response_data = sync_client.post(url, data, headers)
        # print(f"response_data (createScenariosFromJira) : {response_data}")
        # print(
        #     f"response_data (createScenariosFromJira) TYPE == >> : {type(response_data)}"
        # )

        return CreateScenariosResponse(**response_data)


class AsyncNovaUserDescription:

    def __init__(self, api_key: str):
        self.api_key = api_key
        # token_valid = asyncio.run(Configurations.verifyToken(api_key)) # If True is stored, well and good otherwise an Exception will have been raised already if something goes wrong.
        token_valid = Configurations.verifyToken(api_key) # If True is stored, well and good otherwise an Exception will have been raised already if something goes wrong.
        if not token_valid:
            raise Exception("401")
        gatewayDetails = Configurations.getDefaultGateway(api_key)
        # gatewayDetails = asyncio.run(Configurations.getDefaultGateway(api_key))
        self.base_url = gatewayDetails.get("gatewayUrl")
        self.gateway_token = gatewayDetails.get("gatewayToken")

    async def create(self, user_description: str) -> CreateScenariosResponse:
        """Creates Test Scenarios using a User Description.
        
        Args:
            user_description (str): A description by user to create test scenarios.

        Returns:
             CreateScenariosResponse: A model representing the response of the operation with
                the success status, message, and a list of scenarios if successful.
        """

        url = urljoin(self.base_url,Configurations.getNovaContextPath("user"))
        
        data = {
            "user_description": user_description,
        }
        
        headers = {
            'Content-Type': 'application/json',
            "Authorization": "Bearer "+self.gateway_token,
            "Custom": self.api_key
        }  
        
        async_client = AsyncHTTPClient()
        response_data = await async_client.post(url, data, headers)
        # print("📁.....", response_data)
        return CreateScenariosResponse(**response_data)
        
class SyncNovaUserDescription:
    def __init__(self, api_key: str):
        self.api_key = api_key
        # token_valid = asyncio.run(Configurations.verifyToken(api_key)) # If True is stored, well and good otherwise an Exception will have been raised already if something goes wrong.
        token_valid = Configurations.verifyToken(api_key) # If True is stored, well and good otherwise an Exception will have been raised already if something goes wrong.
        if not token_valid:
            raise Exception("401")
        gatewayDetails = Configurations.getDefaultGateway(api_key)
        # gatewayDetails = asyncio.run(Configurations.getDefaultGateway(api_key))
        self.base_url = gatewayDetails.get("gatewayUrl")
        self.gateway_token = gatewayDetails.get("gatewayToken")


    def create(self, user_description: str) -> CreateScenariosResponse:
        """Creates Test Scenarios using a User Description.
        
        Args:
            user_description (str): A description by user to create test scenarios.

        Returns:
            CreateScenariosResponse: A model representing the response of the operation with
                the success status, message, and a list of scenarios if successful.
        """

        url = urljoin(self.base_url,Configurations.getNovaContextPath("user"))
        
        data = {
            "user_description": user_description,
        }
        
        headers = {
            'Content-Type': 'application/json',
            "Custom": self.api_key,
            "Authorization": "Bearer "+self.gateway_token
        }  # Headers if required
        sync_client = SyncHTTPClient()
        response_data = sync_client.post(url, data, headers)
        # print("📁.....", response_data)
        return CreateScenariosResponse(**response_data)
