"""Tests for recommendation generation."""

import pytest

from mixlift.modeling.recommendations import (
    format_all_recommendations,
    format_recommendation,
    generate_recommendations,
)


class TestGenerateRecommendations:
    def test_basic_recommendations(self):
        current = {"Google Search": 5000, "Meta": 8000, "TikTok": 2000}
        optimal = {"Google Search": 7200, "Meta": 6200, "TikTok": 3600}
        roas = {"Google Search": 3.2, "Meta": 1.8, "TikTok": 2.1}

        recs, summary = generate_recommendations(current, optimal, roas, 12.5)

        assert len(recs) > 0
        assert any(r.action == "INCREASE" for r in recs)
        assert any(r.action == "DECREASE" for r in recs)
        assert all(r.rank > 0 for r in recs)
        assert "12.5%" in summary

    def test_no_recommendations_when_optimal(self):
        current = {"A": 1000, "B": 1000}
        optimal = {"A": 1020, "B": 980}  # Less than 5% change
        roas = {"A": 2.0, "B": 2.0}

        recs, summary = generate_recommendations(current, optimal, roas, 0.5)
        assert len(recs) == 0
        assert "close to optimal" in summary.lower()

    def test_recommendations_ranked_by_change_amount(self):
        current = {"A": 5000, "B": 3000, "C": 2000}
        optimal = {"A": 8000, "B": 1000, "C": 1000}
        roas = {"A": 3.0, "B": 1.2, "C": 1.1}

        recs, _ = generate_recommendations(current, optimal, roas, 15.0)

        # Should be ranked by absolute change amount
        for i in range(len(recs) - 1):
            assert recs[i].change_amount >= recs[i + 1].change_amount

    def test_increase_has_positive_reason(self):
        current = {"A": 2000}
        optimal = {"A": 5000}
        roas = {"A": 3.5}

        recs, _ = generate_recommendations(current, optimal, roas, 10.0)
        increase = [r for r in recs if r.action == "INCREASE"]
        assert len(increase) == 1
        assert "roas" in increase[0].reason.lower()

    def test_decrease_mentions_saturation(self):
        current = {"A": 10000}
        optimal = {"A": 5000}
        roas = {"A": 0.8}

        recs, _ = generate_recommendations(current, optimal, roas, 8.0)
        decrease = [r for r in recs if r.action == "DECREASE"]
        assert len(decrease) == 1
        assert "saturat" in decrease[0].reason.lower()


class TestFormatting:
    def test_format_recommendation(self):
        current = {"Google": 5000}
        optimal = {"Google": 7200}
        roas = {"Google": 3.2}

        recs, _ = generate_recommendations(current, optimal, roas, 10.0)
        formatted = format_recommendation(recs[0])
        assert "Google" in formatted
        assert "$" in formatted

    def test_format_all(self):
        current = {"A": 5000, "B": 3000}
        optimal = {"A": 7000, "B": 1000}
        roas = {"A": 3.0, "B": 1.0}

        recs, summary = generate_recommendations(current, optimal, roas, 12.0)
        report = format_all_recommendations(recs, summary)
        assert "BUDGET OPTIMIZATION" in report
        assert "#1" in report
