# Unit Tests for Atlas Knowledge Base & Special Node Catalog (Doc 65)
from src.assistant_tool.atlas_knowledge_base import (
    AtlasKnowledgeBase,
    AtlasNodeType,
    AtlasNodeProfile,
)
from src.assistant_tool.atlas_node_selector import (
    AtlasNode,
    AtlasStrategyConfig,
    AtlasStrategyPlanner,
)

def test_classify_well_of_souls():
    samples = [
        'The Well of Souls',
        'WELL OF SOULS',
        'Well of Soul',
        'the well of souls',
        'Heart of The Well',
        'HEART OF THE WELL',
        'Heart of the Well',
        'Heart of Well',
    ]
    for name in samples:
        profile = AtlasKnowledgeBase.classify_node(name)
        assert profile.node_type == AtlasNodeType.WELL_OF_SOULS
        assert profile.accepts_waystone is False
        assert profile.accepts_tablet is False
        assert profile.is_quest_node is False
        assert profile.activation_type == 'DIRECT_TRAVERSE'
        assert AtlasKnowledgeBase.accepts_waystone(name) is False
        assert AtlasKnowledgeBase.accepts_tablet(name) is False
        assert AtlasKnowledgeBase.is_forbidden_for_waystone_farming(name) is True

def test_classify_precursor_tower():
    samples = [
        'Precursor Tower',
        'PRECURSOR TOWER',
        'Tower of the Precursors',
        'Tablet Tower',
    ]
    for name in samples:
        profile = AtlasKnowledgeBase.classify_node(name)
        assert profile.node_type == AtlasNodeType.PRECURSOR_TOWER
        assert profile.accepts_waystone is False
        assert profile.accepts_tablet is True
        assert profile.activation_type == 'SOCKET_TABLET'
        assert AtlasKnowledgeBase.accepts_waystone(name) is False
        assert AtlasKnowledgeBase.accepts_tablet(name) is True
        assert AtlasKnowledgeBase.is_forbidden_for_waystone_farming(name) is True

def test_classify_quest_nodes():
    quest_cases = [
        ('Enigma Chamber', AtlasNodeType.QUEST_ENIGMA_CHAMBER, 'Legacy of the Precursors', 1),
        ('Western Enigma Chamber', AtlasNodeType.QUEST_ENIGMA_CHAMBER, 'Legacy of the Precursors', 1),
        ('Corrupted Nexus', AtlasNodeType.QUEST_CORRUPTED_NEXUS, 'Doryani\'s Science', 1),
        ('Great Beast Lair', AtlasNodeType.QUEST_GREAT_BEAST, 'Hilda\'s Hunting', 1),
        ('Second Great Beast', AtlasNodeType.QUEST_GREAT_BEAST, 'Hilda\'s Hunting', 1),
        ('The Withered Willow', AtlasNodeType.QUEST_WITHERED_WILLOW, 'Strange Reflection', 1),
        ('Ruins of Kingsmarch', AtlasNodeType.QUEST_KINGSMARCH_RUINS, 'The Grand Expedition', 1),
    ]
    for name, expected_type, expected_quest, expected_pts in quest_cases:
        profile = AtlasKnowledgeBase.classify_node(name)
        assert profile.node_type == expected_type, f'Failed on {name}'
        assert profile.is_quest_node is True
        assert profile.quest_title == expected_quest
        assert profile.atlas_points_reward == expected_pts
        assert profile.accepts_waystone is False
        assert AtlasKnowledgeBase.is_quest_node(name) is True

def test_classify_citadel_and_trial():
    citadel = AtlasKnowledgeBase.classify_node('Iron Citadel')
    assert citadel.node_type == AtlasNodeType.CITADEL_BOSS
    assert citadel.accepts_waystone is False
    assert citadel.activation_type == 'SPECIAL_KEY'
    assert AtlasKnowledgeBase.is_forbidden_for_waystone_farming('Iron Citadel') is True

    sekhema = AtlasKnowledgeBase.classify_node('Trial of the Sekhemas')
    assert sekhema.node_type == AtlasNodeType.TRIAL_OF_SEKHEMAS
    assert sekhema.accepts_waystone is False
    assert sekhema.activation_type == 'SPECIAL_KEY'
    assert AtlasKnowledgeBase.is_forbidden_for_waystone_farming('Trial of the Sekhemas') is True

