import unittest
from types import SimpleNamespace

from datetime import datetime

from lib.trade.trade_stats_calendar_lib import (
    build_initial_stats_calendar,
    build_stats_calendar_bootstrap,
    build_trade_stats_calendar,
)


def _row(**kwargs):
    base = {
        "monitor_type": "",
        "key_signal_type": "",
        "exchange_turnover_usdt": None,
        "exchange_commission_usdt": None,
    }
    base.update(kwargs)
    return SimpleNamespace(**base)


def _matches_all(row, segment_key):
    return segment_key == "all"


def _matches_manual(row, segment_key):
    if segment_key == "all":
        return True
    if segment_key == "manual":
        return (row.monitor_type or "").strip() == "手动" and not (row.key_signal_type or "").strip()
    return False


class TradeStatsCalendarLibTests(unittest.TestCase):
    def test_groups_by_trading_day_and_segment(self):
        pnls = [
            (10.0, None, "2026-06-18", _row(monitor_type="手动")),
            (-3.0, None, "2026-06-18", _row(monitor_type="手动")),
            (5.0, None, "2026-06-19", _row(monitor_type="自动", key_signal_type="箱体突破")),
        ]
        payload = build_trade_stats_calendar(
            pnls,
            2026,
            6,
            "manual",
            _matches_manual,
            reset_hour=8,
        )
        self.assertEqual(payload["month"], 6)
        self.assertEqual(payload["month_open_count"], 2)
        days = payload["days"]
        self.assertIn("2026-06-18", days)
        self.assertNotIn("2026-06-19", days)
        self.assertEqual(days["2026-06-18"]["open_count"], 2)
        self.assertAlmostEqual(days["2026-06-18"]["pnl_total"], 7.0)

    def test_invalid_month_raises(self):
        with self.assertRaises(ValueError):
            build_trade_stats_calendar([], 2026, 13, "all", _matches_all)

    def test_initial_calendar_uses_current_month(self):
        pnls = [(2.5, None, "2026-06-20", _row())]
        payload = build_initial_stats_calendar(
            pnls,
            datetime(2026, 6, 26, 12, 0),
            _matches_all,
            reset_hour=8,
        )
        self.assertEqual(payload["year"], 2026)
        self.assertEqual(payload["month"], 6)
        self.assertEqual(payload["month_open_count"], 1)
        self.assertIn("2026-06-20", payload["days"])

    def test_bootstrap_json_roundtrip(self):
        pnls = [(2.5, None, "2026-06-20", _row())]
        payload, raw = build_stats_calendar_bootstrap(
            pnls,
            datetime(2026, 6, 26, 12, 0),
            _matches_all,
            reset_hour=8,
        )
        self.assertIsNotNone(payload)
        self.assertIsNotNone(raw)
        self.assertIn('"month_open_count":1', raw.replace(" ", ""))


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