"""Meter catalogue integrity."""

from __future__ import annotations

import pytest

from tokencalc.defaults import DEFAULT_METERS, DEFAULT_PRICING
from tokencalc.meters import Confidence, MeterType, TokenMeter, TokenPricing


def test_all_spec_meters_present():
    expected = {
        # Voice / Bot
        "Voice Bot", "Digital Bot",
        # Virtual Agent
        "Virtual Agent (legacy)", "Agentic Virtual Agent",
        # Agent Copilot (named + concurrent)
        "Agent Copilot [named]", "Agent Copilot [concurrent]",
        # AI Quality / Analytics
        "AI Scoring", "AI Summary & Insights",
        # Speech & Text Analytics (named + concurrent)
        "Speech & Text Analytics [named]", "Speech & Text Analytics [concurrent]",
        # Routing
        "Predictive Routing",
        # Messaging
        "Direct Messaging", "Social Listening", "Social Responses",
        # Language
        "AI Translate",
        # Genesys Cloud Copilot
        "Genesys Cloud Copilot",
        # Email AI (rate TBD; Auto-Suggest is inside Agent Copilot)
        "Email AI (Auto-Respond)",
    }
    assert expected == set(DEFAULT_METERS)


def test_confirmed_rates():
    m = DEFAULT_METERS
    assert m["Voice Bot"].units_per_token == 17
    assert m["Voice Bot"].tokens_per_unit == pytest.approx(0.0588, abs=1e-3)
    assert m["Digital Bot"].units_per_token == 51
    assert m["Agentic Virtual Agent"].tokens_per_unit == 1.2
    assert m["AI Summary & Insights"].tokens_per_unit == 0.02
    assert m["Direct Messaging"].units_per_token == 400
    # Named variants
    assert m["Speech & Text Analytics [named]"].tokens_per_unit == 30
    assert m["Speech & Text Analytics [concurrent]"].tokens_per_unit == 45
    assert m["Agent Copilot [named]"].tokens_per_unit == 40
    assert m["Agent Copilot [concurrent]"].tokens_per_unit == 60
    # AI Translate is now a confirmed consumption meter
    assert m["AI Translate"].tokens_per_unit == 0.5
    assert m["AI Translate"].units_per_token == 2
    assert m["AI Translate"].confidence is Confidence.CONFIRMED
    # New meters
    assert m["AI Scoring"].units_per_token == 20
    assert m["Predictive Routing"].units_per_token == 17
    assert m["Genesys Cloud Copilot"].units_per_token == 20


def test_unknown_meters_flagged():
    unknown = {f for f, m in DEFAULT_METERS.items() if m.confidence is Confidence.UNKNOWN}
    assert unknown == {"Email AI (Auto-Respond)"}
    assert Confidence.UNKNOWN.icon == "🔴"
    assert Confidence.CONFIRMED.icon == "🟢"


def test_inverse_consistency_validated():
    with pytest.raises(ValueError, match="not inverses"):
        TokenMeter(
            feature="Bad", meter_type=MeterType.PER_MINUTE,
            units_per_token=10, tokens_per_unit=0.5,
            confidence=Confidence.ESTIMATED, notes="",
        )


def test_every_confirmed_meter_has_source_url():
    for m in DEFAULT_METERS.values():
        if m.confidence is Confidence.CONFIRMED:
            assert m.source_url, f"{m.feature} missing source URL"


def test_pricing_effective_rate():
    p = TokenPricing(region="US", list_rate_per_token=1.0,
                     contracted_rate_per_token=0.85)
    assert p.effective_rate(use_contracted=False) == 1.0
    assert p.effective_rate(use_contracted=True) == 0.85
    # no contracted rate → falls back to list
    assert DEFAULT_PRICING["US"].effective_rate(use_contracted=True) == 1.0


def test_all_regions_priced():
    assert set(DEFAULT_PRICING) == {"US", "EU", "AU", "APAC"}
