"""按可用余额打满 / 全仓复利定仓."""
from __future__ import annotations

import unittest

from lib.options.options_pricing_lib import (
    resolve_budget_full_usdc,
    resolve_compound_full_usdc,
)
from lib.options.options_position_limit_lib import (
    compound_full_single_position_block_msg,
    count_live_option_positions,
)


class TestOptionsBudgetModes(unittest.TestCase):
    def test_balance_above_budget_uses_budget(self):
        self.assertEqual(resolve_budget_full_usdc(100.0, 10.0), 10.0)

    def test_balance_below_budget_uses_balance(self):
        self.assertEqual(resolve_budget_full_usdc(5.0, 10.0), 5.0)

    def test_balance_equals_budget(self):
        self.assertEqual(resolve_budget_full_usdc(10.0, 10.0), 10.0)

    def test_compound_full_no_cap_uses_all(self):
        self.assertEqual(
            resolve_compound_full_usdc(200.0, cap_enabled=False, cap_usdc=50.0),
            200.0,
        )

    def test_compound_full_cap_on(self):
        self.assertEqual(
            resolve_compound_full_usdc(200.0, cap_enabled=True, cap_usdc=50.0),
            50.0,
        )
        self.assertEqual(
            resolve_compound_full_usdc(30.0, cap_enabled=True, cap_usdc=50.0),
            30.0,
        )

    def test_compound_full_cap_invalid_falls_back_to_balance(self):
        self.assertEqual(
            resolve_compound_full_usdc(80.0, cap_enabled=True, cap_usdc=0),
            80.0,
        )
        self.assertEqual(
            resolve_compound_full_usdc(80.0, cap_enabled=True, cap_usdc=None),
            80.0,
        )

    def test_compound_full_blocks_when_position_open(self):
        rows = [{"instId": "ETH-USD_UM-260812-1870-P", "pos": "1"}]
        msg = compound_full_single_position_block_msg(
            object(), fetch_positions=lambda _ex: rows
        )
        self.assertIsNotNone(msg)
        self.assertIn("1 笔", msg or "")

    def test_compound_full_allows_when_flat(self):
        msg = compound_full_single_position_block_msg(
            object(), fetch_positions=lambda _ex: []
        )
        self.assertIsNone(msg)
        self.assertEqual(count_live_option_positions([]), 0)

    def test_normalize_size_mode_when_compound_off(self):
        import os
        from unittest.mock import patch

        from lib.options import options_register as reg

        with patch.dict(os.environ, {"OKX_OPTIONS_COMPOUND_FULL_ENABLED": "false"}):
            mode, note = reg._normalize_size_mode("compound_full")
            self.assertEqual(mode, "sheets")
            self.assertIsNotNone(note)
            mode2, note2 = reg._normalize_size_mode("budget_full")
            self.assertEqual(mode2, "budget_full")
            self.assertIsNone(note2)
            mode3, _ = reg._normalize_size_mode("sheets")
            self.assertEqual(mode3, "sheets")

    def test_normalize_size_mode_when_compound_on(self):
        import os
        from unittest.mock import patch

        from lib.options import options_register as reg

        with patch.dict(os.environ, {"OKX_OPTIONS_COMPOUND_FULL_ENABLED": "true"}):
            mode, note = reg._normalize_size_mode("budget_full")
            self.assertEqual(mode, "compound_full")
            self.assertIsNone(note)
            mode2, _ = reg._normalize_size_mode("compound_full")
            self.assertEqual(mode2, "compound_full")


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