"""Cost engine — including the spec's acceptance numbers."""

from __future__ import annotations

import pytest

from tokencalc.cost_model import (
    calculate_consumption_ai_cost,
    calculate_per_user_ai_cost,
    calculate_platform_license_cost,
    calculate_total_cost,
)
from tokencalc.defaults import (
    CONTRACTED_NAMED_USERS,
    CTM_DEFAULT_FEATURE_SCOPES,
    CTM_DEFAULT_SITES,
    DEFAULT_METERS,
    DEFAULT_PRICING,
)
from tokencalc.inputs import FeatureScope, SiteInput
from tokencalc.scenarios import get_scenario

ALL_SITES = [s.site_name for s in CTM_DEFAULT_SITES]


def _scope(feature, sites=None, **kw):
    return FeatureScope(feature, sites or ALL_SITES, **kw)


def test_default_sites_match_contracted_users():
    assert sum(s.named_users for s in CTM_DEFAULT_SITES) == CONTRACTED_NAMED_USERS


def test_sta_acceptance_number():
    """2,088 users × 30 tokens × 12 months × $1 = $751,680."""
    df = calculate_per_user_ai_cost(
        CTM_DEFAULT_SITES, _scope("Speech & Text Analytics [named]"),
        DEFAULT_METERS["Speech & Text Analytics [named]"], DEFAULT_PRICING,
    )
    assert df["annual_cost"].sum() == pytest.approx(751_680)


def test_agent_copilot_acceptance_number():
    """2,088 users × 40 tokens × 12 months × $1 = $1,002,240."""
    df = calculate_per_user_ai_cost(
        CTM_DEFAULT_SITES, _scope("Agent Copilot [named]"),
        DEFAULT_METERS["Agent Copilot [named]"], DEFAULT_PRICING,
    )
    assert df["annual_cost"].sum() == pytest.approx(1_002_240)


def test_ai_translate_not_active_before_phase():
    """AI Translate (consumption meter) produces zero cost before its phase."""
    scenario = get_scenario("realistic")
    apac_sites = [s.site_name for s in CTM_DEFAULT_SITES if s.region_pricing == "APAC"]
    df = calculate_consumption_ai_cost(
        CTM_DEFAULT_SITES,
        _scope("AI Translate", apac_sites, phase=3),
        DEFAULT_METERS["AI Translate"], scenario, DEFAULT_PRICING, year=2,
    )
    assert df["annual_cost"].sum() == 0


def test_copilot_covers_supervisor_summary():
    """Rule 1: AI Summary cost is zero at Copilot sites."""
    scenario = get_scenario("realistic")
    total = calculate_total_cost(
        CTM_DEFAULT_SITES,
        [
            _scope("Agent Copilot [named]"),
            _scope("AI Summary & Insights"),
        ],
        DEFAULT_METERS, DEFAULT_PRICING, scenario, year=1,
        include_platform=False,
    )
    summary_row = total[total["cost_line"] == "AI Summary & Insights"].iloc[0]
    assert summary_row["annual_cost"] == 0
    # Without Copilot the same line costs real money.
    total2 = calculate_total_cost(
        CTM_DEFAULT_SITES,
        [_scope("AI Summary & Insights")],
        DEFAULT_METERS, DEFAULT_PRICING, scenario, year=1,
        include_platform=False,
    )
    assert total2[total2["cost_line"] == "AI Summary & Insights"].iloc[0][
        "annual_cost"
    ] > 0


def test_consumption_tokens_rounded_up_monthly():
    """Rule 2: ceil on monthly site token totals."""
    site = SiteInput(
        "Tiny", "US", agents=5, supervisors=0,
        voice_volume_monthly=100, email_volume_monthly=0,
        chat_volume_monthly=0, sms_volume_monthly=0,
        voice_aht_seconds=300, email_aht_seconds=600,
        chat_aht_seconds=480, voice_acw_seconds=60,
        fully_loaded_agent_cost_annual=65_000,
        fully_loaded_supervisor_cost_annual=95_000,
    )
    # realistic: 100 calls × 35% × 1.5 min = 52.5 min × (1/17) = 3.088
    # tokens × 70% Y1 ramp applied to units → 36.75 min → 2.16 tokens → ceil 3
    df = calculate_consumption_ai_cost(
        [site], FeatureScope("Voice Bot", ["Tiny"]),
        DEFAULT_METERS["Voice Bot"], "realistic", DEFAULT_PRICING, year=1,
    )
    assert df.iloc[0]["tokens_monthly"] == 3
    assert df.iloc[0]["annual_cost"] == pytest.approx(3 * 12 * 1.0)


