import unittest
from datetime import datetime, timedelta

from lib.key_monitor.false_breakout_key_monitor_lib import (
    FALSE_BREAKOUT_MONITOR_TYPE,
    calc_false_breakout_plan,
    false_breakout_gate_preview,
    is_false_breakout_expired,
    key_price_from_row,
    normalize_false_breakout_symbol,
    storage_bounds_from_key_price,
)


class FalseBreakoutKeyMonitorLibTests(unittest.TestCase):
    def test_normalize_symbol(self):
        self.assertEqual(normalize_false_breakout_symbol("btc"), "BTC/USDT")
        self.assertEqual(normalize_false_breakout_symbol("ETH/USDT"), "ETH/USDT")
        self.assertIsNone(normalize_false_breakout_symbol("SOL"))

    def test_short_plan(self):
        plan = calc_false_breakout_plan("short", 100000)
        self.assertIsNotNone(plan)
        entry, sl, tp = plan
        self.assertAlmostEqual(entry, 100100.0)
        self.assertAlmostEqual(sl, 100600.5)
        self.assertAlmostEqual(tp, 99349.25)

    def test_long_plan(self):
        plan = calc_false_breakout_plan("long", 100000)
        self.assertIsNotNone(plan)
        entry, sl, tp = plan
        self.assertAlmostEqual(entry, 99900.0)
        self.assertAlmostEqual(sl, 99400.5)
        self.assertAlmostEqual(tp, 100649.25)

    def test_storage_bounds(self):
        up, low = storage_bounds_from_key_price("short", 100000)
        self.assertGreater(up, low)
        self.assertAlmostEqual(up, 100000.0)
        self.assertAlmostEqual(low, 99990.0)
        up, low = storage_bounds_from_key_price("long", 100000)
        self.assertGreater(up, low)
        self.assertAlmostEqual(low, 100000.0)
        self.assertAlmostEqual(up, 100010.0)

    def test_key_price_from_row(self):
        self.assertEqual(key_price_from_row("short", 100100, 100000), 100100)
        self.assertEqual(key_price_from_row("long", 100100, 100000), 100000)

    def test_expiry(self):
        now = datetime(2026, 6, 9, 12, 0, 0)
        created = "2026-06-08 12:00:00"
        self.assertTrue(is_false_breakout_expired(created, now))
        self.assertFalse(is_false_breakout_expired(created, now - timedelta(hours=1)))

    def test_monitor_type_constant(self):
        self.assertEqual(FALSE_BREAKOUT_MONITOR_TYPE, "假突破")

    def test_gate_preview_not_box_gate(self):
        now = datetime(2026, 6, 7, 12, 0, 0)
        prev = false_breakout_gate_preview(
            entry_display="1635.0",
            limit_order_id="oid-1",
            created_at="2026-06-07 10:00:00",
            now=now,
        )
        self.assertIn("假突破", prev["summary"])
        self.assertIn("等待成交", prev["summary"])
        self.assertNotIn("量:", prev["summary"])
        self.assertIn("限价单:oid-1", prev["metrics"])
        self.assertTrue(prev["gate_ok"])


if __name__ == "__main__":
    unittest.main()
