import re
import itertools
from dataclasses import dataclass
from collections import defaultdict
from typing import Optional

import jira2markdown
from jira2markdown.elements import MarkupElements
from jira2markdown.markup.lists import UnorderedList, OrderedList
from jira2markdown.markup.text_effects import BlockQuote, Quote, Monospaced
from jira2markdown.markup.text_breaks import Ruler

from markup.lists import UnorderedTweakedList, OrderedTweakedList
from markup.text_effects import EscapeHtmlTag, TweakedBlockQuote, TweakedQuote, TweakedMonospaced
from markup.text_breaks import LongRuler


@dataclass
class Attachment(object):
    filename: str
    created: str
    content: str
    mime_type: str


def extract_summary(o: dict) -> str:
    return o.get("fields").get("summary", "")


def extract_description(o: dict) -> str:
    description = o.get("fields").get("description", "")
    return description if description else ""


def extract_status(o: dict) -> str:
    status = o.get("fields").get("status")
    return status.get("name", "") if status else ""


def extract_issue_type(o: dict) -> str:
    issuetype = o.get("fields").get("issuetype")
    return issuetype.get("name", "") if issuetype else ""


def extract_environment(o: dict) -> str:
    environment = o.get("fields").get("environment", "")
    return environment if environment else ""


def extract_resolution(o: dict) -> Optional[str]:
    resolution = o.get("fields").get("resolution")
    if resolution:
        return resolution.get("name")
    return None


def extract_priority(o: dict) -> Optional[str]:
    priority = o.get("fields").get("priority")
    if priority:
        return priority.get("name")
    return None


def extract_vote_count(o: dict) -> Optional[str]:
    votes = o.get("fields").get("votes")
    if votes:
        vote_count = votes.get("votes")
        if vote_count > 0:
            return vote_count
    return None


def extract_reporter(o: dict) -> tuple[str, str]:
    reporter = o.get("fields").get("reporter")
    name = reporter.get("name", "") if reporter else ""
    disp_name = reporter.get("displayName", "") if reporter else ""
    return (name, disp_name)


def extract_assignee(o: dict) -> tuple[str, str]:
    assignee = o.get("fields").get("assignee")
    name = assignee.get("name", "") if assignee else ""
    disp_name = assignee.get("displayName", "") if assignee else ""
    return (name, disp_name)


def extract_parent_key(o: dict) -> str:
    parent = o["fields"].get("parent")
    if parent:
        key = parent["key"]
        if key:
            return key
    return None


def extract_created(o: dict) -> str:
    return o.get("fields").get("created", "")


def extract_updated(o: dict) -> str:
    return o.get("fields").get("updated", "")


def extract_resolutiondate(o: dict) -> str:
    return o.get("fields").get("resolutiondate", "")


def extract_fixversions(o: dict) -> list[str]:
    return [x.get("name", "") for x in o.get("fields").get("fixVersions", [])]


def extract_versions(o: dict) -> list[str]:
    return [x.get("name", "") for x in o.get("fields").get("versions", [])]


def extract_components(o: dict) -> list[str]:
    return [x.get("name", "") for x in o.get("fields").get("components", [])]


def extract_labels(o: dict) -> list[str]:
    return o.get("fields").get("labels", [])


def extract_attachments(o: dict) -> list[tuple[str, int]]:
    attachments = o.get("fields").get("attachment")
    if not attachments:
        return []
    files = {}
    counts = defaultdict(int)
    for a in attachments:
        filename = a.get("filename")
        created = a.get("created")
        content = a.get("content")
        mime_type = a.get("mimeType")
        if not (filename and created and content and mime_type):
            continue
        if filename not in files or created > files[filename].created:
            files[filename] = Attachment(filename=filename, created=created, content=content, mime_type=mime_type)
        counts[filename] += 1
    result = []
    for name in files.keys():
        result.append((name, counts[name]))
    return result


def extract_issue_links(o: dict) -> list[str]:
    issue_links = o.get("fields").get("issuelinks", [])
    if not issue_links:
        return []

    res = []
    for link in issue_links:
        key = link.get("outwardIssue", {}).get("key")
        if key:
            res.append(key)
        key = link.get("inwardIssue", {}).get("key")
        if key:
            res.append(key)
    return res