def test_classify_regular_waystone_map():
    regular_maps = ['Deserted Map', 'Fortress Map', 'Creek Map', 'Augury Map', 'Wharf Map']
    for name in regular_maps:
        profile = AtlasKnowledgeBase.classify_node(name)
        assert profile.node_type == AtlasNodeType.REGULAR_WAYSTONE_MAP
        assert profile.accepts_waystone is True
        assert profile.accepts_tablet is False
        assert profile.is_quest_node is False
        assert profile.activation_type == 'SOCKET_WAYSTONE'
        assert AtlasKnowledgeBase.accepts_waystone(name) is True
        assert AtlasKnowledgeBase.accepts_tablet(name) is False
        assert AtlasKnowledgeBase.is_forbidden_for_waystone_farming(name) is False

def test_get_all_quest_nodes():
    quest_nodes = AtlasKnowledgeBase.get_all_quest_nodes()
    assert len(quest_nodes) >= 5
    quest_titles = [q.quest_title for q in quest_nodes]
    assert 'Legacy of the Precursors' in quest_titles
    assert 'Doryani\'s Science' in quest_titles
    assert 'Hilda\'s Hunting' in quest_titles
    assert 'Strange Reflection' in quest_titles
    assert 'The Grand Expedition' in quest_titles

def test_planner_farm_mode_excludes_well_of_souls():
    cfg = AtlasStrategyConfig(
        mode='farm_whitelist',
        min_tier=14,
        max_tier=16,
        preferred_maps=['Deserted'],
    )
    planner = AtlasStrategyPlanner(config=cfg)
    candidates = [
        AtlasNode(name='The Well of Souls', tier=0, screen_x=1250.0, screen_y=480.0),
        AtlasNode(name='Deserted Map', tier=15, screen_x=1075.0, screen_y=779.0),
    ]
    best = planner.select_best_node(candidates)
    assert best is not None
    assert best.name == 'Deserted Map'
    assert 'Well of Souls' not in best.name

def test_planner_quest_rush_prioritizes_quest_nodes():
    cfg = AtlasStrategyConfig(
        mode='atlas_quest_rush',
        min_tier=1,
        max_tier=16,
    )
    planner = AtlasStrategyPlanner(config=cfg)
    candidates = [
        AtlasNode(name='Deserted Map', tier=15, screen_x=1075.0, screen_y=779.0, is_quest_node=False),
        AtlasNode(name='Western Enigma Chamber', tier=15, screen_x=850.0, screen_y=400.0, is_quest_node=True),
    ]
    best = planner.select_best_node(candidates)
    assert best is not None
    assert 'Enigma Chamber' in best.name
    assert best.is_quest_node is True

def test_classify_burning_monolith():
    samples = [
        'The Burning Monolith',
        'THE BURNING MONOLITH',
        'Burning Monolith',
        'Monolith',
        'Arbiter of Ash',
    ]
    for name in samples:
        profile = AtlasKnowledgeBase.classify_node(name)
        assert profile.node_type == AtlasNodeType.BURNING_MONOLITH
        assert profile.accepts_waystone is False
        assert profile.activation_type == 'SPECIAL_KEY'
        assert AtlasKnowledgeBase.accepts_waystone(name) is False
        assert AtlasKnowledgeBase.is_forbidden_for_waystone_farming(name) is True

