"""
MTG Card Interaction Rule Engine

Extracts card interactions using structured rules instead of NLP.
Designed for rolling updates when new MTGJSON data is loaded.
"""
import re
from typing import Dict, List, Tuple, Optional, Any
from dataclasses import dataclass
from enum import Enum


class InteractionType(Enum):
    """Types of card interactions."""
    MECHANIC = "mechanic"
    ARCHETYPE = "archetype"
    SYNERGY = "synergy"
    COUNTER = "counter"
    EVOLUTION = "evolution"
    MANA = "mana"
    SET_THEME = "set_theme"


class SynergyType(Enum):
    """Types of synergies between cards."""
    ARCHETYPE_SUPPORT = "archetype_support"
    MECHANIC_SUPPORT = "mechanic_support"
    MANA_BASE = "mana_base"
    COMBO_PARTNER = "combo_partner"
    COUNTER_PARTNER = "counter_partner"
    EVOLUTION_CHAIN = "evolution_chain"


class CounterType(Enum):
    """Types of counter relationships."""
    DIRECT_COUNTER = "direct_counter"
    MANA_DISADVANTAGE = "mana_disadvantage"
    OUTCLASS = "outclass"
    COUNTER_ROLE = "counter_role"


class EvolutionType(Enum):
    """Types of evolution relationships."""
    TRANSFORM = "transform"
    EVOLVE = "evolve"
    DOUBLE_SIDED = "double_sided"
    MODAL_DFC = "modal_dfc"
    REPRINTED = "reprinted"


@dataclass
class CardProfile:
    """Structured profile of a card for interaction extraction."""
    name: str
    mana_cost: Optional[str]
    type_line: Optional[str]
    oracle_text: Optional[str]
    subtypes: Optional[str]
    supertypes: Optional[str]
    colors: Optional[str]
    color_identity: Optional[str]
    power: Optional[str]
    toughness: Optional[str]
    loyalty: Optional[str]
    set_code: Optional[str]
    set_id: int
    card_id: int
    
    # Extracted fields
    mechanics: List[str] = None
    archetypes: List[str] = None
    targets: List[str] = None
    triggers: List[str] = None
    effects: List[str] = None
    themes: List[str] = None
    
    def __post_init__(self):
        if self.mechanics is None:
            self.mechanics = []
        if self.archetypes is None:
            self.archetypes = []
        if self.targets is None:
            self.targets = []
        if self.triggers is None:
            self.triggers = []
        if self.effects is None:
            self.effects = []
        if self.themes is None:
            self.themes = []


