import os
from pathlib import Path
import re
import shutil
import uuid

import nonebot
from nonebot_plugin_alconna import UniMessage, UniMsg
from nonebot_plugin_uninfo import Uninfo
import ujson as json

from zhenxun.configs.path_config import DATA_PATH
from zhenxun.services.log import logger
from zhenxun.utils._build_image import BuildImage
from zhenxun.utils._image_template import ImageTemplate
from zhenxun.utils.http_utils import AsyncHttpx
from zhenxun.utils.platform import PlatformUtils

BASE_PATH = DATA_PATH / "welcome_message"
BASE_PATH.mkdir(parents=True, exist_ok=True)

driver = nonebot.get_driver()


old_file = DATA_PATH / "custom_welcome_msg" / "custom_welcome_msg.json"
if old_file.exists():
    try:
        old_data: dict[str, str] = json.load(old_file.open(encoding="utf8"))
        for group_id, message in old_data.items():
            file = BASE_PATH / "qq" / f"{group_id}" / "text.json"
            file.parent.mkdir(parents=True, exist_ok=True)
            json.dump(
                {
                    uuid.uuid4(): {
                        "at": "[at]" in message,
                        "status": True,
                        "message": message.replace("[at]", ""),
                    }
                },
                file.open("w", encoding="utf8"),
                ensure_ascii=False,
                indent=4,
            )
            logger.debug("群欢迎消息数据迁移", group_id=group_id)
        shutil.rmtree(old_file.parent.absolute())
    except Exception as e:
        logger.error("群欢迎消息数据迁移失败...", e=e)


def migrate(path: Path):
    """数据迁移

    参数:
        path: 路径
    """
    text_file = path / "text.json"
    with text_file.open(encoding="utf8") as f:
        json_data = json.load(f)
    new_data = {}
    if "at" in json_data:
        split_msg = re.split(r"\[image:\d\]", str(json_data["message"]))
        data = []
        for i in range(len(split_msg)):
            msg = split_msg[i]
            data.append(
                {
                    "type": "text",
                    "text": msg,
                }
            )
            image_file = path / f"{i}.png"
            if image_file.exists():
                data.append(
                    {
                        "type": "image",
                        "path": str(image_file),
                    }
                )
        new_data[uuid.uuid4()] = {
            "at": json_data.get("at", False),
            "status": json_data.get("status", True),
            "message": data,
        }
    with text_file.open("w", encoding="utf8") as f:
        json.dump(new_data, f, ensure_ascii=False, indent=4)


@driver.on_startup
def _():
    """数据迁移

    参数:
        path: 存储路径
        json_data: 存储数据
    """
    flag_file = BASE_PATH / "flag.txt"
    if flag_file.exists():
        return
    logger.info("开始迁移群欢迎消息数据...")
    base_path = BASE_PATH
    path_list = []
    for platform in os.listdir(BASE_PATH):
        base_path = base_path / platform
        for group_id in os.listdir(base_path):
            group_path = base_path / group_id
            is_channel = False
            for file in os.listdir(group_path):
                inner_file = group_path / file
                if inner_file.is_dir():
                    path_list.append(inner_file)
                    is_channel = True
            if not is_channel:
                path_list.append(group_path)
    if path_list:
        for path in path_list:
            migrate(path)
    if not flag_file.exists():
        flag_file.touch()
    logger.success("迁移群欢迎消息数据完成!", "")


class Manager:
    @classmethod
    def __get_data(cls, session: Uninfo) -> dict | None:
        """获取存储数据

        参数:
            session: Uninfo

        返回:
            dict | None: 欢迎消息数据
        """
        if not session.group:
            return None
        path = cls.get_path(session)
        if not path:
            return None
        file = path / "text.json"
        if not file.exists():
            return None
        with file.open(encoding="utf8") as f:
            return json.load(f)

    @classmethod
    def get_path(cls, session: Uninfo) -> Path | None:
        """根据Session获取存储路径

        参数:
            session: Uninfo:

        返回:
            Path: 存储路径
        """
        if not session.group:
            return None
        platform = PlatformUtils.get_platform(session)
        path = BASE_PATH / f"{platform}" / f"{session.group.id}"
        if session.group.parent:
            path = (
                BASE_PATH
                / f"{platform}"
                / f"{session.group.parent.id}"
                / f"{session.group.id}"
            )
        path.mkdir(parents=True, exist_ok=True)
        return path

    @classmethod
    async def save(cls, path: Path, message: UniMsg):
        """保存群欢迎消息

        参数:
            path: 存储路径
            message: 消息内容
        """
        file = path / "text.json"
        json_data = {}
        if file.exists():
            with file.open(encoding="utf8") as f:
                json_data = json.load(f)
        data = []
        is_at = False
        for msg in message.dump(True):
            if msg["type"] == "image":
                image_file = path / f"{uuid.uuid4()}.png"
                await AsyncHttpx.download_file(msg["url"], image_file)
                msg["path"] = str(image_file)
            if not is_at and msg["type"] == "text" and "-at" in msg["text"]:
                msg["text"] = msg["text"].replace("-at", "", 1).strip()
                is_at = True
            data.append(msg)
        json_data[str(uuid.uuid4())] = {"at": is_at, "status": True, "message": data}
        with file.open("w", encoding="utf8") as f:
            json.dump(json_data, f, ensure_ascii=False, indent=4)

    @classmethod
    async def get_group_message(
        cls, session: Uninfo, idx: int | None
    ) -> BuildImage | UniMessage | None:
        """获取群欢迎消息

        参数:
            session: Uninfo
            idx: 指定id

        返回:
            list: 消息内容
        """
        json_data = cls.__get_data(session)
        if not json_data:
            return None
        if idx is not None:
            key_list = list(json_data.keys())
            if idx < 0 or idx > len(key_list):
                return None
            return UniMessage().load(json_data[key_list[idx]]["message"])
        else:
            msg_list = []
            for i, uid in enumerate(json_data):
                msg_data = json_data[uid]
                msg_list.append(
                    [
                        i,
                        "开启" if msg_data["status"] else "关闭",
                        "是" if msg_data["at"] else "否",
                        str(UniMessage().load(msg_data["message"])),
                    ]
                )
            if not msg_list:
                return None
            column_name = ["ID", "状态", "是否@", "消息"]
            return await ImageTemplate.table_page(
                "群欢迎消息", session.group.id, column_name, msg_list
            )

    @classmethod
    async def delete_group_message(cls, session: Uninfo, idx: int) -> str | None:
        """获取群欢迎消息

        参数:
            session: EventSession:
            id: 消息ID

        返回:
            list: 消息内容
        """
        json_data = cls.__get_data(session)
        if not json_data:
            return None
        key_list = list(json_data.keys())
        if idx < 0 or idx >= len(key_list):
            return None
        old_msg = str(UniMessage().load(json_data[key_list[idx]]["message"]))
        for msg in json_data[key_list[idx]]["message"]:
            if msg["type"] == "image" and msg["path"]:
                image_path = Path(msg["path"])
                if image_path.exists():
                    image_path.unlink()
        del json_data[key_list[idx]]
        with file.open("w", encoding="utf8") as f:
            json.dump(json_data, f, ensure_ascii=False, indent=4)
        return f"删除群组欢迎消息成功！消息内容: {old_msg}"
