# FIXME: pretty_name add it
# TODO: allow adding custom constraints

from typing import TYPE_CHECKING, Type

if TYPE_CHECKING:
    from .plugin_manager import PluginManager


def normalize_to_list_or_none(obj):
    pass


DEFAULT_VERSION = "0.0.1"
DEFAULT_ORDER = 50


def validate(attr_name, value, expected_types):
    """Validate attribute type or allow None."""
    if value is not None and not isinstance(value, expected_types):
        raise ValueError(
            f"Attribute '{attr_name}' must be of type {expected_types}, got {type(value).__name__}."
        )
    return value


def validate_or_default(attr_name, value, expected_types, default):
    """Validate attribute type or use default if None."""
    if value is None:
        return default
    return validate(attr_name, value, expected_types)


class Metadata:
    def __init__(
        self,
        *,
        version: None | str = None,
        authors: None | list[str] = None,
        description: None | str = None,
        category: None | str = None,
        sub_category: None | str = None,
        tags: None | str | list[str] = None,
        order: None | int | float = None,
        dependencies: None | list[str] = None,
        exe_dependencies: None | list[str] = None,
        plugin_dependencies: None | list[str] = None,
        is_home_plugin: None | bool = None,
    ):
        # TODO: double check validation (generated by LLM)
        self.category = category
        self.sub_category = sub_category
        self.tags = tags
        self.version = validate_or_default("version", version, (str,), DEFAULT_VERSION)
        self.order = validate_or_default("order", order, (int, float), DEFAULT_ORDER)
        self.description = validate("description", description, (str, None))
        self.authors = validate_or_default("authors", authors, (list,), [])
        self.dependencies = validate_or_default(
            "dependencies", dependencies, (list,), []
        )
        self.exe_dependencies = validate_or_default(
            "exe_dependencies", exe_dependencies, (list,), []
        )
        self.plugin_dependencies = validate_or_default(
            "plugin_dependencies", plugin_dependencies, (list,), []
        )
        self.is_home_plugin = validate_or_default(
            "is_home_plugin", is_home_plugin, (bool,), False
        )
        self.plugin_manager: "PluginManager" = None

    @property
    def base_plugin(self) -> Type:
        return self.plugin_manager.base_plugin


# Get the list of all attributes for Metadata
METADATA_ATTRIBUTES_NAMES = {e for e in dir(Metadata()) if not e.startswith("__")}


# TODO: not yet used
from importlib.metadata import PackageNotFoundError, distribution


def is_installed(package_name):
    try:
        distribution(package_name)  # Checks if the package is installed
        return True
    except PackageNotFoundError:
        return False
