import os
from typing import List

__version__ = "1.0.0"


class AppDataManager:
    """管理本地应用程序数据的类"""

    def __init__(self, namespace: str) -> None:
        """
        初始化AppDataManager

        Args:
            namespace: 命名空间，用于隔离不同应用的数据
        """
        self._namespace = namespace
        self._path = os.path.join(os.environ.get("LOCALAPPDATA"), namespace)
        if not os.path.exists(self._path):
            os.mkdir(self._path)

    def add_data(self, filename: str, data: str) -> None:
        """
        添加/更新数据文件

        Args:
            filename: 文件名
            data: 要写入的数据内容
        """
        with open(os.path.join(self._path, filename), "w", encoding="utf-8") as f:
            f.write(data)

    def get_data(self, filename: str, default: str = "") -> str:
        """
        获取数据文件内容

        Args:
            filename: 文件名
            default: 文件不存在时的默认值

        Returns:
            文件内容字符串
        """
        if os.path.exists(os.path.join(self._path, filename)):
            with open(os.path.join(self._path, filename), "r", encoding="utf-8") as f:
                data = f.read()
            return data
        else:
            if isinstance(default, type) and issubclass(default, Exception):
                raise default(f"File {filename} not found")
            return default

    def del_data(self, filename: str) -> None:
        """
        删除指定数据文件

        Args:
            filename: 要删除的文件名
        """
        if os.path.exists(os.path.join(self._path, filename)):
            os.remove(os.path.join(self._path, filename))

    def clear_all_data(self) -> None:
        """
        清空命名空间下的所有数据文件（不删除文件夹本身）
        """
        # 遍历并删除所有文件
        for filename in os.listdir(self._path):
            file_path = os.path.join(self._path, filename)
            if os.path.isfile(file_path):
                os.remove(file_path)

    def exists(self, filename: str) -> bool:
        """
        检查指定文件是否存在

        Args:
            filename: 要检查的文件名

        Returns:
            文件是否存在
        """
        return os.path.exists(os.path.join(self._path, filename))

    def get_file_path(self, filename: str) -> str:
        """
        获取文件的完整路径

        Args:
            filename: 文件名

        Returns:
            文件的完整绝对路径
        """
        return os.path.join(self._path, filename)

    def __getitem__(self, key):
        return self.get_data(key)

    def __setitem__(self, key, value):
        self.add_data(key, value)

    def __getattr__(self, name):
        return self.get_data(name, AttributeError)

    def __setattr__(self, name, value):
        if name in ["_namespace", "_path"]:
            super().__setattr__(name, value)
            return
        self.add_data(name, value)

    def __delitem__(self, key):
        self.del_data(key)

    def __delattr__(self, name):
        self.del_data(name)

    def __dir__(self) -> List[str]:
        # 获取父类的 dir
        parent_dir = super().__dir__()

        # 获取实例的所有属性（包括方法）
        instance_attrs = list(self.__dict__.keys())

        # 获取类的所有方法（包括自定义的）
        class_methods = [
            attr
            for attr in dir(self.__class__)
            if callable(getattr(self.__class__, attr)) and not attr.startswith("_")
        ]

        return sorted(set(self.datas + parent_dir + instance_attrs + class_methods))

    def __iter__(self):
        yield from self.datas

    def items(self):
        for i in self.datas:
            yield i, self.get_data(i)

    def __contains__(self, filename: str) -> bool:
        """
        使用 'in' 运算符检查文件是否存在

        Example:
            if "config.json" in data_manager:
                print("文件存在")

        Args:
            filename: 判断是否存在的文件名

        Returns:
            文件是否存在
        """
        return self.exists(filename)

    def __len__(self) -> int:
        """
        获取命名空间下的文件数量

        Returns:
            文件数量
        """
        return len(self.datas)

    def __eq__(self, other) -> bool:
        """
        判断两个DataManager是否管理相同的命名空间

        Args:
            other: 要比较的对象

        Returns:
            是否相等
        """
        if isinstance(other, AppDataManager):
            return self._namespace == other._namespace
        return False

    def __hash__(self) -> int:
        """
        基于命名空间生成哈希值，用于集合和字典键

        Returns:
            哈希值
        """
        return hash(self._namespace)

    def __repr__(self) -> str:
        """
        对象的正式字符串表示，用于调试

        Returns:
            对象表示字符串
        """
        return f"AppDataManager(namespace='{self._namespace}')"

    def __str__(self) -> str:
        """
        对象的友好字符串表示

        Returns:
            友好字符串
        """
        return f"AppDataManager[{self._namespace}]({len(self)} files)"

    @property
    def namespace(self) -> str:
        """
        获取命名空间

        Returns:
            命名空间字符串
        """
        return self._namespace

    @property
    def data_folder(self) -> str:
        """
        获取数据文件夹路径

        Returns:
            数据文件夹绝对路径
        """
        return self._path

    @property
    def datas(self) -> List[str]:
        """
        列出命名空间下的所有数据文件名

        Returns:
            文件名列表
        """
        try:
            if os.path.exists(self._path):
                return [
                    f
                    for f in os.listdir(self._path)
                    if os.path.isfile(os.path.join(self._path, f))
                ]
        except Exception:
            pass
        return []


__all__ = ["AppDataManager"]
