import json

import requests
from actions_logging.app_logging import logger
from common.common import raise_with_context
from github.env import exit_on_error_and_write_summary, get_required_env_var
from jira.consts import JIRA_API_URL, JIRA_REST_URL, SVC_USER


def create_auth_and_headers(jira_user=None, jira_token=None):
    if not jira_user:
        jira_user = SVC_USER
    if not jira_token:
        jira_token = get_required_env_var('GLOBAL_CICD_JIRA_TOKEN')
    jira_auth = (jira_user, jira_token)
    jira_headers = {
        "Content-Type": "application/json"
    }
    return jira_headers, jira_auth


def get_jira_ticket(ticket_id):
    try:
        logger.info(f"API request to get ticket info for ticket {ticket_id}")
        jira_headers, jira_auth = create_auth_and_headers()
        url = f"{JIRA_API_URL}/issue"
        res = requests.get(f"{url}/{ticket_id}", headers=jira_headers, auth=jira_auth)
        res.raise_for_status()
        logger.debug("ticket info: ")
        logger.debug(res.json())
        res_json = res.json()
        return res_json
    except requests.exceptions.HTTPError as http_err:
        exit_on_error_and_write_summary(f'HTTP error occurred in get_jira_ticket_info: {http_err}')
    except Exception as e:
        exit_on_error_and_write_summary(f"failed in get_jira_ticket_info: {e}")


def get_git_info_from_ticket(issue_id):
    try:
        logger.info(f"API request to get git info from jira for issue {issue_id}")
        jira_headers, jira_auth = create_auth_and_headers()
        jira_url = f"{JIRA_REST_URL}/dev-status/latest/issue/details?issueId={issue_id}&applicationType=GitHub&dataType=repository"
        res = requests.get(jira_url, headers=jira_headers, auth=jira_auth)
        res.raise_for_status()
        return res.json()
    except requests.exceptions.HTTPError as http_err:
        exit_on_error_and_write_summary(f'HTTP error occurred in get_git_info_from_jira: {http_err}')
    except Exception as e:
        exit_on_error_and_write_summary(f"failed in get_git_info_from_jira: {e}")


def get_latest_jira_user() -> None:
    try:
        logger.info(f"API request to get user info")
        url = f"{JIRA_REST_URL}/auth/latest/session"
        jira_headers, jira_auth = create_auth_and_headers()
        res = requests.get(f"{url}", headers=jira_headers, auth=jira_auth)
        res.raise_for_status()
        logger.info_green("get_jira_user:")
        logger.info_green(res.json())
    except Exception as e:
        logger.error(f"get user error {e}")


def update_issue(ticket_id, payload):
    try:
        logger.info("API request to update issue")
        jira_headers, jira_auth = create_auth_and_headers()
        url = f"{JIRA_API_URL}/issue/{ticket_id}"
        response = requests.put(url, json=payload, headers=jira_headers, auth=jira_auth)
        response.raise_for_status()
    except requests.exceptions.HTTPError as http_err:
        exit_on_error_and_write_summary(f'HTTP error occurred in update_issue: {http_err}')
    except Exception as e:
        exit_on_error_and_write_summary(f"failed in update_issue: {e}")


def create_jira_ticket_from_payload(payload: dict) -> str:
    """
    Create a Jira ticket using the provided payload.

    :param payload: The payload containing the ticket details.
    :return: The ID of the created ticket.
    """
    try:
        url = f"{JIRA_API_URL}/issue"

        jira_headers, jira_auth = create_auth_and_headers()

        if not payload:
            raise_with_context(None, ValueError, "Cannot create Jira ticket: Payload is empty")

        logger.debug(f"Payload for creating Jira ticket: {payload}")
        response = requests.post(url, data=json.dumps(payload), headers=jira_headers, auth=jira_auth)

        if response.status_code == 201:
            jira_ticket_id = response.json()["key"]
            logger.info(f"Created Jira ticket {jira_ticket_id}")
            return jira_ticket_id
        else:
            raise_with_context(None, RuntimeError, f"Failed to create ticket: {response.status_code} - {response.text}")

    except requests.exceptions.HTTPError as http_err:
        raise_with_context(http_err, requests.exceptions.HTTPError)
    except Exception as e:
        raise_with_context(e, Exception)
