"""
Genesys AI Experience token meters and pricing.

Every meter carries a :class:`Confidence` flag so the UI can distinguish
published Genesys rates from estimates and unknowns. Rates here are
*planning inputs* — this tool explicitly does not replace contractual
pricing (see README, Non-Goals).
"""

from __future__ import annotations

from dataclasses import dataclass
from enum import Enum


class MeterType(Enum):
    PER_USER_PER_MONTH = "per_user_per_month"
    PER_INTERACTION = "per_interaction"
    PER_MINUTE = "per_minute"
    PER_MESSAGE = "per_message"
    PER_SUMMARY = "per_summary"


class Confidence(Enum):
    CONFIRMED = "confirmed"  # published Genesys rate
    ESTIMATED = "estimated"  # reasonable industry assumption
    UNKNOWN = "unknown"      # rate not yet sourced

    @property
    def icon(self) -> str:
        return {"confirmed": "🟢", "estimated": "🟡", "unknown": "🔴"}[self.value]


@dataclass
class TokenMeter:
    """One Genesys AI feature's token meter.

    ``units_per_token`` and ``tokens_per_unit`` are inverses; both are
    stored because the UI shows whichever reads more naturally (e.g.
    "17 minutes per token" vs "0.0588 tokens per minute"). For
    PER_USER_PER_MONTH meters ``units_per_token`` is 0.0 (n/a) and
    ``tokens_per_unit`` is the flat tokens/user/month figure.
    """

    feature: str
    meter_type: MeterType
    units_per_token: float
    tokens_per_unit: float
    confidence: Confidence
    notes: str
    source_url: str | None = None

    def __post_init__(self) -> None:
        if self.tokens_per_unit < 0:
            raise ValueError(f"{self.feature}: tokens_per_unit must be >= 0")
        if (
            self.meter_type is not MeterType.PER_USER_PER_MONTH
            and self.units_per_token > 0
            and self.tokens_per_unit > 0
        ):
            product = self.units_per_token * self.tokens_per_unit
            if not 0.95 <= product <= 1.05:
                raise ValueError(
                    f"{self.feature}: units_per_token ({self.units_per_token}) and "
                    f"tokens_per_unit ({self.tokens_per_unit}) are not inverses"
                )


@dataclass
class TokenPricing:
    """Per-region token pricing. Default is US list at $1/token."""

    region: str  # "US", "AU", "EU", "APAC"
    list_rate_per_token: float = 1.0
    contracted_rate_per_token: float | None = None
    prepay_commit_tokens: int | None = None
    overage_rate_per_token: float | None = None

    def __post_init__(self) -> None:
        if self.list_rate_per_token < 0:
            raise ValueError(f"{self.region}: list rate must be >= 0")

    def effective_rate(self, use_contracted: bool = False) -> float:
        """Contracted rate when requested and known, else list rate."""
        if use_contracted and self.contracted_rate_per_token is not None:
            return self.contracted_rate_per_token
        return self.list_rate_per_token
