"""
字节跳动系列 / ByteDance Series
支持字符串、容器 / Supports strings and containers
你甚至还可以设置延迟是毫秒还是秒 / You can even set the delay to milliseconds or seconds
字节跳动，也就是类似打字机的效果 / ByteDance, which is similar to a typewriter
bd支持所有了哦！也有对应的全名了！/ bd support everything! There is also a corresponding full name!
byteprint库，全名byte print，也就是说，对应BytePrint库，缩写bp / Byteprint library, full name byte print, that is, corresponding to BytePrint library, abbreviated as bp
提示：可以使用`import byteprint as bp` / Tip: You can use `import byteprint as bp`

对应正式版 / Corresponding to the official version
> 1.2.6
上一个正式版 / Previous official version
> 1.2.5
上一个测试版 / Previous beta version
> 1.2.6rc2
"""
from collections.abc import Container as _Container
from time import sleep as _sleep
from typing import Any as _Any, List as _List, Union as _Union, Callable as _Callable, Tuple as _Tuple
from warnings import warn as _warn
from types import FunctionType as _Function
from traceback import print_exc as _print_exc
from sys import version as _ver

_clear: str = "\033[2J\033[H"
__all__: _Tuple[str, ...] = (
    "string_byte_dance",
    "str_byte_dance",
    "bd",
    "sbd",
    "byte_dance",
    "container_byte_dance",
    "cbd",
    "helps",
    "execute"
)
__version__: str = "1.2.6"
__anchor__: str = "nousername"
__email__: str = "2467906561@qq.com"

def string_byte_dance(content: _Any, speed: _Union[int, float] = 30, end: _Any = "\n", ms_mode: bool = True) -> None:
    """
    :note: 别看我只是一个简简单单的STR类型，实际我支持所有 / Don't be fooled by the simple STR type - I actually support all types
    :param Any content: 内容，建议为str类型 / Content, str type is recommended
    :param int|float speed: 打印速度，默认30 / Printing speed, default 30
    :param Any end: 结尾参数，默认换行 / End parameter, default line wrap
    :param bool ms_mode: 是否设置为毫秒模式，默认True / Whether to set millisecond mode, default True
    :note: 参数除了content，其他都是位置参数，ms_mode关闭时建议同时修改speed / Parameters except contentExcept for content, all parameters are locationExcept for content, all parameters are location parametersExcept for content, all parameters are location parameters; it's recommended to modify speed when ms_mode is disabled
    :return: None: 仅限打印内容 / Only for printing content
    :raises TypeError: speed强制，必须为int或float类型，否则报错 / speed is mandatory, must be int or float type, otherwise an error is raised
    :raises ValueError: speed必须≥0，否则报错 / speed must be ≥ 0, otherwise an error is raised
    :warning: speed不能为0，否则警告提醒你 / speed cannot be 0, otherwise a warning is issued
    :warning: ms_mode为布尔值，建议传入bool类型 / ms_mode should be a boolean value, it's recommended to pass bool type
    :warning: ms_mode为布尔值，建议传入bool类型 / ms_mode should be a boolean value, it's recommended to pass bool type
    """
    if not isinstance(speed, (int, float)):
        raise TypeError(f"不合适的参数类型：{type(speed).__name__}\n请确保它的参数类型为：int 或 float\nInappropriate parameter type: {type(speed).__name__}\nPlease ensure it is int or float type")
    if speed < 0:
        raise ValueError(f"不合适的范围：{speed}，你必须得确保它大于等于0以上\nInappropriate range: {speed}\nPlease ensure it is greater than or equal to 0")
    if speed == 0:
        _warn("speed数值为0时你干脆直接使用print算了！\nWhen speed is 0, you might as well use print directly!", UserWarning, stacklevel=2)
    if not isinstance(ms_mode, bool):
        _warn(f"ms_mode建议为布尔值，不然可能偏离预想，结果你的输入却是{type(ms_mode).__name__}类型\nms_mode is recommended to be boolean, otherwise results may deviate from expectations. Your input is {type(ms_mode).__name__} type", UserWarning, stacklevel=2)
        ms_mode = bool(ms_mode)
    content = str(content)
    if ms_mode:
        speed /= 1000
    for i in content:
        print(end = i, flush = True)
        _sleep(speed)
    print(end = str(end))