def test_predictive_routing_consumption():
    """1,700 calls/mo ÷ 17 per token = 100 tokens/mo → $1,200/yr (year 2, no ramp)."""
    site = SiteInput(
        "Tiny", "US", agents=5, supervisors=0,
        voice_volume_monthly=1_700, email_volume_monthly=0,
        chat_volume_monthly=0, sms_volume_monthly=0,
        voice_aht_seconds=300, email_aht_seconds=600,
        chat_aht_seconds=480, voice_acw_seconds=60,
        fully_loaded_agent_cost_annual=65_000,
        fully_loaded_supervisor_cost_annual=95_000,
    )
    df = calculate_consumption_ai_cost(
        [site], FeatureScope("Predictive Routing", ["Tiny"]),
        DEFAULT_METERS["Predictive Routing"], "realistic", DEFAULT_PRICING, year=2,
    )
    assert df.iloc[0]["tokens_monthly"] == 100
    assert df.iloc[0]["annual_cost"] == pytest.approx(1_200)


def test_predictive_routing_eligibility_and_total_cost():
    """eligibility_pct halves the routed volume; total_cost handles the scope."""
    site = SiteInput(
        "Tiny", "US", agents=5, supervisors=0,
        voice_volume_monthly=1_700, email_volume_monthly=0,
        chat_volume_monthly=0, sms_volume_monthly=0,
        voice_aht_seconds=300, email_aht_seconds=600,
        chat_aht_seconds=480, voice_acw_seconds=60,
        fully_loaded_agent_cost_annual=65_000,
        fully_loaded_supervisor_cost_annual=95_000,
    )
    scope = FeatureScope("Predictive Routing", ["Tiny"], eligibility_pct=0.5)
    df = calculate_consumption_ai_cost(
        [site], scope, DEFAULT_METERS["Predictive Routing"], "realistic",
        DEFAULT_PRICING, year=2,
    )
    assert df.iloc[0]["tokens_monthly"] == 50
    total = calculate_total_cost(
        [site], [scope], DEFAULT_METERS, DEFAULT_PRICING, "realistic", 2,
        include_platform=False,
    )
    pr_row = total[total["cost_line"] == "Predictive Routing"].iloc[0]
    assert pr_row["annual_cost"] == pytest.approx(50 * 12 * 1.0)


def test_regional_pricing_not_hardcoded():
    pricing = dict(DEFAULT_PRICING)
    from tokencalc.meters import TokenPricing

    pricing["APAC"] = TokenPricing(region="APAC", list_rate_per_token=2.0)
    apac_site = next(s for s in CTM_DEFAULT_SITES if s.region_pricing == "APAC")
    df = calculate_per_user_ai_cost(
        [apac_site], _scope("Speech & Text Analytics [named]", [apac_site.site_name]),
        DEFAULT_METERS["Speech & Text Analytics [named]"], pricing,
    )
    expected = apac_site.named_users * 30 * 12 * 2.0
    assert df["annual_cost"].sum() == pytest.approx(expected)


def test_year1_consumption_ramp_default_70pct():
    sc = get_scenario("realistic")
    assert sc.cost_realization(1) == pytest.approx(0.70)
    assert sc.cost_realization(2) == 1.0


def test_platform_license_cost():
    df = calculate_platform_license_cost(CTM_DEFAULT_SITES)
    expected = CONTRACTED_NAMED_USERS * 111.28 * 12
    assert df["annual_cost"].sum() == pytest.approx(expected)


def test_total_cost_default_scopes_runs_all_years():
    for year in (1, 2, 3):
        df = calculate_total_cost(
            CTM_DEFAULT_SITES, CTM_DEFAULT_FEATURE_SCOPES,
            DEFAULT_METERS, DEFAULT_PRICING, "realistic", year,
        )
        assert (df["annual_cost"] >= 0).all()
        assert {"cost_line", "scope", "annual_cost", "confidence"} <= set(df.columns)
