"""Enhanced TTS — the non-token line, its round-up, and its free share."""

from __future__ import annotations

import pytest
from genesyscalc.meters import Confidence
from genesyscalc.tts import (
    TTS_PRICE_PER_MILLION_CHARS,
    TTS_SOURCE,
    TTS_SOURCE_DATE,
    TTS_STANDARD_END_OF_SALE,
    TTS_STANDARD_END_OF_SUPPORT,
    TtsUsage,
    tts_cost,
    tts_free_share,
)
from genesyscalc.usage import DeflectionMix


def test_published_rates() -> None:
    assert TTS_PRICE_PER_MILLION_CHARS == {"advanced": 20.0, "standard": 5.0}


def test_source_pinned_and_distinct_from_the_tokens_article() -> None:
    """TTS has its own page and its own date — it is not a token meter."""
    from genesyscalc.ratecard import RATE_CARD_SOURCE, RATE_CARD_SOURCE_DATE

    assert TTS_SOURCE_DATE == "2026-05-22"
    assert TTS_SOURCE.endswith("genesys-enhanced-tts-pricing/")
    assert TTS_SOURCE != RATE_CARD_SOURCE
    assert TTS_SOURCE_DATE != RATE_CARD_SOURCE_DATE


def test_tts_is_published_so_confirmed() -> None:
    line = tts_cost(TtsUsage(calls_monthly=100_000))
    assert line.confidence is Confidence.CONFIRMED


def test_hand_checked_advanced_cost() -> None:
    """100,000 calls × 2,000 chars = 200M chars → 200 units × $20 = $4,000/mo."""
    line = tts_cost(TtsUsage(calls_monthly=100_000, chars_per_call=2_000))
    assert line.total_chars_monthly == pytest.approx(200_000_000.0)
    assert line.billed_millions_monthly == 200
    assert line.cost_monthly == pytest.approx(4_000.0)
    assert line.cost_annual == pytest.approx(48_000.0)


def test_hand_checked_standard_cost() -> None:
    """Same volume on standard voices: 200 × $5 = $1,000/mo."""
    line = tts_cost(
        TtsUsage(calls_monthly=100_000, chars_per_call=2_000, tier="standard")
    )
    assert line.cost_monthly == pytest.approx(1_000.0)


def test_per_million_roundup_published_examples() -> None:
    """The article's own examples: 200,000 chars = $5; 1,000,005 chars = $10.

    Both on standard voices, where the unit rate is $5.
    """
    small = tts_cost(TtsUsage(calls_monthly=1, chars_per_call=200_000, tier="standard"))
    assert small.billed_millions_monthly == 1
    assert small.cost_monthly == pytest.approx(5.0)

    just_over = tts_cost(
        TtsUsage(calls_monthly=1, chars_per_call=1_000_005, tier="standard")
    )
    assert just_over.billed_millions_monthly == 2
    assert just_over.cost_monthly == pytest.approx(10.0)


def test_free_share_tracks_the_virtual_agent_tiers() -> None:
    """Free during VA and agentic VA — bot-only deflection does not qualify."""
    mix = DeflectionMix(
        bot_only_share=0.30, virtual_agent_share=0.15, agentic_va_share=0.05
    )
    assert tts_free_share(mix) == pytest.approx(0.20)


def test_free_share_reduces_the_bill() -> None:
    """200M chars, 20% free → 160M billable → 160 × $20 = $3,200/mo."""
    mix = DeflectionMix(virtual_agent_share=0.15, agentic_va_share=0.05)
    line = tts_cost(TtsUsage(calls_monthly=100_000, chars_per_call=2_000), mix)
    assert line.free_share == pytest.approx(0.20)
    assert line.free_chars_monthly == pytest.approx(40_000_000.0)
    assert line.billable_chars_monthly == pytest.approx(160_000_000.0)
    assert line.cost_monthly == pytest.approx(3_200.0)


def test_standard_tier_warns_about_end_of_life() -> None:
    line = tts_cost(TtsUsage(calls_monthly=1_000, tier="standard"))
    assert len(line.warnings) == 1
    assert TTS_STANDARD_END_OF_SALE in line.warnings[0]
    assert TTS_STANDARD_END_OF_SUPPORT in line.warnings[0]


def test_advanced_tier_does_not_warn() -> None:
    assert tts_cost(TtsUsage(calls_monthly=1_000)).warnings == ()


def test_concession_applies_to_tts_too() -> None:
    line = tts_cost(TtsUsage(calls_monthly=100_000), concession_pct=0.25)
    assert line.cost_monthly == pytest.approx(3_000.0)


def test_zero_volume_costs_nothing() -> None:
    line = tts_cost(TtsUsage(calls_monthly=0))
    assert line.billed_millions_monthly == 0
    assert line.cost_monthly == 0.0


def test_unknown_tier_rejected() -> None:
    with pytest.raises(ValueError, match="unknown TTS tier"):
        TtsUsage(calls_monthly=1, tier="neural-ultra")
