from decimal import Decimal
from datetime import datetime, timezone, timedelta

from src.tools.analyze_trade_timing import Candle, assess_entry, assess_exit, rsi


def c(i, o, h, l, close):
    return Candle(datetime(2026, 1, 1, tzinfo=timezone.utc) + timedelta(minutes=15*i), Decimal(str(o)), Decimal(str(h)), Decimal(str(l)), Decimal(str(close)), Decimal("1000"))


def test_entry_flags_chased_pre_move_and_adverse_excursion():
    pre = [c(0, 100, 101, 99, 100), c(1, 101, 103, 100, 102), c(2, 102, 104, 101, 103.5), c(3, 103.5, 105, 103, 104.5)]
    post = [c(4, 104.5, 104.7, 103.6, 103.8), c(5, 103.8, 104.0, 102.9, 103.0)]
    result = assess_entry(Decimal("104.5"), pre, post)
    assert "entry_likely_chased_after_pre_move" in result["flags"]
    assert "entry_poor_immediate_adverse_excursion" in result["flags"]
    assert result["quality"] == "bad"


def test_entry_good_follow_through():
    pre = [c(i, 100, 100.3, 99.8, 100 + (0.02 if i % 2 == 0 else -0.01)) for i in range(20)]
    post = [c(20, 102, 103.5, 101.9, 103), c(21, 103, 104, 102.8, 103.7)]
    result = assess_entry(Decimal("102"), pre, post)
    assert "entry_good_follow_through" in result["flags"]
    assert result["quality"] == "good"


def test_exit_flags_too_early_when_followthrough_after_profit_target():
    pre = [c(i, 100+i*0.1, 100+i*0.1+0.2, 99+i*0.1, 100+i*0.1+0.1) for i in range(20)]
    post = [c(20, 102, 103.5, 101.8, 103.2), c(21, 103.2, 104.0, 103, 103.8)]
    result = assess_exit(Decimal("102"), pre, post, "profit_target")
    assert "exit_too_early_missed_followthrough" in result["flags"]
    assert result["quality"] == "bad"


def test_rsi_returns_high_value_on_consistent_gains():
    values = [Decimal(i) for i in range(1, 20)]
    assert rsi(values) == Decimal("100")
