"""
Tests for dating compatibility algorithm.

Tests the calculate_compatibility function with various scenarios:
- Shared interests
- Age compatibility
- Education level matching
- Wealth/prestige compatibility
"""

import pytest
from dating.compatibility import calculate_compatibility


def test_shared_interests_boost():
    """Test that shared interests increase compatibility score"""
    player = {
        'likes': ['music', 'sports', 'reading'],
        'age_years': 25,
        'prestige': 50,
        'education_level': 3
    }
    match = {
        'likes': ['music', 'sports'],
        'age_years': 26,
        'prestige': 55,
        'education_level': 3
    }

    score = calculate_compatibility(player, match)
    # Base 50 + 2 shared interests (10) + age close (15) + same education (10) + similar prestige (10) = 95
    assert score >= 60  # At minimum, 2 shared interests should give +10


def test_age_compatibility():
    """Test that age difference affects compatibility"""
    player = {
        'likes': [],
        'age_years': 25,
        'prestige': 50,
        'education_level': 3
    }
    match_close = {
        'likes': [],
        'age_years': 27,
        'prestige': 50,
        'education_level': 3
    }  # 2 years diff
    match_far = {
        'likes': [],
        'age_years': 40,
        'prestige': 50,
        'education_level': 3
    }   # 15 years diff

    score_close = calculate_compatibility(player, match_close)
    score_far = calculate_compatibility(player, match_far)

    # Close age should score higher than far age
    assert score_close > score_far


def test_no_shared_interests():
    """Test compatibility with no shared interests"""
    player = {
        'likes': ['music', 'sports'],
        'age_years': 25,
        'prestige': 50,
        'education_level': 3
    }
    match = {
        'likes': ['cooking', 'travel'],
        'age_years': 25,
        'prestige': 50,
        'education_level': 3
    }

    score = calculate_compatibility(player, match)
    # Should still have base score + age + education + prestige bonuses
    assert score >= 50  # Base score minimum


def test_perfect_match():
    """Test a perfect match scenario"""
    player = {
        'likes': ['music', 'sports', 'reading'],
        'age_years': 25,
        'prestige': 50,
        'education_level': 3
    }
    match = {
        'likes': ['music', 'sports', 'reading'],
        'age_years': 25,
        'prestige': 50,
        'education_level': 3
    }

    score = calculate_compatibility(player, match)
    # Base 50 + 3 interests (15) + same age (15) + same education (10) + same prestige (10) = 100
    assert score == 100


def test_poor_match():
    """Test a poor match scenario"""
    player = {
        'likes': ['music'],
        'age_years': 20,
        'prestige': 10,
        'education_level': 1
    }
    match = {
        'likes': ['cooking'],
        'age_years': 45,  # 25 years difference
        'prestige': 100,  # 90 prestige difference
        'education_level': 5  # 4 education levels different
    }

    score = calculate_compatibility(player, match)
    # Base 50 - 15 (age) - 5 (prestige) = 30
    assert score < 50


def test_education_level_compatibility():
    """Test education level matching"""
    player = {
        'likes': [],
        'age_years': 25,
        'prestige': 50,
        'education_level': 3
    }
    match_same = {
        'likes': [],
        'age_years': 25,
        'prestige': 50,
        'education_level': 3
    }
    match_close = {
        'likes': [],
        'age_years': 25,
        'prestige': 50,
        'education_level': 4
    }
    match_far = {
        'likes': [],
        'age_years': 25,
        'prestige': 50,
        'education_level': 1
    }

    score_same = calculate_compatibility(player, match_same)
    score_close = calculate_compatibility(player, match_close)
    score_far = calculate_compatibility(player, match_far)

    # Same education should score highest
    assert score_same > score_close > score_far


def test_score_bounds():
    """Test that scores are always between 0 and 100"""
    # Extreme positive case
    player = {
        'likes': ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'],
        'age_years': 25,
        'prestige': 50,
        'education_level': 3
    }
    match = {
        'likes': ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'],
        'age_years': 25,
        'prestige': 50,
        'education_level': 3
    }

    score = calculate_compatibility(player, match)
    assert 0 <= score <= 100

    # Extreme negative case
    player_neg = {
        'likes': [],
        'age_years': 18,
        'prestige': 0,
        'education_level': 0
    }
    match_neg = {
        'likes': [],
        'age_years': 80,  # 62 years difference
        'prestige': 100,
        'education_level': 5
    }

    score_neg = calculate_compatibility(player_neg, match_neg)
    assert 0 <= score_neg <= 100


def test_missing_keys():
    """Test handling of missing optional keys"""
    player = {
        'age_years': 25
    }
    match = {
        'age_years': 26
    }

    score = calculate_compatibility(player, match)
    # Should not crash, should use defaults
    assert isinstance(score, int)
    assert 0 <= score <= 100
