"""Tests for KPI calculator."""

from src.analysis.kpi_calculator import (
    calculate_index_rate,
    check_index_rate,
    check_kpi_thresholds,
)
from src.models.data_models import SearchMetrics


class TestCheckKPIThresholds:
    def test_all_pass(self, sample_metrics, thresholds):
        alerts = check_kpi_thresholds(sample_metrics, thresholds, "test")
        assert len(alerts) == 0

    def test_all_fail(self, low_metrics, thresholds):
        alerts = check_kpi_thresholds(low_metrics, thresholds, "test")
        assert len(alerts) == 4

        metric_names = {a.metric_name for a in alerts}
        assert metric_names == {"clicks", "impressions", "ctr", "position"}

    def test_clicks_below_threshold(self, thresholds):
        metrics = SearchMetrics(clicks=100, impressions=3000, ctr=0.20, position=2.0)
        alerts = check_kpi_thresholds(metrics, thresholds, "test")
        assert len(alerts) == 1
        assert alerts[0].metric_name == "clicks"
        assert alerts[0].current_value == 100

    def test_position_above_threshold(self, thresholds):
        metrics = SearchMetrics(clicks=600, impressions=3000, ctr=0.20, position=5.0)
        alerts = check_kpi_thresholds(metrics, thresholds, "test")
        assert len(alerts) == 1
        assert alerts[0].metric_name == "position"

    def test_ctr_below_threshold(self, thresholds):
        metrics = SearchMetrics(clicks=600, impressions=3000, ctr=0.10, position=2.0)
        alerts = check_kpi_thresholds(metrics, thresholds, "test")
        assert len(alerts) == 1
        assert alerts[0].metric_name == "ctr"

    def test_boundary_values(self, thresholds):
        # Exactly at thresholds — should pass
        metrics = SearchMetrics(clicks=500, impressions=2000, ctr=0.15, position=3.0)
        alerts = check_kpi_thresholds(metrics, thresholds, "test")
        assert len(alerts) == 0


class TestCalculateIndexRate:
    def test_normal(self):
        assert calculate_index_rate(100, 95) == 0.95

    def test_zero_checked(self):
        assert calculate_index_rate(0, 0) == 0.0

    def test_all_indexed(self):
        assert calculate_index_rate(50, 50) == 1.0


class TestCheckIndexRate:
    def test_below_threshold(self, thresholds):
        alert = check_index_rate(100, 80, thresholds, "test")
        assert alert is not None
        assert alert.metric_name == "index_rate"
        assert alert.current_value == 0.8

    def test_above_threshold(self, thresholds):
        alert = check_index_rate(100, 96, thresholds, "test")
        assert alert is None

    def test_exactly_at_threshold(self, thresholds):
        alert = check_index_rate(100, 95, thresholds, "test")
        assert alert is None
