from __future__ import annotations

from hypothesis import given, settings, strategies as st

from app.services.recommendation_service import direction_analyzer, probability_estimator


@settings(max_examples=100, deadline=None)
@given(
    technical=st.floats(min_value=0, max_value=100),
    momentum=st.floats(min_value=0, max_value=100),
    fundamental=st.floats(min_value=0, max_value=100),
    sentiment=st.sampled_from(["bearish", "neutral", "bullish", None]),
)
def test_property_confidence_bounds(technical, momentum, fundamental, sentiment):
    """Feature: intelligent-trade-recommendations, Property 3: Confidence Score Bounds."""
    scores = {
        "technical": technical,
        "momentum": momentum,
        "fundamental": fundamental,
    }

    long_conf = direction_analyzer.calculate_confidence("long", scores, sentiment, conflicts=[])
    short_conf = direction_analyzer.calculate_confidence("short", scores, sentiment, conflicts=[])

    assert 0 <= long_conf <= 100
    assert 0 <= short_conf <= 100


@settings(max_examples=100, deadline=None)
@given(
    strength_low=st.floats(min_value=0, max_value=50),
    strength_high=st.floats(min_value=50, max_value=100),
)
def test_property_strength_monotonic_probability(strength_low, strength_high):
    """Feature: intelligent-trade-recommendations, Property 11: S/R Strength Monotonicity."""
    config = {
        "recommendation_signal_alignment_weight": 0.15,
        "recommendation_sr_strength_weight": 0.20,
    }
    scores = {"technical": 65.0, "momentum": 65.0}

    base_target = {
        "classification": "Moderate",
        "distance_atr_multiple": 3.0,
    }

    low = probability_estimator.estimate_probability(
        {**base_target, "sr_strength": strength_low},
        scores,
        "bullish",
        "long",
        config,
    )
    high = probability_estimator.estimate_probability(
        {**base_target, "sr_strength": strength_high},
        scores,
        "bullish",
        "long",
        config,
    )

    assert high >= low


@settings(max_examples=100, deadline=None)
@given(
    near_distance=st.floats(min_value=1.0, max_value=3.0),
    far_distance=st.floats(min_value=3.1, max_value=8.0),
)
def test_property_distance_probability_relationship(near_distance, far_distance):
    """Feature: intelligent-trade-recommendations, Property 12: Distance Probability Relationship."""
    config = {
        "recommendation_signal_alignment_weight": 0.15,
        "recommendation_sr_strength_weight": 0.20,
    }
    scores = {"technical": 65.0, "momentum": 65.0}

    near_prob = probability_estimator.estimate_probability(
        {
            "classification": "Conservative",
            "sr_strength": 60,
            "distance_atr_multiple": near_distance,
        },
        scores,
        "bullish",
        "long",
        config,
    )
    far_prob = probability_estimator.estimate_probability(
        {
            "classification": "Aggressive",
            "sr_strength": 60,
            "distance_atr_multiple": far_distance,
        },
        scores,
        "bullish",
        "long",
        config,
    )

    assert near_prob >= far_prob
