import random
from typing import Optional
import opencc

from nonebot import on_message
from nonebot.adapters import Event as BaseEvent
from nonebot.adapters.discord.event import MessageEvent as DiscordMessageEvent
from nonebot_plugin_alconna import (
    Alconna,
    Args,
    UniMessage,
    UniMsg,
    on_alconna,
)

convert_type = ["简","簡","繁","正","港","日"]

compiled_str = "|".join([f"{a}{mid}{b}" for mid in ["转","轉","転"] for a in convert_type for b in convert_type if a != b])

def hanzi_to_abbr(hanzi: str) -> str:
    mapping = {
        "简": "s",
        "簡": "s",
        "繁": "t",
        "正": "t",
        "港": "hk",
        "日": "jp",
    }
    return mapping.get(hanzi, "")

def check_valid_convert_type(convert_type: str) -> bool:
    avaliable_set = ["s2t","t2s","s2tw","tw2s","s2hk","hk2s","s2twp","tw2sp","t2tw","hk2t","t2hk","t2jp","jp2t","tw2t"]
    if convert_type in avaliable_set:
        return True
    return False

def convert(source, src_abbr, dst_abbr):
    convert_type_key = f"{src_abbr}2{dst_abbr}"
    if not check_valid_convert_type(convert_type_key):
        # 先转为繁体，再转为目标
        converter = opencc.OpenCC(f"{src_abbr}2t.json")
        source = converter.convert(source)
        src_abbr = "t"
    converter = opencc.OpenCC(f"{src_abbr}2{dst_abbr}.json")
    converted = converter.convert(source)
    return converted

evt = on_alconna(
    Alconna(
        f"re:({compiled_str})",
        Args["source?", str],
    ),
    use_cmd_start=True,
    use_cmd_sep=False,
    skip_for_unmatch=True,
)

@evt.handle()
async def _(msg: UniMsg, event: BaseEvent, source: Optional[str] = None):
    if isinstance(event, DiscordMessageEvent):
        content = event.get_message().extract_plain_text()
    else:
        content = event.get_message().extract_plain_text()

    prefix = content.split()[0]
    to_convert = ""
    # 如果回复了消息，则转换回复的内容
    if(source is None):
        if event.reply:
            to_convert = event.reply.message.extract_plain_text()
            if not to_convert:
                return
        else:
            return
    else:
        to_convert = source
    parts = []
    if "转" in prefix:
        parts = prefix.split("转")
    elif "轉" in prefix:
        parts = prefix.split("轉")
    elif "転" in prefix:
        parts = prefix.split("転")
    if len(parts) != 2:
        notice = "转换格式错误，请使用“简转繁”、“繁转简”等格式。"
        await evt.send(await UniMessage().text(notice).export())
        return
    src, dst = parts
    src_abbr = hanzi_to_abbr(src)
    dst_abbr = hanzi_to_abbr(dst)
    if not src_abbr or not dst_abbr:
        notice = "不支持的转换类型，请使用“简”、“繁”、“正”、“港”、“日”等。"
        if src_abbr:
            notice = convert(notice, "s", src_abbr)
        await evt.send(await UniMessage().text(notice).export())
        return
    
    converted = convert(to_convert, src_abbr, dst_abbr)

    converted_prefix = convert("转换结果", "s", dst_abbr)

    await evt.send(await UniMessage().text(f"{converted_prefix}：{converted}").export())

shuo = ["说","說"]

full_name_type = ["简体","簡體","繁體","繁体","正體","正体","港話","港话","日文"]

combined_list = [f"{a}{b}" for a in shuo for b in full_name_type]

compiled_str_2 = "|".join(combined_list)

evt = on_alconna(
    Alconna(
        f"re:({compiled_str_2})",
        Args["source?", str]
    ),
    use_cmd_start=True,
    use_cmd_sep=False,
    skip_for_unmatch=True,
)

@evt.handle()
async def _(msg: UniMsg, event: BaseEvent, source: Optional[str] = None):
    if isinstance(event, DiscordMessageEvent):
        content = event.get_message().extract_plain_text()
    else:
        content = event.get_message().extract_plain_text()

    prefix = content.split()[0]
    to_convert = ""
    # 如果回复了消息，则转换回复的内容
    if(source is None):
        if event.reply:
            to_convert = event.reply.message.extract_plain_text()
            if not to_convert:
                return
        else:
            return
    else:
        to_convert = source
    # 获取目标转换类型
    dst = ""
    match prefix:
        case "说简体" | "說簡體" | "说簡體" | "說简体":
            dst = "简"
        case "說繁體" | "说繁体" | "說繁体" | "说繁體":
            dst = "繁"
        case "說正體" | "说正体" | "說正体" | "说正體":
            dst = "正"
        case "說港話" | "说港话" | "說港话" | "说港話":
            dst = "港"
        case "說日文" | "说日文":
            dst = "日"
    dst_abbr = hanzi_to_abbr(dst)
    if not dst_abbr:
        notice = "不支持的转换类型，请使用“简体”、“繁體”、“正體”、“港話”、“日文”等。"
        await evt.send(await UniMessage().text(notice).export())
        return
    # 循环，将源语言一次次转换为目标语言
    current_text = to_convert
    for src_abbr in ["s","hk","jp","tw","t"]:
        if src_abbr != dst_abbr:
            current_text = convert(current_text, src_abbr, dst_abbr)

    converted_prefix = convert("转换结果", "s", dst_abbr)

    await evt.send(await UniMessage().text(f"{converted_prefix}：{current_text}").export())

def random_char(char: str) -> str:
    dst_abbr = random.choice(["s","t","hk","jp","tw"])
    for src_abbr in ["s","hk","jp","tw","t"]:
        if src_abbr != dst_abbr:
            char = convert(char, src_abbr, dst_abbr)
    return char

def random_string(text: str) -> str:
    final_text = ""
    for char in text:
        final_text += random_char(char)
    return final_text

random_match = ["混乱字形","混亂字形","乱数字形","亂數字形","ランダム字形"]

evt = on_alconna(
    Alconna(
        f"re:({'|'.join(random_match)})",
        Args["source?", str]
    ),
    use_cmd_start=True,
    use_cmd_sep=False,
    skip_for_unmatch=True,
)
@evt.handle()
async def _(msg: UniMsg, event: BaseEvent, source: Optional[str] = None):
    if isinstance(event, DiscordMessageEvent):
        content = event.get_message().extract_plain_text()
    else:
        content = event.get_message().extract_plain_text()

    prefix = content.split()[0]
    to_convert = ""
    # 如果回复了消息，则转换回复的内容
    if(source is None):
        if event.reply:
            to_convert = event.reply.message.extract_plain_text()
            if not to_convert:
                return
        else:
            return
    else:
        to_convert = source

    final_text = ""
    final_text = random_string(to_convert)
    converted_prefix = convert(random_string("转换结果"), "s", "s")

    await evt.send(await UniMessage().text(f"{converted_prefix}：{final_text}").export())