def test_classify_origin_fortress_pinnacle():
    origin_cases = [
        ('Origin Tower', AtlasNodeType.ORIGIN_TOWER, 'SPECIAL_KEY'),
        ('The Origin Tower', AtlasNodeType.ORIGIN_TOWER, 'SPECIAL_KEY'),
        ('Precursor Reactor', AtlasNodeType.PRECURSOR_REACTOR, 'SPECIAL_KEY'),
        ('Arbiter of Divinity', AtlasNodeType.PRECURSOR_REACTOR, 'SPECIAL_KEY'),
        ('Patriarch Hall', AtlasNodeType.PATRIARCH_HALL, 'DIRECT_TRAVERSE'),
        ('Matriarch Hall', AtlasNodeType.MATRIARCH_HALL, 'DIRECT_TRAVERSE'),
    ]
    for name, expected_type, expected_act in origin_cases:
        profile = AtlasKnowledgeBase.classify_node(name)
        assert profile.node_type == expected_type, f'Failed on {name}'
        assert profile.accepts_waystone is False
        assert profile.activation_type == expected_act
        assert AtlasKnowledgeBase.accepts_waystone(name) is False
        assert AtlasKnowledgeBase.is_forbidden_for_waystone_farming(name) is True

def test_classify_trial_of_chaos():
    samples = ['Trial of Chaos', 'The Trial of Chaos', 'Trialmaster', 'Chaos Trial']
    for name in samples:
        profile = AtlasKnowledgeBase.classify_node(name)
        assert profile.node_type == AtlasNodeType.TRIAL_OF_CHAOS
        assert profile.accepts_waystone is False
        assert profile.activation_type == 'SPECIAL_KEY'
        assert AtlasKnowledgeBase.accepts_waystone(name) is False
        assert AtlasKnowledgeBase.is_forbidden_for_waystone_farming(name) is True

def test_classify_unique_maps():
    unique_maps = [
        'Untainted Paradise',
        'Moment of Zen',
        'Vaults of Kamasa',
        'Phaaryl Megalith',
        'The Fractured Lake',
        'The Silent Cave',
        'Viridian Wildwood',
        'Castaway',
    ]
    for name in unique_maps:
        profile = AtlasKnowledgeBase.classify_node(name)
        assert profile.node_type == AtlasNodeType.UNIQUE_MAP, f'Failed on {name}'
        assert profile.accepts_waystone is True
        assert profile.atlas_points_reward == 2
        assert AtlasKnowledgeBase.is_unique_map(name) is True
        # Unique maps BẮT BUỘC bị cấm trong chu trình cày Waystone tự hành để chống lãng phí / kẹt cơ chế
        assert AtlasKnowledgeBase.is_forbidden_for_waystone_farming(name) is True

def test_classify_league_pinnacle_arenas():
    arenas = [
        'Simulacrum',
        'Domain of Timeless Conflict',
        'Xesht',
        'King in the Mists',
        'The Bodach',
    ]
    for name in arenas:
        profile = AtlasKnowledgeBase.classify_node(name)
        assert profile.node_type == AtlasNodeType.LEAGUE_PINNACLE_ARENA
        assert profile.accepts_waystone is False
        assert AtlasKnowledgeBase.accepts_waystone(name) is False
        assert AtlasKnowledgeBase.is_forbidden_for_waystone_farming(name) is True

def test_planner_farm_mode_excludes_all_special_nodes():
    cfg = AtlasStrategyConfig(
        mode='farm_whitelist',
        min_tier=14,
        max_tier=16,
        preferred_maps=['Deserted'],
    )
    planner = AtlasStrategyPlanner(config=cfg)
    candidates = [
        AtlasNode(name='Heart of The Well', tier=0, screen_x=1250.0, screen_y=480.0),
        AtlasNode(name='The Burning Monolith', tier=16, screen_x=1043.0, screen_y=810.0),
        AtlasNode(name='Origin Tower', tier=16, screen_x=1280.0, screen_y=500.0),
        AtlasNode(name='Untainted Paradise', tier=15, screen_x=900.0, screen_y=600.0),
        AtlasNode(name='Moment of Zen', tier=15, screen_x=950.0, screen_y=650.0),
        AtlasNode(name='Phaaryl Megalith', tier=16, screen_x=1000.0, screen_y=700.0),
        AtlasNode(name='Deserted Map', tier=15, screen_x=1075.0, screen_y=779.0),
    ]
    best = planner.select_best_node(candidates)
    assert best is not None
    assert best.name == 'Deserted Map'

