"""Result of a license validation request."""

from __future__ import annotations

from dataclasses import dataclass
from typing import Any


@dataclass(frozen=True)
class ValidationResult:
    """Result of a license validation request.

    The validation endpoint always returns HTTP 200, even for invalid licenses.
    Check ``is_valid()`` to determine if the license is valid.
    """

    valid: bool
    license: dict[str, Any] | None = None
    activated: bool | None = None
    activation: dict[str, Any] | None = None
    offline_token: str | None = None
    error: dict[str, str] | None = None

    def is_valid(self) -> bool:
        """Whether the license is valid."""
        return self.valid

    def is_active(self) -> bool:
        """Whether the license status is 'active'."""
        if self.license is None:
            return False
        return self.license.get("status") == "active"

    def is_expired(self) -> bool:
        """Whether the license is expired.

        Checks the ``is_expired`` field on full license data first,
        then falls back to checking if the status is 'expired'.
        """
        if self.license is None:
            return False
        if self.valid and "is_expired" in self.license:
            return bool(self.license["is_expired"])
        return self.license.get("status") == "expired"

    def is_revoked(self) -> bool:
        """Whether the license status is 'revoked'."""
        if self.license is None:
            return False
        return self.license.get("status") == "revoked"

    def has_entitlement(self, key: str) -> bool:
        """Check if the license has a specific entitlement key."""
        if not self.valid or self.license is None:
            return False
        entitlements = self.license.get("entitlements")
        if entitlements is None:
            return False
        return key in entitlements

    def get_entitlement(self, key: str, default: Any = None) -> Any:
        """Get the value of an entitlement, or a default if not present."""
        if not self.valid or self.license is None:
            return default
        entitlements = self.license.get("entitlements")
        if entitlements is None:
            return default
        return entitlements.get(key, default)

    def get_remaining_activations(self) -> int | None:
        """Get the number of remaining activations, or None if no limit.

        Only available for valid licenses with full license data.
        """
        if not self.valid or self.license is None:
            return None
        limit = self.license.get("activation_limit")
        if limit is None:
            return None
        count = self.license.get("activation_count", 0)
        return max(0, limit - count)

    def to_dict(self) -> dict[str, Any]:
        """Serialize to a plain dictionary."""
        result: dict[str, Any] = {"valid": self.valid}
        if self.license is not None:
            result["license"] = self.license
        if self.activated is not None:
            result["activated"] = self.activated
        if self.activation is not None:
            result["activation"] = self.activation
        if self.offline_token is not None:
            result["offline_token"] = self.offline_token
        if self.error is not None:
            result["error"] = self.error
        return result