class MTGRuleEngine:
    """
    Extracts card interactions using structured rules.
    
    This is NOT NLP. It uses:
    - Regex patterns for known game language
    - Curated dictionaries for mechanics/archetypes
    - Game rule logic for determining interactions
    """
    
    def __init__(self):
        # Define mechanics and their extraction patterns
        self.mechanics_patterns = {
            'flying': r'Flying',
            'first_strike': r'First strike',
            'double_strike': r'Double strike',
            'deathtouch': r'Death touch',
            'lifelink': r'Lifelink',
            'haste': r'Haste',
            'trample': r'Trample',
            'menace': r'Menace',
            'vigilance': r'Vegilance',
            'reach': r'Reach',
            'indestructible': r'Indestructible',
            'hexproof': r'Hexproof',
            'shroud': r'Shroud',
            'defender': r'Defender',
            'landfall': r'Landfall',
            'delve': r'Delve',
            'soulshift': r'Soulshift',
            'suspend': r'Suspend',
            'convoke': r'Convoke',
            'rampage': r'Rampage',
            'toxic': r'Toxic',
            'crew': r'Crew',
            'equip': r'Equip',
            'annihilator': r'Annihilator',
            'spectacle': r'Spectacle',
            'prowess': r'Prowess',
            'aftermath': r'Aftermath',
            'adapt': r'Adapt',
            'amplify': r'Amplify',
            'awaken': r'Awaken',
            'banding': r'Band with',
            'bestow': r'Bestow',
            'burst': r'Burst',
            'channel': r'Channel',
            'clash': r'Clash',
            'curse': r'Curse',
            'day_night': r'Day|Night',
            'decay': r'Decay',
            'defiant': r'Defiant',
            'demolish': r'Demolish',
            'detain': r'Detain',
            'detect': r'Detect',
            'devour': r'Devour',
            'disguise': r'Disguise',
            'disturb': r'Disturb',
            'dome': r'Dome',
            'dredge': r'Dredge',
            'emerge': r'Emerge',
            'encore': r'Encore',
            'endure': r'Endure',
            'evoke': r'Evoke',
            'evolve': r'Evolve',
            'exalted': r'Exalted',
            'exile': r'Exile',
            'exploit': r'Exploit',
            'extort': r'Extort',
            'fairy': r'Fairy',
            'fanatic': r'Fanatic',
            'fathom': r'Fathom',
            'fear': r'Fear',
            'feline': r'Feline',
            'flash': r'Flash',
            'flight': r'Flight',
            'foretell': r'Foretell',
            'frenzy': r'Frenzy',
            'fumble': r'Fumble',
            'galvanize': r'Galvanize',
            'gateway': r'Gateway',
            'genesis': r'Genesis',
            'graft': r'Graft',
            'grave': r'Grave',
            'grit': r'Grit',
            'guardian': r'Guardian',
            'harvest': r'Harvest',
            'healer': r'Healer',
            'heroic': r'Heroic',
            'hideaway': r'Hideaway',
            'hinterland': r'Hinterland',
            'hoard': r'Hoard',
            'hour': r'Hour',
            'illusion': r'Illusion',
            'immortal': r'Immortal',
            'impulse': r'Impulse',
            'inspiration': r'Inspiration',
            'instill': r'Instill',
            'iron': r'Iron',
            'junk': r'Junk',
            'kicker': r'Kicker',
            'knight': r'Knight',
            'land': r'Land',
            'leech': r'Leech',
            'lich': r'Lich',
            'lifespan': r'Lifespan',
            'lightning': r'Lightning',
            'living': r'Living',
            'lurk': r'Lurk',
            'madness': r'Madness',
            'manifest': r'Manifest',
            'map': r'Map',
            'meld': r'Meld',
            'miracle': r'Miracle',
            'mitosis': r'Mitosis',
            'modular': r'Modular',
            'moon': r'Moon',
            'mother': r'Mother',
            'morph': r'Morph',
            'mutate': r'Mutate',
            'ninja': r'Ninja',
            'night': r'Night',
            'nightmare': r'Nightmare',
            'pact': r'Pact',
            'paradox': r'Paradox',
            'persist': r'Persist',
            'pillage': r'Pillage',
            'pivot': r'Pivot',
            'planar': r'Planar',
            'polar': r'Polar',
            'pour': r'Pour',
            'prey': r'Prey',
            'priest': r'Priest',
            'primer': r'Primer',
            'probe': r'Probe',
            'prosperity': r'Prosperity',
            'psychic': r'Psychic',
            'puppet': r'Puppet',
            'quest': r'Quest',
            'quote': r'Quote',
            'rage': r'Rage',
            'raid': r'Raid',
            'raise': r'Raise',
            'rally': r'Rally',
            'rapid': r'Rapid',
            'rat': r'Rat',
            'rebound': r'Rebound',
            'reckless': r'Reckless',
            'recoup': r'Recoup',
            'reflect': r'Reflect',
            'refresh': r'Refresh',
            'replicate': r'Replicate',
            'reverberate': r'Reverberate',
            'reviviant': r'Reviviant',
            'rift': r'Rift',
            'rip': r'Rip',
            'ritual': r'Ritual',
            'rite': r'Rite',
            'rogue': r'Rogue',
            'savant': r'Savant',
            'scavenge': r'Scavenge',
            'seek': r'Seek',
            'shadow': r'Shadow',
            'shards': r'Shards',
            'skulk': r'Skulk',
            'smelt': r'Smelt',
            'snap': r'Snap',
            'snow': r'Snow',
            'spectacle': r'Spectacle',
            'splice': r'Splice',
            'spore': r'Spore',
            'sprawl': r'Sprawl',
            'stabilize': r'Stabilize',
            'stasis': r'Stasis',
            'storm': r'Storm',
            'story': r'Story',
            'substitute': r'Substitute',
            'sunder': r'Sunder',
            'surge': r'Surge',
            'survive': r'Survive',
            'swarm': r'Swarm',
            'symbiosis': r'Symbiosis',
            'synchronized': r'Synchronized',
            'synth': r'Synth',
            'table': r'Table',
            'taint': r'Taint',
            'tank': r'Tank',
            'thorn': r'Thorn',
            'thwart': r'Thwart',
            'time': r'Time',
            'tinker': r'Tinker',
            'toxin': r'Toxin',
            'trail': r'Trail',
            'transfigure': r'Transfigure',
            'transform': r'Transform',
            'transport': r'Transport',
            'trouble': r'Trouble',
            'tunnel': r'Tunnel',
            'unearth': r'Unearth',
            'unleash': r'Unleash',
            'unmask': r'Unmask',
            'unstoppable': r'Unstoppable',
            'urborg': r'Urborg',
            'urgent': r'Urgent',
            'utility': r'Utility',
            'vengeful': r'Vengeful',
            'vanish': r'Vanish',
            'venom': r'Venom',
            'victory': r'Victory',
            'villainous': r'Villainous',
            'vitalize': r'Vitalize',
            'void': r'Void',
            'voyage': r'Veoyage',
            'ward': r'Ward',
            'watch': r'Watch',
            'weave': r'Weave',
            'wed': r'Wed',
            'whammy': r'Whammy',
            'wild': r'Wild',
            'will': r'Will',
            'wisp': r'Wisp',
            'witch': r'Witch',
            'woe': r'Woe',
            'wounded': r'Wounded',
            'wrap': r'Wrap',
            'wrought': r'Wrought',
            'wurm': r'Wurm',
            'wythe': r'Wythe',
        }
        
        # Define archetype patterns
        self.archetype_patterns = {
            'goblin': r'Goblin',
            'elf': r'Elf',
            'vampire': r'Veampire',
            'angel': r'Angel',
            'dragon': r'Dragon',
            'human': r'Human',
            'zombie': r'Zombie',
            'soldier': r'Soldier',
            'knight': r'Knight',
            'wizard': r'Wizard',
            'spirit': r'Spirit',
            'demon': r'Demon',
            'snake': r'Snake',
            'cat': r'Cat',
            'wolf': r'Wolf',
            'bear': r'Bear',
            'bird': r'Bird',
            'insect': r'Insect',
            'horror': r'Horror',
            'goat': r'Goat',
            'ox': r'Ox',
            'elephant': r'Elephant',
            'whale': r'Whale',
            'shark': r'Shark',
            'fish': r'Fish',
            'serpent': r'Serpent',
            'lizard': r'Lizard',
            'scorpion': r'Scorpion',
            'spider': r'Spider',
            'rat': r'Rat',
            'drake': r'Drake',
            'wyvern': r'Wyvern',
            'phoenix': r'Phoenix',
            'lynx': r'Lynx',
            'jaguar': r'Jaguar',
            'hydra': r'Hydra',
            'leviathan': r'Leviathan',
            'kraken': r'Kraken',
            'cyclops': r'Cyclops',
            'golem': r'Golem',
            'homunculus': r'Homunculus',
            'clay': r'Clay',
            'construct': r'Construct',
            'myr': r'Myr',
            'aether': r'Aether',
            'pumpkin': r'Pumpkin',
            'pirate': r'Pirate',
            'pegasus': r'Pegasus',
            'unicorn': r'Unicorn',
            'centaur': r'Centaur',
            'merfolk': r'Merfolk',
            'mermaid': r'Mermaid',
            'naga': r'Naga',
            'satyr': r'Satyr',
            'dryad': r'Dryad',
            'treant': r'Treant',
            'elemental': r'Elemental',
            'fiend': r'Fiend',
            'imp': r'Imp',
            'faerie': r'Faerie',
            'minion': r'Minion',
            'abomination': r'Abomination',
            'beast': r'Beast',
            'demigod': r'Demigod',
            'god': r'God',
            'avatar': r'Avatar',
            'guardian': r'Guardian',
            'warrior': r'Warrior',
            'rogue': r'Rogue',
            'artificer': r'Artificer',
            'bard': r'Bard',
            'monk': r'Monk',
            'ninja': r'Ninja',
            'samurai': r'Samurai',
            'assassin': r'Assassin',
            'thief': r'Thief',
            'acrobat': r'Acrobat',
            'explorer': r'Explorer',
            'farmer': r'Farmer',
            'myth': r'Myth',
            'illusion': r'Illusion',
            'mirror': r'Mirror',
            'phantom': r'Phantom',
            'shapeshifter': r'Shapeshifter',
            'shaman': r'Shaman',
            'skeleton': r'Skeleton',
            'slime': r'Slime',
            'squirrel': r'Squirrel',
            'troll': r'Troll',
            'tyrannosaur': r'Tyrannosaur',
            'wraith': r'Wraith',
            'wurm': r'Wurm',
        }
        
        # Target types for counter interactions
        self.target_types = {
            'creature': r'creature',
            'artifact': r'artifact',
            'enchantment': r'enchantment',
            'instant': r'instant',
            'sorcery': r'sorcery',
            'planeswalker': r'planeswalker',
            'land': r'land',
            'player': r'player',
        }
        
        # Trigger patterns
        self.trigger_patterns = {
            'enters_battlefield': r'when [~|this] enters the battlefield',
            'leaves_battlefield': r'when [~|this] leaves the battlefield',
            'attacks': r'whenever [~|this] attacks',
            'blocks': r'whenever [~|this] blocks',
            'dies': r'when [~|this] dies',
            'damage': r'deals [0-9]+ damage',
            'draws_card': r'draw a card|draw two cards',
            'gains_life': r'gain [0-9]+ life',
            'creates_token': r'create a token',
            'taps': r'tap: add',
            'untaps': r'untap: add',
            'destroys': r'destroy target',
            'exiles': r'exile target',
            'counters_spell': r'counter target spell',
        }
        
        # Effect patterns
        self.effect_patterns = {
            'gain_flying': r'gain flying',
            'gain_first_strike': r'gain first strike',
            'gain_double_strike': r'gain double strike',
            'gain_deathtouch': r'gain deathtouch',
            'gain_lifelink': r'gain lifelink',
            'gain_haste': r'gain haste',
            'gain_trample': r'gain trample',
            'gain_vigilance': r'gain vigilance',
            'gain_indestructible': r'gain indestructible',
            'gain_hexproof': r'gain hexproof',
            'until_end_of_turn': r'until end of turn',
            'until_next_turn': r'until your next turn',
        }
    
    def extract_mechanics(self, card: CardProfile) -> List[str]:
        """Extract mechanics from card type line and oracle text."""
        mechanics = []
        
        # Check type line for mechanics
        if card.type_line:
            for mechanic, pattern in self.mechanics_patterns.items():
                if re.search(pattern, card.type_line, re.IGNORECASE):
                    mechanics.append(mechanic)
        
        # Check oracle text for mechanics
        if card.oracle_text:
            for mechanic, pattern in self.mechanics_patterns.items():
                if re.search(pattern, card.oracle_text, re.IGNORECASE):
                    if mechanic not in mechanics:
                        mechanics.append(mechanic)
        
        return mechanics
    
    def extract_archetypes(self, card: CardProfile) -> List[str]:
        """Extract archetypes from card subtypes."""
        archetypes = []
        
        if card.subtypes:
            for archetype, pattern in self.archetype_patterns.items():
                if re.search(pattern, card.subtypes, re.IGNORECASE):
                    archetypes.append(archetype)
        
        return archetypes
    
    def extract_targets(self, card: CardProfile) -> List[str]:
        """Extract target types from oracle text."""
        targets = []
        
        if card.oracle_text:
            for target, pattern in self.target_types.items():
                if re.search(pattern, card.oracle_text, re.IGNORECASE):
                    targets.append(target)
        
        return targets
    
    def extract_triggers(self, card: CardProfile) -> List[str]:
        """Extract trigger conditions from oracle text."""
        triggers = []
        
        if card.oracle_text:
            for trigger, pattern in self.trigger_patterns.items():
                if re.search(pattern, card.oracle_text, re.IGNORECASE):
                    triggers.append(trigger)
        
        return triggers
    
    def extract_effects(self, card: CardProfile) -> List[str]:
        """Extract game effects from oracle text."""
        effects = []
        
        if card.oracle_text:
            for effect, pattern in self.effect_patterns.items():
                if re.search(pattern, card.oracle_text, re.IGNORECASE):
                    effects.append(effect)
        
        return effects
    
    def extract_themes(self, card: CardProfile) -> List[str]:
        """Extract set themes based on card characteristics."""
        themes = []
        
        # Storm theme
        if 'storm' in card.mechanics or 'storm' in card.oracle_text.lower():
            themes.append('storm')
        
        # Token theme
        if any(e in card.effects for e in ['creates_token']):
            themes.append('tokens')
        
        # Mill theme
        if any(t in card.triggers for t in ['draws_card']):
            themes.append('draw')
        
        # Life gain theme
        if any(e in card.effects for e in ['gains_life']):
            themes.append('life_gain')
        
        # Board wipe theme
        if any(t in card.triggers for t in ['dies']):
            themes.append('board_wipe')
        
        # Reanimate theme
        if any(t in card.triggers for t in ['leaves_battlefield']):
            themes.append('reanimate')
        
        # Countermagic theme
        if any(e in card.effects for e in ['counters_spell']):
            themes.append('countermagic')
        
        # Card advantage theme
        if any(t in card.triggers for t in ['draws_card']):
            themes.append('card_advantage')
        
        # Mana acceleration theme
        if any(t in card.triggers for t in ['taps', 'untaps']):
            themes.append('mana_acceleration')
        
        # Combat tricks theme
        if any(e in card.effects for e in ['gain_flying', 'gain_first_strike', 
                                           'gain_double_strike', 'gain_deathtouch',
                                           'gain_lifelink', 'gain_vigilance']):
            themes.append('combat_tricks')
        
        # ETB effects theme
        if any(t in card.triggers for t in ['enters_battlefield']):
            themes.append('etb_effects')
        
        # LTB effects theme
        if any(t in card.triggers for t in ['leaves_battlefield']):
            themes.append('ltb_effects')
        
        return themes
    
    def profile_card(self, card_data: Dict[str, Any]) -> CardProfile:
        """Convert raw MTGJSON card data to CardProfile."""
        # Parse subtypes
        subtypes = None
        if card_data.get('subtypes'):
            subtypes = ', '.join(card_data['subtypes'])
        
        # Parse supertypes
        supertypes = None
        if card_data.get('supertypes'):
            supertypes = ', '.join(card_data['supertypes'])
        
        # Parse colors
        colors = None
        if card_data.get('colors'):
            colors = ', '.join(card_data['colors'])
        
        # Parse color identity
        color_identity = None
        if card_data.get('colorIdentity'):
            color_identity = ', '.join(card_data['colorIdentity'])
        
        # Extract interactions
        profile = CardProfile(
            name=card_data.get('name', ''),
            mana_cost=card_data.get('manaCost'),
            type_line=card_data.get('typeLine'),
            oracle_text=card_data.get('oracleText'),
            subtypes=subtypes,
            supertypes=supertypes,
            colors=colors,
            color_identity=color_identity,
            power=card_data.get('power'),
            toughness=card_data.get('toughness'),
            loyalty=card_data.get('loyalty'),
            set_code=card_data.get('set', {}).get('code') if card_data.get('set') else None,
            set_id=card_data.get('setId', 0),
            card_id=card_data.get('id', 0),
        )
        
        # Extract mechanics, archetypes, etc.
        profile.mechanics = self.extract_mechanics(profile)
        profile.archetypes = self.extract_archetypes(profile)
        profile.targets = self.extract_targets(profile)
        profile.triggers = self.extract_triggers(profile)
        profile.effects = self.extract_effects(profile)
        profile.themes = self.extract_themes(profile)
        
        return profile
    
    def find_synergies(self, card_a: CardProfile, card_b: CardProfile) -> List[Tuple[str, int, str]]:
        """
        Find synergies between two cards.
        
        Returns list of (synergy_type, strength, notes) tuples.
        """
        synergies = []
        
        # Same archetype synergy
        if card_a.archetypes and card_b.archetypes:
            common_archetypes = set(card_a.archetypes) & set(card_b.archetypes)
            if common_archetypes:
                synergies.append((
                    'archetype_support',
                    3,
                    f"Both are {', '.join(common_archetypes)}"
                ))
        
        # Mechanic support
        if card_a.mechanics and card_b.mechanics:
            # If card_b has a mechanic that supports card_a's archetype
            for mech in card_a.mechanics:
                if mech in card_b.mechanics:
                    synergies.append((
                        'mechanic_support',
                        2,
                        f"Both have {mech}"
                    ))
        
        # Mana base synergy
        if card_a.colors and card_b.colors:
            # Check for color compatibility
            colors_a = set(card_a.colors.split(','))
            colors_b = set(card_b.colors.split(','))
            
            if colors_a == colors_b:
                synergies.append((
                    'mana_base',
                    4,
                    "Same color identity"
                ))
        
        # Combo partner
        if card_a.targets and card_b.triggers:
            # If card_a targets creatures and card_b triggers on creatures
            if 'creature' in card_a.targets and any(t in card_b.triggers for t in ['enters_battlefield', 'dies']):
                synergies.append((
                    'combo_partner',
                    3,
                    "Card A targets creatures, Card B interacts with creature entry/death"
                ))
        
        # Counter partner
        if card_a.targets and card_b.targets:
            # If they target different types, they complement each other
            targets_a = set(card_a.targets)
            targets_b = set(card_b.targets)
            
            if targets_a != targets_b and targets_a & targets_b:
                synergies.append((
                    'counter_partner',
                    2,
                    "Different target types provide coverage"
                ))
        
        # Evolution chain
        if card_a.name == card_b.name:
            synergies.append((
                'evolution_chain',
                2,
                "Same card name (reprint or different version)"
            ))
        
        return synergies
    
    def find_counters(self, card_a: CardProfile, card_b: CardProfile) -> List[Tuple[str, int, str]]:
        """
        Find counter relationships between two cards.
        
        Returns list of (counter_type, strength, notes) tuples.
        """
        counters = []
        
        # Different color identities
        if card_a.color_identity and card_b.color_identity:
            colors_a = set(card_a.color_identity.split(','))
            colors_b = set(card_b.color_identity.split(','))
            
            if colors_a != colors_b:
                counters.append((
                    'mana_disadvantage',
                    2,
                    "Different color identities create strategic tension"
                ))
        
        # Outclass
        if card_a.power and card_b.power:
            try:
                power_a = int(card_a.power)
                power_b = int(card_b.power)
                
                if power_a > power_b + 1:
                    counters.append((
                        'outclass',
                        3,
                        f"Card A has higher power ({power_a} vs {power_b})"
                    ))
                elif power_b > power_a + 1:
                    counters.append((
                        'outclass',
                        3,
                        f"Card B has higher power ({power_b} vs {power_a})"
                    ))
            except (ValueError, TypeError):
                pass
        
        # Counter role
        if card_a.targets and 'creature' in card_a.targets:
            if card_b.mechanics and any(m in card_b.mechanics for m in ['deathtouch', 'trample']):
                counters.append((
                    'counter_role',
                    2,
                    "Card A targets creatures, Card B has combat keywords"
                ))
        
        return counters
    
    def find_evolution(self, card: CardProfile, all_cards: Dict[int, CardProfile]) -> List[Tuple[str, int, str]]:
        """
        Find evolution relationships for a card.
        
        Returns list of (evolution_type, strength, notes) tuples.
        """
        evolutions = []
        
        # Find reprints
        for other_id, other_card in all_cards.items():
            if other_id != card.card_id and card.name == other_card.name:
                evolutions.append((
                    'reprinted',
                    2,
                    f"Reprint in {other_card.set_code} (set_id: {other_card.set_id})"
                ))
        
        # Find transform pairs (same name, different face)
        # This would require checking card_faces in the database
        
        return evolutions
    
    def build_interaction_graph(self, cards: List[Dict[str, Any]]) -> Dict[str, Any]:
        """
        Build interaction graph for a batch of cards.
        
        Returns dictionary with:
        - mechanics: card_id -> mechanics list
        - archetypes: card_id -> archetypes list
        - synergies: (card_a, card_b) -> list of synergies
        - counters: (card_a, card_b) -> list of counters
        - evolutions: card_id -> list of evolutions
        """
        # Profile all cards
        profiles = {}
        for card_data in cards:
            if card_data.get('id'):
                profile = self.profile_card(card_data)
                profiles[profile.card_id] = profile
        
        # Extract interactions
        graph = {
            'mechanics': {},
            'archetypes': {},
            'synergies': [],
            'counters': [],
            'evolutions': [],
        }
        
        # Extract mechanics and archetypes
        for card_id, profile in profiles.items():
            graph['mechanics'][card_id] = profile.mechanics
            graph['archetypes'][card_id] = profile.archetypes
        
        # Find synergies between all card pairs
        card_ids = list(profiles.keys())
        for i in range(len(card_ids)):
            for j in range(i + 1, len(card_ids)):
                card_a = profiles[card_ids[i]]
                card_b = profiles[card_ids[j]]
                
                synergies = self.find_synergies(card_a, card_b)
                if synergies:
                    graph['synergies'].append({
                        'card_a': card_a.card_id,
                        'card_b': card_b.card_id,
                        'synergies': synergies,
                    })
        
        # Find counters between all card pairs
        for i in range(len(card_ids)):
            for j in range(i + 1, len(card_ids)):
                card_a = profiles[card_ids[i]]
                card_b = profiles[card_ids[j]]
                
                counters = self.find_counters(card_a, card_b)
                if counters:
                    graph['counters'].append({
                        'card_a': card_a.card_id,
                        'card_b': card_b.card_id,
                        'counters': counters,
                    })
        
        # Find evolutions for each card
        for card_id, profile in profiles.items():
            evolutions = self.find_evolution(profile, profiles)
            if evolutions:
                graph['evolutions'].append({
                    'card_id': card_id,
                    'evolutions': evolutions,
                })
        
        return graph