def extract_subtasks(o: dict) -> list[str]:
    return [x.get("key", "") for x in o.get("fields").get("subtasks", [])]


def extract_comments(o: dict) -> list[str, str, str, str, str]:
    comments = o.get("fields").get("comment", {}).get("comments", [])
    if not comments:
        return []
    res = []
    for c in comments:
        author = c.get("author")
        name = author.get("name", "") if author else ""
        disp_name = author.get("displayName", "") if author else ""
        body = c.get("body", "")
        created = c.get("created", "")
        updated = c.get("updated", "")
        comment_id = c.get("id", "")
        res.append((name, disp_name, body, created, updated, comment_id))
    return res


def extract_pull_requests(o: dict) -> list[str]:
    worklogs = o.get("fields").get("worklog", {}).get("worklogs", [])
    if not worklogs:
        return []
    res = []
    for wl in worklogs:
        if wl.get("author").get("name", "") != "githubbot":
            continue
        comment: str = wl.get("comment", "")
        if not comment:
            continue
        if "opened a new pull request" not in comment and not "opened a pull request" in comment:
            continue
        comment = comment.replace('\n', ' ')
        # detect pull request url
        matches = re.match(r".*(https://github\.com/apache/lucene/pull/\d+)", comment)
        if matches:
            res.append(matches.group(1))
        # detect pull request url in old lucene-solr repo
        matches = re.match(r".*(https://github\.com/apache/lucene-solr/pull/\d+)", comment)
        if matches:
            res.append(matches.group(1))     
    return res


# space character + Jira emoji + space character
JIRA_EMOJI_TO_UNICODE = {
    "(?<=\s)\(y\)((?=$)|(?=\s))": "\U0001F44D",
    "(?<=\s)\(n\)((?=$)|(?=\s))": "\U0001F44E",
    "(?<=\s)\(i\)((?=$)|(?=\s))": "\U0001F6C8",
    "(?<=\s)\(/\)((?=$)|(?=\s))": "\u2714",
    "(?<=\s)\(x\)((?=$)|(?=\s))": "\u274C",
    "(?<=\s)\(\!\)((?=$)|(?=\s))": "\u26A0",
    "(?<=\s)\(\+\)((?=$)|(?=\s))": "\u002B",
    "(?<=\s)\(\-\)((?=$)|(?=\s))": "\u2212",
    "(?<=\s)\(\?\)((?=$)|(?=\s))": "\u003F",
    "(?<=\s)\(on\)((?=$)|(?=\s))": "\U0001F4A1",
    "(?<=\s)\(off\)((?=$)|(?=\s))": "\U0001F4A1",
    "(?<=\s)\(\*\)((?=$)|(?=\s))": "\u2B50",
    "(?<=\s)\(\*r\)((?=$)|(?=\s))": "\u2B50",
    "(?<=\s)\(\*g\)((?=$)|(?=\s))": "\u2B50",
    "(?<=\s)\(\*b\)((?=$)|(?=\s))": "\u2B50",
    "(?<=\s)\(flag\)((?=$)|(?=\s))": "\U0001F3F4",
    "(?<=\s)\(flagoff\)((?=$)|(?=\s))": "\U0001F3F3"
}

REGEX_CRLF = re.compile(r"\r\n")
REGEX_JIRA_KEY = re.compile(r"[^/]LUCENE-\d+")
REGEX_MENTION_ATMARK = re.compile(r"(^@[\w\.]+)|((?<=[\s\(\"'])@[\w\.]+)(?=[\s\)\"'\?!,\.$])")  # this regex may capture only "@" + "<username>" mentions
REGEX_MENION_TILDE = re.compile(r"(^\[~[\w\.]+\])|((?<=[\s\(\"'])\[~[\w\.]+\])(?=[\s\)\"'\?!,\.$])")  # this regex may capture only "[~" + "<username>" + "]" mentions
REGEX_LINK = re.compile(r"\[([^\]]+)\]\(([^\)]+)\)")


