from src.domain.runtime_ai.catalog import (
    DISPLAY_SCALE,
    estimate_livechat_millicredits,
    estimate_voice_millicredits,
    millicredits_for_usage,
    millicredits_to_credits,
)


def test_displayed_credit_scale() -> None:
    assert DISPLAY_SCALE == 1_000
    assert millicredits_to_credits(1_000) == 1.0


def test_livechat_usage_is_normalized_not_raw_tokens() -> None:
    charged = millicredits_for_usage(
        provider="openai",
        model="gpt-4.1-mini",
        input_tokens=800,
        output_tokens=200,
    )
    assert charged == 2


def test_zero_usage_does_not_invent_charges() -> None:
    assert millicredits_for_usage(provider="openai", model="gpt-4.1-mini") == 0


def test_unknown_model_falls_back_to_default_chat_rate() -> None:
    known = millicredits_for_usage(provider="openai", model="gpt-4.1-mini", input_tokens=1_000_000)
    unknown = millicredits_for_usage(provider="openai", model="some-future-mini", input_tokens=1_000_000)
    assert known == 400
    assert unknown == 400


def test_livechat_reservation_covers_max_tokens() -> None:
    reserved = estimate_livechat_millicredits("openai", "gpt-4.1-mini", 512)
    actual = millicredits_for_usage(
        provider="openai", model="gpt-4.1-mini", input_tokens=800, output_tokens=512
    )
    assert reserved >= actual


def test_voice_estimate_uses_audio_meters() -> None:
    reserved = estimate_voice_millicredits("gpt-4o-realtime-preview", 1)
    actual = millicredits_for_usage(
        provider="openai",
        model="gpt-4o-realtime-preview",
        audio_input_seconds=60,
        audio_output_seconds=60,
    )
    assert reserved == actual
    assert reserved == 60 * 1_000 + 60 * 2_000


def test_voice_tokens_are_not_double_counted_with_zero_audio() -> None:
    charged = millicredits_for_usage(
        provider="openai",
        model="gpt-4o-realtime-preview",
        input_tokens=1_000_000,
        output_tokens=0,
        audio_input_seconds=0,
        audio_output_seconds=0,
    )
    assert charged == 5_000
