"""趋势回调运行中计划:实际成交价重算补仓表与金额盈亏比."""
from __future__ import annotations

import json
import sys
import unittest
from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]
sys.path.insert(0, str(ROOT))

from lib.strategy.strategy_snapshot_lib import attach_trend_dca_levels  # noqa: E402
from lib.strategy.strategy_trend_lib import (  # noqa: E402
    calc_trend_plan_money_metrics,
    trend_leg_display_price,
)


class TestTrendDcaEnrichFills(unittest.TestCase):
    def _base_plan(self, **overrides):
        plan = {
            "direction": "long",
            "stop_loss": 0.329,
            "take_profit": 0.476,
            "first_order_amount": 115,
            "snapshot_available_usdt": 97.98,
            "risk_percent": 5,
            "contract_size": 1.0,
            "grid_prices_json": json.dumps([0.3465, 0.343, 0.3395, 0.336, 0.3325]),
            "leg_amounts_json": json.dumps([23, 23, 23, 23, 23]),
            "dca_legs": 5,
            "first_order_done": 1,
            "legs_done": 0,
            "avg_entry_price": 0.3537,
            "order_amount_open": 115,
            "target_order_amount": 230,
            "leg_fill_prices_json": json.dumps([0.3537]),
        }
        plan.update(overrides)
        return plan

    def test_header_money_rr_not_price_rr(self):
        plan = self._base_plan()
        metrics = calc_trend_plan_money_metrics(plan)
        self.assertAlmostEqual(metrics["risk_amount_u"], 4.899, places=2)
        self.assertIsNotNone(metrics["money_rr"])
        self.assertLess(metrics["money_rr"], 4.0)

    def test_done_dca_uses_actual_fill_price(self):
        plan = self._base_plan(
            legs_done=1,
            avg_entry_price=0.3512,
            order_amount_open=138,
            leg_fill_prices_json=json.dumps([0.3537, 0.3458]),
        )
        enriched = attach_trend_dca_levels(plan)
        levels = enriched["dca_levels"]
        self.assertEqual(len(levels), 6)
        dca1 = levels[1]
        self.assertEqual(dca1["status"], "done")
        self.assertAlmostEqual(dca1["price"], 0.3458, places=4)
        self.assertIsNotNone(dca1["avg_entry"])
        self.assertIsNotNone(dca1["rr"])
        dca2 = levels[2]
        self.assertEqual(dca2["status"], "pending")
        self.assertAlmostEqual(dca2["price"], 0.343, places=4)

    def test_missing_dca_fills_use_grid_trigger_not_inferred_price(self):
        """缺补仓成交价时:触发价用计划网格,末档均价对齐头部,禁止反推离谱成交价."""
        plan = self._base_plan(
            legs_done=2,
            avg_entry_price=0.3507,
            order_amount_open=161,
            leg_fill_prices_json=json.dumps([0.3436]),
            grid_prices_json=json.dumps([0.343, 0.343, 0.3395, 0.336, 0.3325]),
        )
        enriched = attach_trend_dca_levels(plan)
        levels = enriched["dca_levels"]
        dca1 = levels[1]
        dca2 = levels[2]
        self.assertEqual(dca1["status"], "done")
        self.assertAlmostEqual(dca1["price"], 0.343, places=4)
        self.assertEqual(dca2["status"], "done")
        self.assertAlmostEqual(dca2["price"], 0.343, places=4)
        self.assertAlmostEqual(dca2["avg_entry"], 0.3507, places=4)
        self.assertLess(dca2["price"], 0.36)

    def test_display_price_never_infers_from_target_avg(self):
        """三所共用:缺记录时只用网格,不因均价反推离谱触发价."""
        plan = self._base_plan(
            legs_done=2,
            avg_entry_price=0.3507,
            leg_fill_prices_json=json.dumps([0.3436]),
            grid_prices_json=json.dumps([0.343, 0.343, 0.3395, 0.336, 0.3325]),
        )
        self.assertAlmostEqual(trend_leg_display_price(plan, 2), 0.343, places=4)
        self.assertLess(trend_leg_display_price(plan, 2), 0.36)


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