from nonebot_plugin_htmlrender import template_to_pic
from nonebot_plugin_uninfo import Uninfo
from pydantic import BaseModel

from zhenxun.configs.config import BotConfig
from zhenxun.configs.path_config import TEMPLATE_PATH
from zhenxun.models.group_console import GroupConsole
from zhenxun.models.plugin_info import PluginInfo
from zhenxun.utils.enum import BlockType
from zhenxun.utils.platform import PlatformUtils

from ._utils import classify_plugin


class Item(BaseModel):
    plugin_name: str
    """插件名称"""


def __handle_item(plugin: PluginInfo, group: GroupConsole | None):
    """构造Item

    参数:
        plugin: PluginInfo
        group: 群组

    返回:
        Item: Item
    """
    if not plugin.status:
        if plugin.block_type == BlockType.ALL:
            plugin.name = f"{plugin.name}(不可用)"
        elif group and plugin.block_type == BlockType.GROUP:
            plugin.name = f"{plugin.name}(不可用)"
        elif not group and plugin.block_type == BlockType.PRIVATE:
            plugin.name = f"{plugin.name}(不可用)"
    elif group and f"{plugin.module}," in group.block_plugin:
        plugin.name = f"{plugin.name}(不可用)"
    return Item(plugin_name=f"{plugin.id}-{plugin.name}")


def build_plugin_data(classify: dict[str, list[Item]]) -> list[dict[str, str]]:
    """构建前端插件数据

    参数:
        classify: 插件数据

    返回:
        list[dict[str, str]]: 前端插件数据
    """
    classify = dict(sorted(classify.items(), key=lambda x: len(x[1]), reverse=True))
    menu_key = next(iter(classify.keys()))
    max_data = classify[menu_key]
    del classify[menu_key]
    plugin_list = [
        {
            "name": "主要功能" if menu in ["normal", "功能"] else menu,
            "items": value,
        }
        for menu, value in classify.items()
    ]
    plugin_list = build_line_data(plugin_list)
    plugin_list.insert(
        0,
        build_plugin_line(
            menu_key if menu_key not in ["normal", "功能"] else "主要功能",
            max_data,
            30,
            100,
            True,
        ),
    )
    return plugin_list


def build_plugin_line(
    name: str, items: list, left: int, width: int | None = None, is_max: bool = False
) -> dict:
    """构造插件行数据

    参数:
        name: 菜单名称
        items: 插件名称列表
        left: 左边距
        width: 总插件长度.
        is_max: 是否为最大长度的插件菜单

    返回:
        dict: 插件数据
    """
    _plugins = []
    width = width or 50
    if len(items) // 2 > 6 or is_max:
        width = 100
        plugin_list1 = []
        plugin_list2 = []
        for i in range(len(items)):
            if i % 2:
                plugin_list1.append(items[i])
            else:
                plugin_list2.append(items[i])
        _plugins = [(30, 50, plugin_list1), (0, 50, plugin_list2)]
    else:
        _plugins = [(left, 100, items)]
    return {"name": name, "items": _plugins, "width": width}


def build_line_data(plugin_list: list[dict]) -> list[dict]:
    """构造插件数据

    参数:
        plugin_list: 插件列表

    返回:
        list[dict]: 插件数据
    """
    left = 30
    data = []
    for plugin in plugin_list:
        data.append(build_plugin_line(plugin["name"], plugin["items"], left))
        if len(plugin["items"]) // 2 <= 6:
            left = 15 if left == 30 else 30
    return data


async def build_zhenxun_image(session: Uninfo, group_id: str | None) -> bytes:
    """构造真寻帮助图片

    参数:
        bot_id: bot_id
        group_id: 群号
    """
    classify = await classify_plugin(group_id, __handle_item)
    plugin_list = build_plugin_data(classify)
    platform = PlatformUtils.get_platform(session)
    bot_id = BotConfig.get_qbot_uid(session.self_id) or session.self_id
    bot_ava = PlatformUtils.get_user_avatar_url(bot_id, platform)
    return await template_to_pic(
        template_path=str((TEMPLATE_PATH / "ss_menu").absolute()),
        template_name="main.html",
        templates={
            "data": {
                "plugin_list": plugin_list,
                "ava": bot_ava,
            }
        },
        pages={
            "viewport": {"width": 637, "height": 453},
            "base_url": f"file://{TEMPLATE_PATH}",
        },
        wait=2,
    )
