import os
import sys
from antlr4 import *

if "." in __name__:
    from .ptmlTranslator import ptmlTranslator
    from .ptmlParser import ptmlParser as Parser
    from .ptmlLexer import ptmlLexer as Lexer

else:
    from ptmlTranslator import ptmlTranslator
    from ptmlParser import ptmlParser as Parser
    from ptmlLexer import ptmlLexer as Lexer


def load(scene, ptml_path: str, behaviour_lib_path: str):
    """_summary_

    Args:
        ptml_path (str): _description_
        behaviour_lib_path (str): _description_

    Raises:
        FileNotFoundError: _description_
        FileNotFoundError: _description_
    """
    # error handle
    if not os.path.exists(ptml_path):
        raise FileNotFoundError("Given a fault ptml path: {}".format(ptml_path))
    if not os.path.exists(behaviour_lib_path):
        raise FileNotFoundError(
            "Given a fault behaviour library path: {}".format(behaviour_lib_path)
        )

    # noting fault, go next
    ptml_path = format_trans_to_bracket(ptml_path)
    # print(ptml_path)
    input_stream = FileStream(ptml_path, encoding="utf-8")

    lexer = Lexer(input_stream)
    stream = CommonTokenStream(lexer)
    parser = Parser(stream)
    tree = parser.root()

    walker = ParseTreeWalker()

    sys.path.append(os.path.join(behaviour_lib_path, "cond"))
    sys.path.append(os.path.join(behaviour_lib_path, "act"))

    ptml = ptmlTranslator(scene, behaviour_lib_path)  # listener mode
    walker.walk(ptml, tree)

    return ptml.bt_root

def parse_indentation(text):
    tree = {}
    stack = [(-1, tree)]  # 使用栈来跟踪节点层级和父节点

    for line in text.splitlines():
        indent = len(line) - len(line.lstrip())
        content = line.strip()

        if not content:
            continue  # 跳过空行

        # 找到当前行的父级
        while stack and stack[-1][0] >= indent:
            stack.pop()

        # 确保栈不为空
        if not stack:
            raise ValueError("缩进错误")

        # 检查当前行是否已存在于父级中
        parent = stack[-1][1]
        if content not in parent:
            parent[content] = []

        # 添加新节点
        node = {}
        parent[content].append(node)
        stack.append((indent, node))

    return tree

def format_nested_dict(d, indent=0, outermost=True):
    """ 格式化嵌套字典为特定字符串格式，如果没有子级就不添加大括号 """
    indention = "    " * indent  # 用空格表示缩进
    formatted_str = ""

    if (not outermost) and d:  # 添加大括号，除非是空字典
        formatted_str += "{\n"

    for key, value_list in d.items():
        for value in value_list:  # 遍历列表中的每个字典
            formatted_str += f"{indention}{'    ' if (not outermost) and d else ''}{key}\n"

            if isinstance(value, dict):
                # 如果值是字典，则递归调用
                formatted_str += format_nested_dict(value, indent + (0 if outermost else 1), False)
            else:
                # 否则，直接添加值
                formatted_str += f"{indention}{'    ' * 2}{value}\n"

    if (not outermost) and d:  # 如果不是空字典，才关闭大括号
        formatted_str += indention + "}\n"

    return formatted_str.strip()

def format_trans_to_bracket(file_path: str) -> str:
    """_summary_

    Args:
        file_path (str): _description_

    Raises:
        FileNotFoundError: _description_

    Returns:
        str: the path tp temp file with '{}' form.
    """
    import autopep8

    if not os.path.exists(file_path):
        raise FileNotFoundError("Given a fault ptml path: {}".format(file_path))

    with open(file_path, 'r') as file:
        f = file.read().strip()
        if "{" in f:
            return file_path

    parsed_tree = parse_indentation(f)

    formatted_output  = format_nested_dict(parsed_tree)

    # def counter_(input: str) -> int:
    #     length = 0
    #     for i in range(len(input)):
    #         if input[i] == ' ':
    #             length += 1
    #         else:
    #             if length % 4 != 0:
    #                 raise TabError('Tab length in ptml file should be 4.')
    #             return length
    #
    # with open(file_path, 'r') as file:
    #     ptml_new = ''
    #     ptml_tab = file.readlines()
    #
    #     level = 0
    #     for i in ptml_tab:
    #
    #         if i.startswith('//'):
    #             continue
    #
    #         new_level = counter_(i) // 4
    #         if new_level == level:
    #             ptml_new += i
    #         elif new_level > level:
    #             ptml_new += '{\n' + i
    #             level += 1
    #         elif new_level < level:
    #             ptml_new += '\n}' + i
    #             level -= 1
    #     for i in range(level):
    #         ptml_new += '}'

    file_name = os.path.basename(file_path).split(".")[0]
    dir_path = os.path.dirname(file_path)
    # import re
    # new_path = re.sub('\\\[a-zA-Z0-9_]*\.ptml', '/bracket_ptml.ptml', file_path)
    new_path = os.path.join(dir_path,file_name+"_bracket.ptml")
    with open(new_path, 'w') as file:
        file.write(formatted_output)
    return new_path

# format_trans_to_bracket('C:\\Users\\Estrella\\Desktop\\RoboWaiter\\robowaiter\\behavior_tree\\ptml\\test\\Default.ptml')

if __name__ == '__main__':
    # 示例文本
    text = """
selector
    sequence
        cond Chatting()
        act DealChat()
    sequence
        cond HasSubTask()
        sequence
            act SubTaskPlaceHolder()
    sequence
        cond FocusingCustomer()
        act ServeCustomer()
    sequence
        cond NewCustomer()
        selector
            cond At(Robot,Bar)
            act MoveTo(Bar)
        act GreetCustomer()
    sequence
        cond AnomalyDetected()
        act ResolveAnomaly()
    """

    parsed_tree = parse_indentation(text)
    print(parsed_tree)

    formatted_output  = format_nested_dict(parsed_tree)
    print(formatted_output)