def str_byte_dance(content: _Any, speed: _Union[int, float] = 30, end: _Any = "\n", ms_mode: bool = True) -> None:
    """
    :note: 这是一个名称简化的string_byte_dance函数 / This is a simplified-named version of str_byte_dance
    :param Any content: 对应content / Corresponded content
    :param int|float speed: 对应speed，默认为30 / Corresponded speed, default 30
    :param Any e: 对应end，默认换行 / Corresponded end , default line wrap
    :param bool ms_mode: 对应ms_mode，默认为True / Corresponded ms_mode, default True
    :note: 具体内容请看被简化的函数 / For details, refer to the original function
    :return: None: 与原函数机制一致 / Consistent with the original function mechanism
    :raises TypeError: 与原函数机制一致 / Consistent with the original function mechanism
    :raises ValueError: 与原函数机制一致 / Consistent with the original function mechanism
    :warning: 与原函数机制一致 / Consistent with the original function mechanism
    """
    string_byte_dance(content, speed = speed, end = end, ms_mode = ms_mode)

def bd(c: _Any, s: _Union[int, float] = 30, e: _Any = "\n", m: bool = True) -> None:
    """
    :note: 这是一个融合的sbd和cbd的函数 / This is a function that combines sbd and cbd
    :param Any c: 简化版content / Simplified content
    :param int|float s: 简化版speed，默认为30 / Simplified speed, default 30
    :param Any e: 简化版end，默认换行 / Simplified end , default line wrap
    :param bool m: 简化版ms_mode，默认为True / Simplified ms_mode, default True
    :note: 具体内容请看被简化的函数 / For details, refer to the original function
    :return: None: 与原函数机制一致 / Consistent with the original function mechanism
    :raises TypeError: 与原函数机制一致 / Consistent with the original function mechanism
    :raises ValueError: 与原函数机制一致 / Consistent with the original function mechanism
    :warning: 与原函数机制一致 / Consistent with the original function mechanism
    :note: 会自动判断应该使用哪一类的 / will automatically determine which type to use
    """
    try:
        if isinstance(c, str):
            raise TypeError
        if not isinstance(c, dict):
            for i in c:
                break
        cbd(c, s = s, e = e, m = m)
    except TypeError:
        sbd(c, s = s, e = e, m = m)

def byte_dance(content: _Any, speed: _Union[int, float] = 30, end: _Any = "\n", ms_mode: bool = True) -> None:
    """
    :note: 这是一个融合的sbd和cbd的函数 / This is a function that combines sbd and cbd
    :param Any content: 对应content / Corresponded c
    :param int|float speed: 对应s，默认为30 / Corresponded s, default 30
    :param Any end: 对应e，默认换行 / Corresponded e, default line wrap
    :param bool ms_mode: 对应m，默认为True / Corresponded m, default True
    :note: 具体内容请看被简化的函数 / For details, refer to the original function
    :return: None: 与原函数机制一致 / Consistent with the original function mechanism
    :raises TypeError: 与原函数机制一致 / Consistent with the original function mechanism
    :raises ValueError: 与原函数机制一致 / Consistent with the original function mechanism
    :warning: 与原函数机制一致 / Consistent with the original function mechanism
    :note: 会自动判断应该使用哪一类的 / will automatically determine which type to use
    """
    bd(content, s = speed, e = end, m = ms_mode)

def sbd(c: _Any, s: _Union[int, float] = 30, e: _Any = "\n", m: bool = True) -> None:
    """
    :note: 这是一个名称简化的str_byte_dance函数 / This is a simplified-named version of str_byte_dance
    :param Any c: 简化版content / Simplified content
    :param int|float s: 简化版speed，默认为30 / Simplified speed, default 30
    :param Any e: 简化版end，默认换行 / Simplified end , default line wrap
    :param bool m: 简化版ms_mode，默认True / Simplified ms_mode, default True
    :note: 具体内容请看被简化的函数 / For details, refer to the original function
    :return: None: 与原函数机制一致 / Consistent with the original function mechanism
    :raises TypeError: 与原函数机制一致 / Consistent with the original function mechanism
    :raises ValueError: 与原函数机制一致 / Consistent with the original function mechanism
    :warning: 与原函数机制一致 / Consistent with the original function mechanism
    """
    str_byte_dance(c, speed = s, end = e, ms_mode = m)

