"""触价开仓(回调/突破)关键位监控单元测试."""
from lib.key_monitor.trigger_entry_key_monitor_lib import (
    BREAKOUT_TRIGGER_ENTRY_MONITOR_TYPE,
    CALLBACK_TRIGGER_ENTRY_MONITOR_TYPE,
    LEGACY_TRIGGER_ENTRY_MONITOR_TYPE,
    TRIGGER_ENTRY_MONITOR_TYPES,
    TRIGGER_ENTRY_VALIDITY_HOURS,
    breakout_trigger_entry_crossed,
    check_trigger_entry_intent_limit,
    is_breakout_trigger_entry_key_monitor_type,
    is_trigger_entry_key_monitor_type,
    trigger_entry_invalidate,
    trigger_entry_reached,
    trigger_should_fire,
    validate_trigger_entry_geometry,
)


class _FakeConn:
    def execute(self, sql, params=()):
        class R:
            def fetchone(self_inner):
                return (2,)

        return R()


def test_trigger_entry_reached_long():
    assert trigger_entry_reached("long", 2049.0, 2050.0) is True
    assert trigger_entry_reached("long", 2051.0, 2050.0) is False


def test_breakout_cross_long_up():
    assert breakout_trigger_entry_crossed("long", 99.0, 100.5, 100.0) is True
    assert breakout_trigger_entry_crossed("long", None, 101.0, 100.0) is True
    assert breakout_trigger_entry_crossed("long", 100.0, 100.0, 100.0) is False


def test_breakout_cross_short_down():
    assert breakout_trigger_entry_crossed("short", 101.0, 99.5, 100.0) is True
    assert breakout_trigger_entry_crossed("short", None, 99.0, 100.0) is True


def test_trigger_should_fire_modes():
    assert trigger_should_fire(CALLBACK_TRIGGER_ENTRY_MONITOR_TYPE, "long", 2049.0, 2050.0) is True
    assert trigger_should_fire(BREAKOUT_TRIGGER_ENTRY_MONITOR_TYPE, "long", 100.5, 100.0, 99.0) is True


def test_validate_geometry_callback_long():
    assert validate_trigger_entry_geometry("long", 2050, 2000, 2100, 2090) is None


def test_validate_geometry_breakout_short_requires_mark_above_entry():
    assert (
        validate_trigger_entry_geometry(
            "short", 551, 568, 540, 560, monitor_type=BREAKOUT_TRIGGER_ENTRY_MONITOR_TYPE
        )
        is None
    )
    err = validate_trigger_entry_geometry(
        "short", 551, 568, 540, 550, monitor_type=BREAKOUT_TRIGGER_ENTRY_MONITOR_TYPE
    )
    assert err is not None
    assert "高于入场价" in err


def test_invalidate_breakout_sl_side():
    assert trigger_entry_invalidate(BREAKOUT_TRIGGER_ENTRY_MONITOR_TYPE, "long", 96, 97, 110) == "sl"
    assert trigger_entry_invalidate(CALLBACK_TRIGGER_ENTRY_MONITOR_TYPE, "long", 96, 97, 110) is None


def test_intent_limit():
    ok, msg = check_trigger_entry_intent_limit(_FakeConn(), "2026-06-07", 2, 3)
    assert ok is False
    assert "意图" in msg


def test_type_names():
    assert is_trigger_entry_key_monitor_type(CALLBACK_TRIGGER_ENTRY_MONITOR_TYPE)
    assert is_trigger_entry_key_monitor_type(BREAKOUT_TRIGGER_ENTRY_MONITOR_TYPE)
    assert is_trigger_entry_key_monitor_type(LEGACY_TRIGGER_ENTRY_MONITOR_TYPE)
    assert is_breakout_trigger_entry_key_monitor_type(BREAKOUT_TRIGGER_ENTRY_MONITOR_TYPE)
    assert CALLBACK_TRIGGER_ENTRY_MONITOR_TYPE in TRIGGER_ENTRY_MONITOR_TYPES
    assert BREAKOUT_TRIGGER_ENTRY_MONITOR_TYPE in TRIGGER_ENTRY_MONITOR_TYPES
    assert TRIGGER_ENTRY_VALIDITY_HOURS == 24