def convert_text(text: str, att_replace_map: dict[str, str] = {}, account_map: dict[str, str] = {}, jira_users: dict[str, str] = {}) -> str:
    """Convert Jira markup to Markdown
    """
    def repl_att(m: re.Match):
        res = m.group(0)
        for src, repl in att_replace_map.items():
            if m.group(2) == src:
                res = f"[{m.group(1)}]({repl})"
        return res

    text = re.sub(REGEX_CRLF, "\n", text)  # jira2markup does not support carriage return (?)

    # convert Jira special emojis into corresponding or similar Unicode characters
    for emoji, unicode in JIRA_EMOJI_TO_UNICODE.items():
        text = re.sub(emoji, unicode, text)

    # convert Jira markup into Markdown with customization
    elements = MarkupElements()
    elements.replace(UnorderedList, UnorderedTweakedList)
    elements.replace(OrderedList, OrderedTweakedList)
    elements.replace(BlockQuote, TweakedBlockQuote)
    elements.replace(Quote, TweakedQuote)
    elements.replace(Monospaced, TweakedMonospaced)
    elements.insert_after(Ruler, LongRuler)
    elements.append(EscapeHtmlTag)
    text = jira2markdown.convert(text, elements=elements)

    # convert @ mentions
    mentions = re.findall(REGEX_MENTION_ATMARK, text)
    if mentions:
        mentions = set(filter(lambda x: x != '', itertools.chain.from_iterable(mentions)))
        for m in mentions:
            jira_id = m[1:]
            disp_name = jira_users.get(jira_id)
            gh_m = account_map.get(jira_id)
            # replace Jira name with GitHub account or Jira display name if it is available, othewise show Jira name with `` to avoid unintentional mentions
            mention = lambda: f"@{gh_m}" if gh_m else disp_name if disp_name else f"`@{jira_id}`"
            text = text.replace(m, mention())
    
    # convert ~ mentions
    mentions = re.findall(REGEX_MENION_TILDE, text)
    if mentions:
        mentions = set(filter(lambda x: x != '', itertools.chain.from_iterable(mentions)))
        for m in mentions:
            jira_id = m[2:-1]
            disp_name = jira_users.get(jira_id)
            gh_m = account_map.get(jira_id)
            # replace Jira name with GitHub account or Jira display name if it is available, othewise show Jira name with ``
            mention = lambda: f"@{gh_m}" if gh_m else disp_name if disp_name else f"`~{jira_id}`"
            text = text.replace(m, mention())
    
    text = re.sub(REGEX_LINK, repl_att, text)

    return text


def embed_gh_issue_link(text: str, issue_id_map: dict[str, str]) -> str:
    """Embed GitHub issue number
    """
    def repl_simple(m: re.Match):
        res = m.group(0)
        gh_number = issue_id_map.get(m.group(2))
        if gh_number:
            res = f"{m.group(1)}#{gh_number}{m.group(3)}"
        return res
    
    def repl_paren(m: re.Match):
        res = m.group(0)
        gh_number = issue_id_map.get(m.group(2))
        if gh_number:
            res = f"{m.group(1)}#{gh_number}{m.group(3)}"
        return res

    def repl_bracket(m: re.Match):
        res = m.group(0)
        gh_number = issue_id_map.get(m.group(2))
        if gh_number:
            res = f"#{gh_number}"
        return res
    
    def repl_md_link(m: re.Match):
        res = m.group(0)
        gh_number = issue_id_map.get(m.group(1))
        if gh_number:
            res = f"{m.group(0)} (#{gh_number})"
            # print(res)
        return res

    text = re.sub(r"(\s)(LUCENE-\d+)([\s,;:\?\!\.])", repl_simple, text)
    text = re.sub(r"(\()(LUCENE-\d+)(\))", repl_paren, text)
    text = re.sub(r"(\[)(LUCENE-\d+)(\])(?!\()", repl_bracket, text)
    text = re.sub(r"\[(LUCENE-\d+)\]\(https?[^\)]+LUCENE-\d+\)", repl_md_link, text)

    return text
