from datetime import datetime

from actions_logging.app_logging import logger
from common.common import raise_with_context
from deepmerge import Merger
from dacite import from_dict
from github.env import exit_on_error_and_write_summary
from jira.jira_apis import (create_jira_ticket_from_payload,
                            get_git_info_from_ticket, get_jira_ticket,
                            get_latest_jira_user)
from jira.models import *


def get_jira_ticket_info(ticket_id) -> JiraTicket:
    try:
        logger.info(f"get ticket info for ticket {ticket_id}")
        ticket_res = get_jira_ticket(ticket_id)
        logger.debug("ticket info: ")
        logger.debug(ticket_res)
        ticket: JiraTicket = from_dict(data_class=JiraTicket, data=ticket_res)
        return ticket
    except Exception as e:
        exit_on_error_and_write_summary(f"failed in get_jira_ticket_info: {e}")


def get_branch_info(branches, ticket_id):
    try:
        if not branches:
            return
        for branch in branches:
            if ticket_id in branch['name']:
                logger.info_green(f"branch {branch} found")
                return branch
    except Exception as e:
        logger.error(f"error in get branch info: {e}")
        return None


def get_git_info_from_jira(issue_id, ticket_id) -> bool:
    try:
        logger.info(f"get git info from jira for issue {issue_id}")
        res_json = get_git_info_from_ticket(issue_id)
        branches_list = res_json["detail"]
        if len(branches_list) == 0:
            return False
        if len(res_json["detail"][0]["branches"]) == 1:
            return True
        else:
            if get_branch_info(res_json["detail"][0]["branches"], ticket_id):
                return True
        return False
    except Exception as e:
        logger.error(f"from get git info from jira {e}")
        return False


def get_jira_user():
    """
    used for backward compatibility for platform jira check
    :return:
    """
    try:
        get_latest_jira_user()
    except Exception as e:
        logger.error(f"get user error {e}")


def create_jira_ticket(summary: str, description: str, project_key: str = "P81", issue_type="Task", payload_overrides: dict = None):
    """
    Create a Jira ticket with the given summary, description, project key, and issue type.

    :param summary: The summary of the Jira ticket.
    :param description: The description of the Jira ticket.
    :param project_key: The project key for the Jira ticket. Default is "P81".
    :param issue_type: The issue type for the Jira ticket. Default is "Task".
    :param payload_overrides: Optional overrides for the payload.
    :return: The ID of the created Jira ticket.
    """
    try:
        payload = {
            "fields": {
                "project": {
                    "key": project_key
                },
                "summary": summary,
                "description": {
                    "type": "doc",
                    "version": 1,
                    "content": [{
                        "type": "paragraph",
                        "content": [{
                            "text": description,
                            "type": "text"
                        }]
                    }]
                },
                "issuetype": {
                    "name": issue_type
                }
            }
        }


        if payload_overrides:
            merger = Merger(
                # Merge dicts
                [
                    (dict, ["merge"]),
                ],
                # Override other types
                ["override"],
                # Override on type conflict
                ["override"]
            )
            payload = merger.merge(payload, payload_overrides)

        return create_jira_ticket_from_payload(payload)
    except Exception as e:
        raise_with_context(e)

def calculate_current_designated_q() -> str:
    """
    Calculate the current designated Q based on the current date in the convention expected in Jira (e.g. 2025-Q2).

    :return: The current designated Q as a string (e.g., "Q1", "Q2", "Q3", "Q4").
    """
    try:
        current_date = datetime.now()
        year = current_date.year
        month = current_date.month
        if month in [1, 2, 3]:
            quarter = 1
        elif month in [4, 5, 6]:
            quarter = 2
        elif month in [7, 8, 9]:
            quarter = 3
        else:
            quarter = 4
        return f"{year}-Q{quarter}"
    except Exception as e:
        raise_with_context(e)