def main():
    """Test the rule engine with sample data."""
    engine = MTGRuleEngine()
    
    # Sample card data
    sample_cards = [
        {
            'id': 1,
            'name': 'Lightning Bolt',
            'manaCost': '{R}',
            'typeLine': 'Instant',
            'oracleText': 'Lightning Bolt deals 3 damage to any target.',
            'subtypes': [],
            'supertypes': [],
            'colors': ['R'],
            'colorIdentity': ['R'],
            'set': {'code': '2X2'},
            'setId': 100,
        },
        {
            'id': 2,
            'name': 'Lightning Greaves',
            'manaCost': '{1}{R}',
            'typeLine': 'Artifact — Equipment',
            'oracleText': 'Enchanted creature has hexproof and haste.\nEquip {1}',
            'subtypes': ['Equipment'],
            'supertypes': [],
            'colors': ['R'],
            'colorIdentity': ['R'],
            'power': None,
            'toughness': None,
            'set': {'code': '10E'},
            'setId': 200,
        },
        {
            'id': 3,
            'name': 'Elvish Archers',
            'manaCost': '{G}',
            'typeLine': 'Creature — Elf Ranger',
            'oracleText': 'Elvish Archers can\'t be blocked by creatures with power 2 or less.\n{T}: Target creature gets -1/-1 until end of turn.',
            'subtypes': ['Elf', 'Ranger'],
            'supertypes': [],
            'colors': ['G'],
            'colorIdentity': ['G'],
            'power': '1',
            'toughness': '1',
            'set': {'code': '5DN'},
            'setId': 300,
        },
        {
            'id': 4,
            'name': 'Swords to Plowshares',
            'manaCost': '{W}',
            'typeLine': 'Enchantment',
            'oracleText': 'Exile target creature. Its controller gains 1 life.',
            'subtypes': [],
            'supertypes': [],
            'colors': ['W'],
            'colorIdentity': ['W'],
            'set': {'code': '2X2'},
            'setId': 100,
        },
    ]
    
    # Build interaction graph
    graph = engine.build_interaction_graph(sample_cards)
    
    # Print results
    print("=" * 60)
    print("MTG Card Interaction Graph")
    print("=" * 60)
    
    print("\n📊 Mechanics:")
    for card_id, mechanics in graph['mechanics'].items():
        print(f"  Card {card_id}: {mechanics}")
    
    print("\n📊 Archetypes:")
    for card_id, archetypes in graph['archetypes'].items():
        print(f"  Card {card_id}: {archetypes}")
    
    print("\n🔗 Synergies:")
    for synergy in graph['synergies']:
        print(f"  Cards {synergy['card_a']} ↔ {synergy['card_b']}:")
        for syn_type, strength, notes in synergy['synergies']:
            print(f"    - {syn_type} (strength: {strength}): {notes}")
    
    print("\n⚔️ Counters:")
    for counter in graph['counters']:
        print(f"  Cards {counter['card_a']} ↔ {counter['card_b']}:")
        for counter_type, strength, notes in counter['counters']:
            print(f"    - {counter_type} (strength: {strength}): {notes}")
    
    print("\n🔄 Evolutions:")
    for evolution in graph['evolutions']:
        print(f"  Card {evolution['card_id']}:")
        for evol_type, strength, notes in evolution['evolutions']:
            print(f"    - {evol_type} (strength: {strength}): {notes}")
    
    print("\n" + "=" * 60)
    print("✅ Interaction graph built successfully!")
    print("=" * 60)


if __name__ == "__main__":
    main()