def container_byte_dance(content: _Container[_Any], speed: _Union[int, float] = 30, end: _Any = "\n", ms_mode: bool = True) -> None:
    """
    :note: 这是一个容器迭代方式，通过遍历来打印 / This is a container iteration method, printing through traversal
    :param AnyConNstr content: 一个容器，比如list, tuple（str不建议） / A container, e.g., list, tuple (str is not recommended)
    :param int|float speed: 打印速度，默认为30 / Printing speed, default 30
    :param Any end: 结尾参数，默认换行 / End parameter, default line wrap
    :param bool ms_mode: 是否设置为毫秒模式，默认True / Whether to set millisecond mode, default True
    :note: 参数除了content，其他都是位置参数，ms_mode关闭时建议同时修改speed / Except for content, all parameters are location parameters; it's recommended to modify speed when ms_mode is disabled
    :return: None: 仅限打印内容 / Only for printing content
    :raises TypeError: speed强制，必须为int或float类型，否则报错 / speed is mandatory, must be int or float type, otherwise an error is raised
    :raises TypeError: 强制内容content，必须可迭代，否则报错 / content must be iterable, otherwise an error is raised
    :raises ValueError: speed必须≥0，否则报错 / speed must be ≥ 0, otherwise an error is raised
    :warning: speed不能为0，否则警告提醒你 / speed cannot be 0, otherwise a warning is issued
    :warning: 如果content为Str类型，则发个警告 / If content is str type, a warning is issued
    :warning: ms_mode为布尔值，建议传入bool类型 / ms_mode should be a boolean value, it's recommended to pass bool type
    :note: 处理dict类型时，会先打印key，再打印value / When processing dict type, keys are printed first, then values
    """
    if not isinstance(speed, (int, float)):
        raise TypeError(f"不合适的参数类型：{type(speed).__name__}\n请确保它的参数类型为：int 或 float\nInappropriate parameter type: {type(speed).__name__}\nPlease ensure it is int or float type")
    if speed < 0:
        raise ValueError(f"不合适的范围：{speed}，你必须确保它大于等于0以上\nInappropriate range: {speed}\nPlease ensure it is greater than or equal to 0")
    if speed == 0:
        _warn("数值为0时，你干脆直接使用print算了！\nWhen speed is 0, you might as well use print directly!", UserWarning, stacklevel=2)
    if isinstance(content, str):
        _warn("这里是容器玩的地方，不是Str能来的地方\nThis is for containers, not str type!", UserWarning, stacklevel=2)
    if isinstance(content, dict):
        d: _List[_Any] = []
        e: _List[_Any] = []
        for a, b in content.items():
            d.append(a)
            e.append(b)
        content = d + e
    if not isinstance(ms_mode, bool):
        _warn(f"ms_mode建议为布尔值，不然可能偏离预想，结果你的输入却是{type(ms_mode).__name__}类型\nms_mode is recommended to be boolean, otherwise results may deviate from expectations. Your input is {type(ms_mode).__name__} type", UserWarning, stacklevel=2)
        ms_mode = bool(ms_mode)
    if ms_mode:
        speed /= 1000
    try:
        for i in content:  # type: ignore[attr-defined]
            print(end = i, flush = True)
            _sleep(speed)
        print(end = str(end))
    except TypeError:
        raise TypeError(f"你这迭代对象可真特别呢：{type(content).__name__}\nThis iterable object is quite special: {type(content).__name__}")

def cbd(c: _Container[_Any], s: _Union[int, float] = 30, e: _Any = "\n" , m: bool = True) -> None:
    """
    :note: 这是一个名称简化的container_byte_dance函数 / This is a simplified-named version of container_byte_dance
    :param Any c: 简化版content / Simplified content
    :param int|float s: 简化版speed，默认为30 / Simplified speed, default 30
    :param Any e: 简化版end，默认换行 / Simplified end , default line wrap
    :param bool m: 简化版ms_mode，默认为True / Simplified ms_mode, default True
    :note: 具体内容请看被简化的函数 / For details, refer to the original function
    :return: None: 与原函数机制一致 / Consistent with the original function mechanism
    :raises TypeError: 与原函数机制一致 / Consistent with the original function mechanism
    :raises ValueError: 与原函数机制一致 / Consistent with the original function mechanism
    :warning: 与原函数机制一致 / Consistent with the original function mechanism
    """
    container_byte_dance(c, speed = s, end = e, ms_mode = m)

