"""Enum class for Miele intergration."""

from enum import IntEnum
import logging
from typing import Any

_LOGGER = logging.getLogger(__name__)
completed_warnings: set[str] = set()


class MieleEnum(IntEnum):
    """Miele Enum for codes with int values."""

    # Modify the behaviour of the class when detecting a missing value:
    # Set argument missing_to_none= True when creating the subclass in order to:
    # - Log a warning that the code is missing
    # - Return None as key name
    #
    # Deprecated variant - can be removed 2025.12
    # Add a member unknown_code in order to:
    # - Log a warning that the code is missing
    # - Return 'unknown_value' as key name

    def __init_subclass__(
        cls, /, missing_to_none: bool = False, **kwargs: dict[str, Any]
    ) -> None:
        """Add default member when setting up the subclass."""
        super().__init_subclass__(**kwargs)
        if missing_to_none:
            self = int.__new__(cls)
            self._name_ = None  # pylint: disable=W0201
            self._value_ = -9999  # A dummy code value
            cls._add_member_("missing_to_none", self)

    @property
    def name(self) -> str | None:  # pylint: disable=E0102, W0236
        """Force to lower case."""
        _name = super().name.lower() if super().name is not None else None
        return _name if _name != "missing_to_none" else None

    @classmethod
    def _missing_(cls, value: object) -> Any | None:
        """Handle missing enum values."""
        if hasattr(cls, "unknown_code") or hasattr(cls, "unknown"):
            warning = (
                f"Missing {cls.__name__} code: {value} - defaulting to 'unknown_code'"
            )
            if warning not in completed_warnings:
                completed_warnings.add(warning)
                _LOGGER.warning(warning)
            return cls.unknown_code  # pylint: disable=no-member

        if hasattr(cls, "missing_to_none"):
            if value is not None:
                warning = (
                    f"Missing {cls.__name__} code: {value} - defaulting to Unknown"
                )
                if warning not in completed_warnings:
                    completed_warnings.add(warning)
                    _LOGGER.warning(warning)
            return cls.missing_to_none  # pylint: disable=no-member

        return None

    def __new__(cls, value: int, *values: int) -> Any:
        """Allow duplicate values."""
        self = int.__new__(cls)
        self._value_ = value
        for v in values:
            self._add_value_alias_(v)
        return self

    @classmethod
    def as_dict(cls) -> dict[str, int]:
        """Return a dict of enum names and values."""
        return {i.name: i.value for i in cls if i.name is not None}

    @classmethod
    def as_enum_dict(cls) -> dict[int, Any]:
        """Return a dict of enum values and enum names."""
        return {i.value: i for i in cls if i.name is not None}

    @classmethod
    def values(cls) -> list[int]:
        """Return a list of enum values."""
        return list(cls.as_dict().values())

    @classmethod
    def keys(cls) -> list[str]:
        """Return a list of enum names."""
        return list(cls.as_dict().keys())

    @classmethod
    def items(cls) -> Any:
        """Return a list of enum items."""
        return cls.as_dict().items()
