"""Tests for Auto-Arbitrage & Profit-Taking Orchestrator (Chu Kỳ 7).
================================================================
Kiem thu toan dien:
- Hop nhat so du kho tien te (Wallet + Stash Currency Tab).
- Kiem chung nguong thanh ly an toan (Liquidation & Reserve Thresholds).
- Tinh toan ty gia doi ngoai te va thu tu uu tien lenh (Priority Ranking).
- Kiem soat khoa an toan Vang (INV-EXCHANGE-GOLD-TAX) va cat tia lenh.
- Ma tran phan tich rui ro kinh te (Economic Risk Matrix).
- In bao cao dinh luong tuan thu Rule 5: [MO PHONG THUAT TOAN HEADLESS - KHONG PHAI LIVE GAME].
"""

import pytest
from typing import Dict

from src.assistant_tool.currency_exchange.models import (
    ExchangeActionType,
    ExchangeOrderStatus,
    ExchangePortfolioConfig,
)
from src.assistant_tool.currency_exchange.auto_profit_taker import (
    AutoProfitTaker,
    EconomicRisk,
    ProfitTakingPlan,
    ProfitTakingThresholds,
)


class TestAutoProfitTaker:
    def test_scan_holdings_merges_wallet_and_stash(self):
        """Kiem tra ham scan_holdings hop nhat chinh xac so du tu vi va Stash."""
        profit_taker = AutoProfitTaker()
        wallet = {"Chaos Orb": 20, "Orb of Alchemy": 15, "Exalted Orb": 2}
        stash = {"Chaos Orb": 100, "Orb of Alchemy": 45, "Divine Orb": 1}

        combined = profit_taker.scan_holdings(wallet=wallet, stash_currency=stash)
        assert combined["Chaos Orb"] == 120
        assert combined["Orb of Alchemy"] == 60
        assert combined["Exalted Orb"] == 2
        assert combined["Divine Orb"] == 1

    def test_liquidation_thresholds_preserves_safety_reserve(self):
        """Kiem tra chi thanh ly phan thang du vuot nguong, bao toan 100% dinh muc du tru."""
        profit_taker = AutoProfitTaker()

        # Alchemy: Reserve = 20, Min liquidation = 10.
        # So du = 25 -> Thang du = 5 < 10 -> KHONG ban.
        holdings_below = {"Orb of Alchemy": 25}
        plan_below = profit_taker.evaluate_profit_taking(holdings_below, current_gold=10000)
        assert len(plan_below.orders) == 0

        # Alchemy: So du = 50 -> Thang du = 30 >= 10 -> Ban 30 Alchemy
        holdings_above = {"Orb of Alchemy": 50}
        plan_above = profit_taker.evaluate_profit_taking(holdings_above, current_gold=10000)
        assert len(plan_above.orders) == 1
        ord_alch = plan_above.orders[0]
        assert ord_alch.sell_currency == "Orb of Alchemy"
        assert ord_alch.sell_amount == 30  # 50 - 20 = 30
        assert ord_alch.buy_currency == "Chaos Orb"
        assert ord_alch.expected_buy_amount == 15  # 30 * 0.5 = 15 Chaos

    def test_order_priority_ranking_and_waterfall(self):
        """Kiem tra thu tu uu tien lenh: Ban thang du -> Mua Divine -> Mua Mirror."""
        profit_taker = AutoProfitTaker()

        # Co 300 Chaos (Reserve 50 -> Thang du 250), 100 Alchemy (Ban 80 -> +40 Chaos).
        # Tong Chaos = 250 + 40 = 290 Chaos.
        # Gia Divine = 145 Chaos -> Mua duoc 290 // 145 = 2 Divine!
        holdings = {
            "Chaos Orb": 300,
            "Orb of Alchemy": 100,
            "Regal Orb": 50,  # Reserve 10 -> Ban 40 Regal -> +48 Chaos
        }

        plan = profit_taker.evaluate_profit_taking(holdings, current_gold=20000)
        assert plan.total_orders >= 3

        # Lenh 1 & 2 phai la SELL_TO_CHAOS
        assert plan.orders[0].action_type == ExchangeActionType.SELL_TO_CHAOS
        assert plan.orders[1].action_type == ExchangeActionType.SELL_TO_CHAOS

        # Lenh 3 phai la CONVERT_CHAOS_TO_DIVINE
        divine_orders = [o for o in plan.orders if o.action_type == ExchangeActionType.CONVERT_CHAOS_TO_DIVINE]
        assert len(divine_orders) == 1
        assert divine_orders[0].expected_buy_amount >= 2

    def test_gold_safety_interlock_and_order_pruning(self):
        """Kiem tra khoa an toan Vang INV-EXCHANGE-GOLD-TAX va co che cat tia lenh."""
        profit_taker = AutoProfitTaker()

        holdings = {
            "Orb of Alchemy": 200,
            "Orb of Transmutation": 500,
            "Chaos Orb": 300,
        }

        # Case 1: Vang <= 5,000 (Ngương bảo vệ) -> Tu choi 100%
        plan_blocked = profit_taker.evaluate_profit_taking(holdings, current_gold=4500)
        assert plan_blocked.total_orders == 0
        assert any(r.risk_type == "GOLD_DEPLETION_RISK" for r in plan_blocked.risks)

        # Case 2: Vang du 6,000 (Kha dung = 1,000 Gold) -> Chap thuan 1 phan, cat tia lenh vuot ngan sach
        plan_partial = profit_taker.evaluate_profit_taking(holdings, current_gold=6000)
        assert plan_partial.total_estimated_gold_tax <= 1000
        assert plan_partial.remaining_gold_balance >= 5000

    def test_economic_risk_matrix_detection(self):
        """Kiem tra phat hien cac rui ro kinh te (Crafting starvation, Gold depletion)."""
        profit_taker = AutoProfitTaker()

        # Alchemy sat nguong reserve (20)
        holdings = {
            "Orb of Alchemy": 20,
            "Chaos Orb": 50,
        }
        plan = profit_taker.evaluate_profit_taking(holdings, current_gold=10000)
        risk_types = [r.risk_type for r in plan.risks]
        assert "CRAFTING_STARVATION_RISK" in risk_types

    def test_print_profit_taking_plan_rule5_compliant(self, capsys):
        """
        Mo phong lap ke hoach chot loi toan dien va in bao cao dinh luong.
        Ghi chu bat buoc: [MO PHONG THUAT TOAN HEADLESS - KHONG PHAI LIVE GAME]
        """
        profit_taker = AutoProfitTaker()

        holdings = {
            "Orb of Transmutation": 300,
            "Orb of Alteration": 150,
            "Orb of Alchemy": 120,
            "Regal Orb": 40,
            "Exalted Orb": 15,
            "Chaos Orb": 450,
            "Divine Orb": 3,
        }

        plan = profit_taker.evaluate_profit_taking(holdings, current_gold=25000)
        report_str = profit_taker.format_ascii_plan(plan)
        print("\n" + report_str)

        # Kiem tra nhan bat buoc Rule 5
        assert "[MO PHONG THUAT TOAN HEADLESS - KHONG PHAI LIVE GAME]" in report_str
        assert plan.total_orders > 0
        assert plan.projected_divine_bought >= 3
        assert plan.remaining_gold_balance >= 5000