def helps(func: _Union[_Function, None] = None) -> None:
    """
    :note: 查看对应函数的文档（function）/用法的帮助（None） / View the corresponding function's documentation (function)/usage help (None)
    :param function|None func: 决定是查看函数的文档（function）还是用法的帮助（None）（默认） / Decide whether to view the function's documentation (function) or usage help (None)(default)
    :return: None: 单纯的文本输出 / Pure text output
    :raises TypeError: 输入的类型不是function或None / The type entered is not function or None
    :note: 只适用于内置的函数 / Only applies to built-in functions
    """
    if isinstance(func, _Function) and func.__module__ == "byteprint":
        sbd(f"{func.__name__}函数文档帮助 / {func.__name__} Function Documentation Help \n\n\n {func.__doc__}")
    elif func is None:
        sbd(f"""
        {_clear}
        欢迎来到函数帮助界面，这里将给予教程 /
        Welcome to the function help interface, where you will provide tutorials.
        
        我尽量保持真实！ / I try to be real!
        {'\0'*30}
        {_clear}
        首先，请看三个有功能的函数 /
        First, look at three functional functions

        > string_byte_dance
        > container_byte_dance
        > bd
        核心都是(c, s, e, m) / The core is all (c, s, e, m)
        c -> content (/)  [(存在差异) / there are differences]
        s -> speed  [int | float]
        e -> end  [_Any]
        m -> ms_mode  [bool]
        {'\0'*30}
        {_clear}
        接下来介绍 / then introduced

        > string_byte_dance
        
        对应缩写 / Corresponding abbreviation

        > sbd

        你可以把缩写看成一个快捷方式 /
        You can think of abbreviations as a shortcut
        
        示例 / example：
        >>> from byteprint import sbd
        >>> sbd('Hello world, python')""")
        sbd("        Hello world, python")
        sbd("        >>> sbd('这是慢性 / This is chronic', 50)")
        sbd("        这是慢性 / This is chronic", 50)
        sbd("        >>> sbd('秒级模式 / Second-level mode', 0.1, True)  # 具体规则请看帮助 / Please see Help for specific rules")
        sbd("        秒级模式 / Second-level mode", 0.1, True)
        sbd("        >>> sbd('字符串 / String', '50')")
        print(f"""        Traceback (most recent call last):
          File \'<python-input-4>\', line 1, in <module>
            sbd('字符串 / String', '50')
            ~~~^^^^^^^^^^^^^^^^^^^^^^^^^
          File \'.../site-packages/byteprint.py\', line 117, in sbd
            str_byte_dance(c, s, ms_mode = m)
            ~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^
          File \'.../site-packages/byteprint.py\', line 67, in str_byte_dance
            string_byte_dance(content, speed, ms_mode = ms_mode)
            ~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
          File \'.../site-packages/byteprint.py\', line 39, in string_byte_dance
            raise TypeError(f\'不合适的参数类型：{{type(speed).__name__}}\\n请确保它的参数类型为：int 或 float\\nInappropriate parameter type: {{type(speed).__name__}}\\nPlease ensure it is int or float type\')
        TypeError: 不合适的参数类型：str
        请确保它的参数类型为：int 或 float
        Inappropriate parameter type: str
        Please ensure it is int or float type""")
        sbd(f"""
        >>> # 更多文档帮助，请使用 / For more documentation assistance, please use
        >>> from byteprint import sbd
        >>> help(sbd)
        >>> # 或 / or
        >>> import byteprint
        >>> byteprint.helps(byteprint.sbd)
        >>> # 或 查看源码 / or View source code {'\0'*60}
        {_clear}
        接下来介绍 / then introduced
        
        > container_byte_dance
        
        对应缩写 / Corresponding abbreviation
        
        > cbd
        
        示例 / example：
        >>> from byteprint import cbd
        >>> cbd(['中英', 'Sino-British', 'Hi'])""")
        cbd(['        ', '中英', 'Sino-British', 'Hi'])
        sbd("        >>> cbd(['你好', '！', 'Hello', '!'], 120)")
        cbd(['        ', '你好', '！', 'Hello', '!'], 120)
        sbd(f"""
        >>> # 更多文档帮助，请使用 / For more documentation assistance, please use
        >>> from byteprint import cbd
        >>> help(cbd)
        >>> # 或 / or
        >>> import byteprint
        >>> byteprint.helps(byteprint.cbd)
        >>> # 或 查看源码 / or View source code {'\0'*60}
        {_clear}
        最牛逼的还得是 / The best thing is
        
        > bd
        
        全称 / full name
        
        > byte_dance
        
        能厉害到什么程度？ / How powerful can it be?
        融合了sbd函数和cbd函数 / Fusion of sbd function and cbd function
        核心判断就是是否可迭代 / The core judgment is whether it is iterable or not
        可以算比较智能的了 / It can be regarded as relatively intelligent
        >>> # 更多文档帮助，请使用 / For more documentation assistance, please use
        >>> from byteprint import bd
        >>> help(bd)
        >>> # 或 / or
        >>> import byteprint
        >>> byteprint.helps(byteprint.bd)
        >>> # 或 查看源码 / or View source code {'\0'*60}
        {_clear}
        好啦，教程就到这里 / Okay, that's all for the tutorial
        祝你用库愉快！ / I wish you a happy use of the library!
        
        提示：使用execute函数进行内部执行方式 /
        Tip: Use the execute function for internal execution
        [Version {__version__}]
        """)
    else:
        raise TypeError(f"请确保输入的类型为None或者Function，你输入类型的是{type(func).__name__}\nPlease make sure the type you enter is None or Function, and the type you enter is {type(func).__name__}")

