"""Tests for Atlas Passive Tree Planner & 115-Point Max Profit Blueprint.
======================================================================
Kiem thu toan dien:
- Khoi tao cay noi tai Atlas chuan 115 diem.
- Phan ky 3 giai doan: Early Sustain (T1-5), Mid Quantity/Gold (T6-10), Endgame League Mechanics (T11-16).
- Tuan thu do thi phu thuoc DAG (Prerequisites) trong qua trinh phan bo tu dong.
- Reset cay va thong ke chi so tong hop.
- In bao cao dinh luong tuan thu Rule 5: [MO PHONG THUAT TOAN HEADLESS - KHONG PHAI LIVE GAME].
"""

import pytest
from src.assistant_tool.atlas.atlas_tree_planner import (
    AtlasPassiveNode,
    AtlasTreePlanner,
    TreePhase,
)


class TestAtlasTreePlanner:
    def test_canonical_tree_initialization(self):
        """Kiem tra khoi tao 115 nodes noi tai voi du 3 phase."""
        planner = AtlasTreePlanner()
        assert planner.total_nodes == 115
        assert planner.allocated_count == 0

        # Kiem tra phan bo so luong node theo phase
        p1_nodes = [n for n in planner._nodes.values() if n.phase == TreePhase.PHASE_1_EARLY_SUSTAIN]
        p2_nodes = [n for n in planner._nodes.values() if n.phase == TreePhase.PHASE_2_MID_QUANTITY_GOLD]
        p3_nodes = [n for n in planner._nodes.values() if n.phase == TreePhase.PHASE_3_ENDGAME_MAX_PROFIT]

        assert len(p1_nodes) == 35, f"Phase 1 phai co 35 nodes, thuc te: {len(p1_nodes)}"
        assert len(p2_nodes) == 40, f"Phase 2 phai co 40 nodes, thuc te: {len(p2_nodes)}"
        assert len(p3_nodes) == 40, f"Phase 3 phai co 40 nodes, thuc te: {len(p3_nodes)}"

        # Kiem tra priority_order tang dan 1 -> 115
        priorities = sorted([n.priority_order for n in planner._nodes.values()])
        assert priorities == list(range(1, 116))

    def test_sequential_point_allocation_dag_validity(self):
        """Kiem tra phan bo tuan tu 115 diem luon thoa man rang buoc tien quyet (DAG Prerequisites)."""
        planner = AtlasTreePlanner()

        allocated_so_far = set()
        for expected_order in range(1, 116):
            node = planner.allocate_next_point()
            assert node is not None, f"Khong the phan bo diem thu {expected_order}"
            assert node.priority_order == expected_order, (
                f"Thu tu phan bo khong khop: expected {expected_order}, got {node.priority_order}"
            )
            assert node.allocated is True

            # Kiem tra moi tien quyet (prerequisites) da duoc phan bo truoc do
            for prereq in node.prerequisites:
                assert prereq in allocated_so_far, (
                    f"Node {node.node_id} vi pham DAG: Tien quyet {prereq} chua duoc phan bo truoc do!"
                )

            allocated_so_far.add(node.node_id)
            assert planner.allocated_count == expected_order

        # Sau khi da cap du 115 diem, goi them phai tra ve None
        extra_node = planner.allocate_next_point()
        assert extra_node is None
        assert planner.allocated_count == 115

    def test_phase_transitions(self):
        """Kiem tra su chuyen tiep giai doan chuan xac theo so diem."""
        planner = AtlasTreePlanner()

        # Phase 1: 0 - 35
        assert planner.get_current_phase(0) == TreePhase.PHASE_1_EARLY_SUSTAIN
        assert planner.get_current_phase(1) == TreePhase.PHASE_1_EARLY_SUSTAIN
        assert planner.get_current_phase(35) == TreePhase.PHASE_1_EARLY_SUSTAIN

        # Phase 2: 36 - 75
        assert planner.get_current_phase(36) == TreePhase.PHASE_2_MID_QUANTITY_GOLD
        assert planner.get_current_phase(50) == TreePhase.PHASE_2_MID_QUANTITY_GOLD
        assert planner.get_current_phase(75) == TreePhase.PHASE_2_MID_QUANTITY_GOLD

        # Phase 3: 76 - 115+
        assert planner.get_current_phase(76) == TreePhase.PHASE_3_ENDGAME_MAX_PROFIT
        assert planner.get_current_phase(100) == TreePhase.PHASE_3_ENDGAME_MAX_PROFIT
        assert planner.get_current_phase(115) == TreePhase.PHASE_3_ENDGAME_MAX_PROFIT

    def test_batch_allocation_and_reset(self):
        """Kiem tra phan bo theo batch va reset toan bo cay."""
        planner = AtlasTreePlanner()

        # Batch 1: Early Sustain (35 points)
        batch_1 = planner.allocate_batch(35)
        assert len(batch_1) == 35
        assert planner.allocated_count == 35
        stats_1 = planner.get_tree_stats()
        assert stats_1["current_phase"] == TreePhase.PHASE_1_EARLY_SUSTAIN.value
        assert stats_1["phase_distribution"][TreePhase.PHASE_1_EARLY_SUSTAIN.value] == 35

        # Batch 2: Mid Quantity & Gold (40 points)
        batch_2 = planner.allocate_batch(40)
        assert len(batch_2) == 40
        assert planner.allocated_count == 75
        stats_2 = planner.get_tree_stats()
        assert stats_2["current_phase"] == TreePhase.PHASE_2_MID_QUANTITY_GOLD.value
        assert stats_2["phase_distribution"][TreePhase.PHASE_2_MID_QUANTITY_GOLD.value] == 40

        # Batch 3: Endgame Max Profit (40 points)
        batch_3 = planner.allocate_batch(40)
        assert len(batch_3) == 40
        assert planner.allocated_count == 115
        stats_3 = planner.get_tree_stats()
        assert stats_3["current_phase"] == TreePhase.PHASE_3_ENDGAME_MAX_PROFIT.value
        assert stats_3["completion_pct"] == 100.0

        # Reset tree
        planner.reset_tree()
        assert planner.allocated_count == 0
        stats_reset = planner.get_tree_stats()
        assert stats_reset["total_allocated_points"] == 0
        assert stats_reset["completion_pct"] == 0.0

    def test_print_simulation_report_rule5_compliant(self, capsys):
        """
        Mo phong phan bo tron ven 115 diem va in bao cao dinh luong.
        Ghi chu bat buoc: [MO PHONG THUAT TOAN HEADLESS - KHONG PHAI LIVE GAME]
        """
        planner = AtlasTreePlanner()
        allocated = planner.allocate_batch(115)
        assert len(allocated) == 115

        stats = planner.get_tree_stats()

        header = "=" * 80
        report = [
            "",
            header,
            " [MO PHONG THUAT TOAN HEADLESS - KHONG PHAI LIVE GAME]",
            " BAO CAO PHAN BO CAY NOI TAI ATLAS 115 DIEM (ATLAS PASSIVE TREE PLANNER)",
            header,
            f" Tong so diem noi tai da phan bo : {stats['total_allocated_points']} / {planner.total_nodes} ({stats['completion_pct']}%)",
            f" Giai doan dat duoc               : {stats['current_phase']}",
            "-" * 80,
            " PHAN BO THEO GIAI DOAN (PHASE DISTRIBUTION):",
        ]
        for phase, count in stats["phase_distribution"].items():
            report.append(f"   * {phase:<30}: {count:>3} diem")

        report.extend([
            "-" * 80,
            " PHAN BO THEO DANH MUC CO CHE (CATEGORY DISTRIBUTION):",
        ])
        for cat, count in sorted(stats["category_distribution"].items(), key=lambda x: x[1], reverse=True):
            report.append(f"   * {cat:<20}: {count:>3} diem")

        report.extend([
            header,
            " KET LUAN: Lo trinh DAG 115 diem hoan hao, khong co chu trinh, thoa man 100% DAG prerequisites.",
            header,
            "",
        ])

        output_str = "\n".join(report)
        print(output_str)

        # Kiem tra chuoi bat buoc theo Rule 5
        assert "[MO PHONG THUAT TOAN HEADLESS - KHONG PHAI LIVE GAME]" in output_str
        assert stats["total_allocated_points"] == 115
