"""Tests for trend analyzer."""

from src.analysis.trend_analyzer import calculate_change_pct, compare_periods, detect_drops
from src.models.data_models import SearchMetrics


class TestCalculateChangePct:
    def test_increase(self):
        assert calculate_change_pct(120, 100) == 20.0

    def test_decrease(self):
        assert calculate_change_pct(80, 100) == -20.0

    def test_no_change(self):
        assert calculate_change_pct(100, 100) == 0.0

    def test_zero_previous(self):
        assert calculate_change_pct(100, 0) == 0.0

    def test_both_zero(self):
        assert calculate_change_pct(0, 0) == 0.0

    def test_large_drop(self):
        assert calculate_change_pct(10, 100) == -90.0


class TestComparePeriods:
    def test_basic_comparison(self):
        current = SearchMetrics(clicks=120, impressions=1200, ctr=0.10, position=3.0)
        previous = SearchMetrics(clicks=100, impressions=1000, ctr=0.10, position=2.0)

        trend = compare_periods(current, previous, "前日比")

        assert trend.period_label == "前日比"
        assert trend.clicks_change_pct == 20.0
        assert trend.impressions_change_pct == 20.0
        assert trend.ctr_change_pct == 0.0
        assert trend.position_change == 1.0

    def test_declining_metrics(self):
        current = SearchMetrics(clicks=50, impressions=500, ctr=0.10, position=5.0)
        previous = SearchMetrics(clicks=100, impressions=1000, ctr=0.10, position=2.0)

        trend = compare_periods(current, previous, "7日比")

        assert trend.clicks_change_pct == -50.0
        assert trend.impressions_change_pct == -50.0
        assert trend.position_change == 3.0


class TestDetectDrops:
    def test_significant_drop(self):
        current = SearchMetrics(clicks=50, impressions=500, ctr=0.10, position=5.0)
        previous = SearchMetrics(clicks=100, impressions=1000, ctr=0.10, position=2.0)
        trend = compare_periods(current, previous, "前日比")

        alerts = detect_drops([trend], "test")
        assert len(alerts) == 3  # clicks, impressions, position

    def test_no_drop(self):
        current = SearchMetrics(clicks=110, impressions=1100, ctr=0.10, position=2.0)
        previous = SearchMetrics(clicks=100, impressions=1000, ctr=0.10, position=2.0)
        trend = compare_periods(current, previous, "前日比")

        alerts = detect_drops([trend], "test")
        assert len(alerts) == 0

    def test_position_worsening(self):
        current = SearchMetrics(clicks=100, impressions=1000, ctr=0.10, position=5.0)
        previous = SearchMetrics(clicks=100, impressions=1000, ctr=0.10, position=2.0)
        trend = compare_periods(current, previous, "前日比")

        alerts = detect_drops([trend], "test")
        assert len(alerts) == 1
        assert "平均順位" in alerts[0]

    def test_custom_threshold(self):
        current = SearchMetrics(clicks=85, impressions=1000, ctr=0.085, position=2.0)
        previous = SearchMetrics(clicks=100, impressions=1000, ctr=0.10, position=2.0)
        trend = compare_periods(current, previous, "前日比")

        # Default -20% threshold: -15% should not trigger
        alerts = detect_drops([trend], "test")
        assert len(alerts) == 0

        # Lower threshold: -10% should trigger
        alerts = detect_drops([trend], "test", threshold_pct=-10.0)
        assert len(alerts) >= 1