def execute(inp: _Union[str, None] = None) -> None:
    """
    :note: 执行代码的方式其一，在一个简易交互式进行byteprint交互 / One way to execute code is to interact byteprint in a simple interactive format
    :param str|None inp: 决定方式，str代表执行内部内容，None代表进入交互 / Decision method, str represents execution of internal content, and None represents entry of interaction
    :return None: 单纯的文本输出 / Pure text output
    :raises ValueError: 当文本出现\\n（换行）时报错（还不支持） / When the text appears\\n (newline), an error is reported (not supported yet)
    :raises TypeError: 输入的类型不是str或None / The type entered is not str or None
    :note: 暂不支持此功能！
    """
    def _form(a: str) -> str:
        """你不应该看的，这里是内置函数，不能用 / You shouldn't read it. This is a built-in function and cannot be used."""
        strs: bool = True
        b: str = ""
        for d in a.split(";"):
            for i in d:
                if i in ["'", '"']:
                    strs = not strs
                if i in "#" and strs:
                    break
                b += i
            b += ";"
        return b.strip()
    def _run(c: str) -> None:
        """你不应该看的，这里是内置函数，不能用 / You shouldn't read it. This is a built-in function and cannot be used."""
        for l, d in enumerate(c.split(";"), start = 1):
            if any([
                    (len(d) >= 3 and "bd" in d[:3]),
                    (len(d) >= 17 and "_byte_dance" in d[:17]),
                    (len(d) >= 4 and "help" in d[:4]),
                    (len(d) >= 5 and "helps" in d[:5]),
                    (len(d) >= 5 and "print" in d[:5])
            ]):
                try:
                    eval(d)
                except Exception:
                    _print_exc()
                    print(f"\n\033[31m错误在第{l}个分号：{d}")
            else:
                print("SyntaxError: invalid syntax")
    a: str
    if inp is None:
        alls: _List[str] = list(__all__)
        alls.pop()
        alls.extend(["exit", "help", "print", "info"])
        print(f"BytePrint {__version__} [Python {_ver}]")
        infs: _Callable[[], None] = lambda: print(f"""
        使用“exit”退出，无需括号 / Use 'exit' to exit without parentheses
        只支持： / only supports: {alls}
        “#”就是注释 / '#' is a comment
        报错形式原汁原味 / The original form of error reporting
        byteprint库，Ctrl+C，Ctrl+D，'exit' 都可以退出 / byteprint library, Ctrl+C, Ctrl+D, 'exit' can be exited
        """)
        while True:
            try:
                if input("是否需要提示？(y/其他) / Do you need a prompt? (y/Other)：") == "y":
                    infs()
                a = _form(input("\033[38;5;129m(byteprint)>>> \033[0m"))
                if not a or a.isspace():
                    continue
                if a == "exit" or a == "exit()":
                    break
                if a == "info" or a == "info()":
                    infs()
                _run(a)
            except (KeyboardInterrupt, EOFError):
                break
        print("已退出byteprint交互式 / Byteprint interactive has been exited")
    elif isinstance(inp, str):
        a = _form(inp)
        if not a or a.isspace():
            return
        _run(a)
    else:
        raise TypeError(f"请确保输入的类型为None或者str，你输入类型的是{type(inp).__name__}\nPlease make sure the type you enter is None or str, and the type you enter is {type(inp).__name__}")

__init__ = (bd, helps, execute)
