import time
from typing import Literal, Union

from nonebot.adapters.onebot.v11.bot import Bot
from nonebot.adapters.onebot.v11.exception import ActionFailed
from nonebot.adapters.onebot.v11.message import Message
from nonebot.log import logger

from .plugin_config import plugin_config
from .utils.get_bot import refresh_bots

QUEUE: list[
    tuple[
        Bot,
        int,
        Literal["private", "group", "group-forward"],
        Union[str, Message],
        int,
    ]
] = []
LAST_SEND_TIME = time.time()


async def _do_send(
    bot: "Bot",
    user: int,
    user_type: Literal["group", "private", "group-forward"],
    msg: Union[str, Message],
):
    try:
        if user_type == "group":
            await bot.send_group_msg(group_id=user, message=msg)
        elif user_type == "private":
            await bot.send_private_msg(user_id=user, message=msg)
        elif user_type == "group-forward":
            await bot.send_group_forward_msg(group_id=user, messages=msg)
    except ActionFailed:
        await refresh_bots()
        logger.warning(f"send msg failed, refresh bots")


async def do_send_msgs():
    global LAST_SEND_TIME
    if time.time() - LAST_SEND_TIME < 1.5:
        return
    if QUEUE:
        bot, user, user_type, msg, retry_time = QUEUE.pop(0)
        try:
            await _do_send(bot, user, user_type, msg)
        except Exception as e:
            if retry_time > 0:
                QUEUE.insert(0, (bot, user, user_type, msg, retry_time - 1))
            else:
                msg_str = str(msg)
                if len(msg_str) > 50:
                    msg_str = msg_str[:50] + "..."
                logger.warning(f"send msg err {e} {msg_str}")
        LAST_SEND_TIME = time.time()


async def _send_msgs_dispatch(
    bot: Bot,
    user,
    user_type: Literal["private", "group", "group-forward"],
    msg: Union[str, Message],
):
    if plugin_config.bison_use_queue:
        QUEUE.append((bot, user, user_type, msg, plugin_config.bison_resend_times))
    else:
        await _do_send(bot, user, user_type, msg)


async def send_msgs(
    bot: Bot, user, user_type: Literal["private", "group"], msgs: list[Message]
):
    if not plugin_config.bison_use_pic_merge or user_type == "private":
        for msg in msgs:
            await _send_msgs_dispatch(bot, user, user_type, msg)
        return
    msgs = msgs.copy()
    if plugin_config.bison_use_pic_merge == 1:
        await _send_msgs_dispatch(bot, user, "group", msgs.pop(0))
    if msgs:
        if len(msgs) == 1:  # 只有一条消息序列就不合并转发
            await _send_msgs_dispatch(bot, user, "group", msgs.pop(0))
        else:
            group_bot_info = await bot.get_group_member_info(
                group_id=user, user_id=int(bot.self_id), no_cache=True
            )  # 调用api获取群内bot的相关参数
            # forward_msg = Message(
            #     [
            #         MessageSegment.node_custom(
            #             group_bot_info["user_id"],
            #             nickname=group_bot_info["card"] or group_bot_info["nickname"],
            #             content=msg,
            #         )
            #         for msg in msgs
            #     ]
            # )
            # FIXME: Because of https://github.com/nonebot/adapter-onebot/issues/9

            forward_msg = [
                {
                    "type": "node",
                    "data": {
                        "name": group_bot_info["card"] or group_bot_info["nickname"],
                        "uin": group_bot_info["user_id"],
                        "content": msg,
                    },
                }
                for msg in msgs
            ]

            await _send_msgs_dispatch(bot, user, "group-forward", forward_msg)