"""
MTG Card Interaction Graph Schema

Creates tables for categorizing cards based on their interactions with each other.
This creates a knowledge graph of card relationships including:
- Synergies (cards that work well together)
- Combos (cards that create powerful combinations)
- Counters (cards that counter each other)
- Evolution chains (cards that transform/evolve)
- Partners (commander partnerships, etc.)
- Archetypes (goblins, vampires, elves, etc.)
- Mechanics (first strike, trample, flying, etc.)
- Themes (storm, tokens, mill, etc.)
- Mana relationships (land support)
- Set themes (cards that share set-specific themes)
"""
from sqlalchemy import create_engine, text

DB_URL = "postgresql+psycopg2://mtgonline:mtgonline_pass@172.18.0.2:5432/mtgdata"


class CardInteractionGraph:
    """Creates and manages the card interaction knowledge graph."""
    
    def __init__(self):
        self.engine = create_engine(DB_URL)
        self.conn = None
    
    def connect(self):
        """Connect to database."""
        self.conn = self.engine.connect()
        print("✓ Connected to database")
    
    def disconnect(self):
        """Disconnect from database."""
        if self.conn:
            self.conn.close()
        self.engine.dispose()
        print("✓ Disconnected from database")
    
    def column_exists(self, table_name: str, column_name: str) -> bool:
        """Check if a column exists in a table."""
        result = self.conn.execute(text("""
            SELECT column_name 
            FROM information_schema.columns 
            WHERE table_name = :table AND column_name = :column
        """), {"table": table_name, "column": column_name})
        return result.fetchone() is not None
    
    def add_column(self, table_name: str, column_name: str, column_type: str):
        """Add a column to a table if it doesn't exist."""
        if not self.column_exists(table_name, column_name):
            self.conn.execute(text(f"ALTER TABLE {table_name} ADD COLUMN {column_name} {column_type}"))
            print(f"  ✓ Added: {table_name}.{column_name} ({column_type})")
    
    def create_table(self, table_sql: str):
        """Create a table if it doesn't exist."""
        self.conn.execute(text(table_sql))
        print(f"  ✓ Created table: {table_sql.split('CREATE TABLE')[1].split('(')[0].strip()}")
    
    def create_unique_constraint(self, constraint_sql: str):
        """Create a unique constraint if it doesn't exist."""
        try:
            self.conn.execute(text(constraint_sql))
            print(f"  ✓ Created constraint: {constraint_sql.split('ADD')[1].split('CONSTRAINT')[1].split('(')[0].strip()}")
        except Exception as e:
            # Constraint might already exist
            pass
    
    def create_index(self, index_sql: str):
        """Create an index if it doesn't exist."""
        self.conn.execute(text(f"CREATE INDEX IF NOT EXISTS {index_sql}"))
        print(f"  ✓ Created index: {index_sql.split('ON ')[1].split(' ')[0]}")
    
    def create_card_mechanics_table(self):
        """Create table for card mechanics (first strike, trample, flying, etc.)."""
        print("\n📊 Creating mtg_card_mechanics table...")
        
        self.create_table("""
            CREATE TABLE IF NOT EXISTS mtg_card_mechanics (
                id SERIAL PRIMARY KEY,
                card_id INTEGER REFERENCES mtg_cards(id) ON DELETE CASCADE,
                mechanic VARCHAR(100) NOT NULL,
                strength INTEGER DEFAULT 1,
                created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
                UNIQUE(card_id, mechanic)
            )
        """)
        
        # Add indexes for frequently queried mechanics
        indexes = [
            "idx_mechanics_card_id ON mtg_card_mechanics(card_id)",
            "idx_mechanics_mechanic ON mtg_card_mechanics(mechanic)",
        ]
        for idx in indexes:
            self.create_index(idx)
        
        print("  ✓ Card mechanics table created")
    
    def create_card_archetypes_table(self):
        """Create table for card archetypes (goblins, vampires, elves, etc.)."""
        print("\n📊 Creating mtg_card_archetypes table...")
        
        self.create_table("""
            CREATE TABLE IF NOT EXISTS mtg_card_archetypes (
                id SERIAL PRIMARY KEY,
                card_id INTEGER REFERENCES mtg_cards(id) ON DELETE CASCADE,
                archetype VARCHAR(100) NOT NULL,
                strength INTEGER DEFAULT 1,
                created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
                UNIQUE(card_id, archetype)
            )
        """)
        
        indexes = [
            "idx_archetypes_card_id ON mtg_card_archetypes(card_id)",
            "idx_archetypes_archetype ON mtg_card_archetypes(archetype)",
        ]
        for idx in indexes:
            self.create_index(idx)
        
        print("  ✓ Card archetypes table created")
    
    def create_card_themes_table(self):
        """Create table for card themes (storm, tokens, mill, etc.)."""
        print("\n📊 Creating mtg_card_themes table...")
        
        self.create_table("""
            CREATE TABLE IF NOT EXISTS mtg_card_themes (
                id SERIAL PRIMARY KEY,
                card_id INTEGER REFERENCES mtg_cards(id) ON DELETE CASCADE,
                theme VARCHAR(100) NOT NULL,
                strength INTEGER DEFAULT 1,
                created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
                UNIQUE(card_id, theme)
            )
        """)
        
        indexes = [
            "idx_themes_card_id ON mtg_card_themes(card_id)",
            "idx_themes_theme ON mtg_card_themes(theme)",
        ]
        for idx in indexes:
            self.create_index(idx)
        
        print("  ✓ Card themes table created")
    
    def create_card_relationships_table(self):
        """Create table for general card relationships."""
        print("\n📊 Creating mtg_card_relationships table...")
        
        self.create_table("""
            CREATE TABLE IF NOT EXISTS mtg_card_relationships (
                id SERIAL PRIMARY KEY,
                card_a_id INTEGER REFERENCES mtg_cards(id) ON DELETE CASCADE,
                card_b_id INTEGER REFERENCES mtg_cards(id) ON DELETE CASCADE,
                relationship_type VARCHAR(50) NOT NULL,
                -- Types: synergy, combo, counter, evolution, partner, support, rival
                strength INTEGER DEFAULT 1,
                -- Strength: 1-5 (how strong the relationship is)
                notes TEXT,
                created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
                UNIQUE(card_a_id, card_b_id, relationship_type)
            )
        """)
        
        indexes = [
            "idx_relationships_card_a ON mtg_card_relationships(card_a_id)",
            "idx_relationships_card_b ON mtg_card_relationships(card_b_id)",
            "idx_relationships_type ON mtg_card_relationships(relationship_type)",
        ]
        for idx in indexes:
            self.create_index(idx)
        
        print("  ✓ Card relationships table created")
    
    def create_card_synergies_table(self):
        """Create table for card synergies with detailed scoring."""
        print("\n📊 Creating mtg_card_synergies table...")
        
        self.create_table("""
            CREATE TABLE IF NOT EXISTS mtg_card_synergies (
                id SERIAL PRIMARY KEY,
                card_a_id INTEGER REFERENCES mtg_cards(id) ON DELETE CASCADE,
                card_b_id INTEGER REFERENCES mtg_cards(id) ON DELETE CASCADE,
                synergy_type VARCHAR(50) NOT NULL,
                -- Types: mana_base, mechanic_support, archetype_support, 
                --        combo_partner, counter_partner, evolution_chain
                strength INTEGER NOT NULL CHECK (strength BETWEEN 1 AND 5),
                -- 1: Weak synergy, 5: Essential synergy
                notes TEXT,
                created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
                UNIQUE(card_a_id, card_b_id, synergy_type)
            )
        """)
        
        indexes = [
            "idx_synergies_card_a ON mtg_card_synergies(card_a_id)",
            "idx_synergies_card_b ON mtg_card_synergies(card_b_id)",
            "idx_synergies_type ON mtg_card_synergies(synergy_type)",
            "idx_synergies_strength ON mtg_card_synergies(strength)",
        ]
        for idx in indexes:
            self.create_index(idx)
        
        print("  ✓ Card synergies table created")
    
    def create_card_counters_table(self):
        """Create table for cards that counter each other."""
        print("\n📊 Creating mtg_card_counters table...")
        
        self.create_table("""
            CREATE TABLE IF NOT EXISTS mtg_card_counters (
                id SERIAL PRIMARY KEY,
                card_a_id INTEGER REFERENCES mtg_cards(id) ON DELETE CASCADE,
                card_b_id INTEGER REFERENCES mtg_cards(id) ON DELETE CASCADE,
                counter_type VARCHAR(50) NOT NULL,
                -- Types: direct_counter, disadvantage, outclass, counter_role
                strength INTEGER DEFAULT 1,
                notes TEXT,
                created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
                UNIQUE(card_a_id, card_b_id, counter_type)
            )
        """)
        
        indexes = [
            "idx_counters_card_a ON mtg_card_counters(card_a_id)",
            "idx_counters_card_b ON mtg_card_counters(card_b_id)",
            "idx_counters_type ON mtg_card_counters(counter_type)",
        ]
        for idx in indexes:
            self.create_index(idx)
        
        print("  ✓ Card counters table created")
    
    def create_card_evolution_table(self):
        """Create table for evolution chains (cards that transform/evolve)."""
        print("\n📊 Creating mtg_card_evolution table...")
        
        self.create_table("""
            CREATE TABLE IF NOT EXISTS mtg_card_evolution (
                id SERIAL PRIMARY KEY,
                card_id INTEGER REFERENCES mtg_cards(id) ON DELETE CASCADE,
                evolved_card_id INTEGER REFERENCES mtg_cards(id) ON DELETE CASCADE,
                evolution_type VARCHAR(50) NOT NULL,
                -- Types: transform, evolve, double_sided, modal_dfc
                strength INTEGER DEFAULT 1,
                notes TEXT,
                created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
                UNIQUE(card_id, evolved_card_id, evolution_type)
            )
        """)
        
        indexes = [
            "idx_evolution_card_id ON mtg_card_evolution(card_id)",
            "idx_evolution_evolved_id ON mtg_card_evolution(evolved_card_id)",
            "idx_evolution_type ON mtg_card_evolution(evolution_type)",
        ]
        for idx in indexes:
            self.create_index(idx)
        
        print("  ✓ Card evolution table created")
    
    def create_card_partners_table(self):
        """Create table for card partnerships (commander partners, etc.)."""
        print("\n📊 Creating mtg_card_partners table...")
        
        self.create_table("""
            CREATE TABLE IF NOT EXISTS mtg_card_partners (
                id SERIAL PRIMARY KEY,
                card_a_id INTEGER REFERENCES mtg_cards(id) ON DELETE CASCADE,
                card_b_id INTEGER REFERENCES mtg_cards(id) ON DELETE CASCADE,
                partnership_type VARCHAR(50) NOT NULL,
                -- Types: commander_partner, double_faced, companion, partner_commander
                strength INTEGER DEFAULT 1,
                notes TEXT,
                created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
                UNIQUE(card_a_id, card_b_id, partnership_type)
            )
        """)
        
        indexes = [
            "idx_partners_card_a ON mtg_card_partners(card_a_id)",
            "idx_partners_card_b ON mtg_card_partners(card_b_id)",
            "idx_partners_type ON mtg_card_partners(partnership_type)",
        ]
        for idx in indexes:
            self.create_index(idx)
        
        print("  ✓ Card partners table created")
    
    def create_card_mana_relations_table(self):
        """Create table for land/mana relationships."""
        print("\n📊 Creating mtg_card_mana_relations table...")
        
        self.create_table("""
            CREATE TABLE IF NOT EXISTS mtg_card_mana_relations (
                id SERIAL PRIMARY KEY,
                card_id INTEGER REFERENCES mtg_cards(id) ON DELETE CASCADE,
                land_id INTEGER REFERENCES mtg_cards(id) ON DELETE CASCADE,
                mana_type VARCHAR(10) NOT NULL,
                -- Types: produces, taps_for, fetches, searches, enters_tapped
                strength INTEGER DEFAULT 1,
                notes TEXT,
                created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
                UNIQUE(card_id, land_id, mana_type)
            )
        """)
        
        indexes = [
            "idx_mana_card_id ON mtg_card_mana_relations(card_id)",
            "idx_mana_land_id ON mtg_card_mana_relations(land_id)",
            "idx_mana_type ON mtg_card_mana_relations(mana_type)",
        ]
        for idx in indexes:
            self.create_index(idx)
        
        print("  ✓ Card mana relations table created")
    
    def create_card_set_relations_table(self):
        """Create table for set/theme relationships."""
        print("\n📊 Creating mtg_card_set_relations table...")
        
        self.create_table("""
            CREATE TABLE IF NOT EXISTS mtg_card_set_relations (
                id SERIAL PRIMARY KEY,
                card_id INTEGER REFERENCES mtg_cards(id) ON DELETE CASCADE,
                set_id INTEGER REFERENCES mtg_sets(id) ON DELETE CASCADE,
                theme VARCHAR(100) NOT NULL,
                strength INTEGER DEFAULT 1,
                notes TEXT,
                created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
                UNIQUE(card_id, set_id, theme)
            )
        """)
        
        indexes = [
            "idx_setrel_card_id ON mtg_card_set_relations(card_id)",
            "idx_setrel_set_id ON mtg_card_set_relations(set_id)",
            "idx_setrel_theme ON mtg_card_set_relations(theme)",
        ]
        for idx in indexes:
            self.create_index(idx)
        
        print("  ✓ Card set relations table created")
    
    def create_card_power_relations_table(self):
        """Create table for power/toughness relationships."""
        print("\n📊 Creating mtg_card_power_relations table...")
        
        self.create_table("""
            CREATE TABLE IF NOT EXISTS mtg_card_power_relations (
                id SERIAL PRIMARY KEY,
                card_a_id INTEGER REFERENCES mtg_cards(id) ON DELETE CASCADE,
                card_b_id INTEGER REFERENCES mtg_cards(id) ON DELETE CASCADE,
                relation_type VARCHAR(50) NOT NULL,
                -- Types: outclasses, matches, underclasses, counters_power
                strength INTEGER DEFAULT 1,
                notes TEXT,
                created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
                UNIQUE(card_a_id, card_b_id, relation_type)
            )
        """)
        
        indexes = [
            "idx_power_card_a ON mtg_card_power_relations(card_a_id)",
            "idx_power_card_b ON mtg_card_power_relations(card_b_id)",
            "idx_power_type ON mtg_card_power_relations(relation_type)",
        ]
        for idx in indexes:
            self.create_index(idx)
        
        print("  ✓ Card power relations table created")
    
    def create_card_history_table(self):
        """Create table for card history and legacy relationships."""
        print("\n📊 Creating mtg_card_history table...")
        
        self.create_table("""
            CREATE TABLE IF NOT EXISTS mtg_card_history (
                id SERIAL PRIMARY KEY,
                card_id INTEGER REFERENCES mtg_cards(id) ON DELETE CASCADE,
                related_card_id INTEGER REFERENCES mtg_cards(id) ON DELETE CASCADE,
                history_type VARCHAR(50) NOT NULL,
                -- Types: reprinted_in, previous_version, alternative_art, 
                --        superseded_by, predecessor
                strength INTEGER DEFAULT 1,
                notes TEXT,
                created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
                UNIQUE(card_id, related_card_id, history_type)
            )
        """)
        
        indexes = [
            "idx_history_card_id ON mtg_card_history(card_id)",
            "idx_history_related_id ON mtg_card_history(related_card_id)",
            "idx_history_type ON mtg_card_history(history_type)",
        ]
        for idx in indexes:
            self.create_index(idx)
        
        print("  ✓ Card history table created")
    
    def create_card_interaction_stats_table(self):
        """Create summary statistics table for card interactions."""
        print("\n📊 Creating mtg_card_interaction_stats table...")
        
        self.create_table("""
            CREATE TABLE IF NOT EXISTS mtg_card_interaction_stats (
                id SERIAL PRIMARY KEY,
                card_id INTEGER REFERENCES mtg_cards(id) ON DELETE CASCADE,
                total_synergies INTEGER DEFAULT 0,
                total_counters INTEGER DEFAULT 0,
                total_evolution INTEGER DEFAULT 0,
                total_partners INTEGER DEFAULT 0,
                total_mechanics INTEGER DEFAULT 0,
                total_archetypes INTEGER DEFAULT 0,
                total_themes INTEGER DEFAULT 0,
                avg_synergy_strength DECIMAL(3,2) DEFAULT 0.00,
                max_synergy_strength INTEGER DEFAULT 0,
                primary_archetype VARCHAR(100),
                primary_theme VARCHAR(100),
                computed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
                UNIQUE(card_id)
            )
        """)
        
        indexes = [
            "idx_stats_card_id ON mtg_card_interaction_stats(card_id)",
            "idx_stats_total_synergies ON mtg_card_interaction_stats(total_synergies)",
            "idx_stats_primary_archetype ON mtg_card_interaction_stats(primary_archetype)",
        ]
        for idx in indexes:
            self.create_index(idx)
        
        print("  ✓ Card interaction stats table created")
    
    def populate_mechanics_from_type_line(self):
        """Populate mechanics from card type lines and oracle text."""
        print("\n🔄 Populating mechanics from type lines...")
        
        # Define mechanics to look for in type lines
        mechanics_map = {
            'Flying': 'flying',
            'Flying feet': 'flying',
            'First strike': 'first_strike',
            'Double strike': 'double_strike',
            'Deathtouch': 'deathtouch',
            'Lifelink': 'lifelink',
            'Haste': 'haste',
            'Trample': 'trample',
            'Menace': 'menace',
            'Vigilance': 'vigilance',
            'Reach': 'reach',
            'Indestructible': 'indestructible',
            'Hexproof': 'hexproof',
            'Shroud': 'shroud',
            'Defender': 'defender',
            'Etrata, the Silencer': 'first_strike',  # Just as example
            'Landfall': 'landfall',
            'Delve': 'delve',
            'Soulshift': 'soulshift',
            'Suspend': 'suspend',
            'Convoke': 'convoke',
            'Rampage': 'rampage',
            'Toxic': 'toxic',
            'Crew': 'crew',
            'Equip': 'equip',
            'Annihilator': 'annihilator',
            'Boltwall': 'boltwall',
            'Boltwing': 'boltwing',
            'Spectacle': 'spectacle',
            'Prowess': 'prowess',
            'Aftermath': 'aftermath',
            'Adapt': 'adapt',
            'Archon': 'archon',
            'Amplify': 'amplify',
            'Arrest': 'arrest',
            'Awaken': 'awaken',
            'Band with': 'banding',
            'Bestow': 'bestow',
            'Borrow': 'borrow',
            'Burst': 'burst',
            'Channel': 'channel',
            'Clash': 'clash',
            'Codex': 'codex',
            'Crawl': 'crawl',
            'Crew': 'crew',
            'Curse': 'curse',
            'Day': 'day_night',
            'Decay': 'decay',
            'Defiant': 'defiant',
            'Demolish': 'demolish',
            'Detain': 'detain',
            'Detect': 'detect',
            'Devour': 'devour',
            'Disguise': 'disguise',
            'Disturb': 'disturb',
            'Dome': 'dome',
            'Double strike': 'double_strike',
            'Dredge': 'dredge',
            'Emerge': 'emerge',
            'Encore': 'encore',
            'Endure': 'endure',
            'Evoke': 'evoke',
            'Evolve': 'evolve',
            'Exalted': 'exalted',
            'Exile': 'exile',
            'Exploit': 'exploit',
            'Extort': 'extort',
            'Fairy': 'fairy',
            'Fanatic': 'fanatic',
            'Fathom': 'fathom',
            'Fear': 'fear',
            'Feline': 'feline',
            'Flash': 'flash',
            'Flight': 'flight',
            'Foretell': 'foretell',
            'Frenzy': 'frenzy',
            'Fumble': 'fumble',
            'Galvanize': 'galvanize',
            'Gateway': 'gateway',
            'Genesis': 'genesis',
            'Graft': 'graft',
            'Grave': 'grave',
            'Grit': 'grit',
            'Guardian': 'guardian',
            'Harvest': 'harvest',
            'Healer': 'healer',
            'Heroic': 'heroic',
            'Hideaway': 'hideaway',
            'Hinterland': 'hinterland',
            'Hoard': 'hoard',
            'Hour': 'hour',
            'Illusion': 'illusion',
            'Immortal': 'immortal',
            'Impulse': 'impulse',
            'Inspiration': 'inspiration',
            'Instill': 'instill',
            'Iron': 'iron',
            'Junk': 'junk',
            'Kicker': 'kicker',
            'Knight': 'knight',
            'Land': 'land',
            'Leech': 'leech',
            'Lich': 'lich',
            'Lifespan': 'lifespan',
            'Lightning': 'lightning',
            'Living': 'living',
            'Lurk': 'lurk',
            'Madness': 'madness',
            'Manifest': 'manifest',
            'Map': 'map',
            'Meld': 'meld',
            'Miracle': 'miracle',
            'Mitosis': 'mitosis',
            'Modular': 'modular',
            'Moon': 'moon',
            'Mother': 'mother',
            'Morph': 'morph',
            'Mutate': 'mutate',
            'Ninja': 'ninja',
            'Night': 'night',
            'Nightmare': 'nightmare',
            'Pact': 'pact',
            'Paradox': 'paradox',
            'Persist': 'persist',
            'Pillage': 'pillage',
            'Pivot': 'pivot',
            'Planar': 'planar',
            'Polar': 'polar',
            'Pour': 'pour',
            'Prey': 'prey',
            'Prey': 'prey',
            'Priest': 'priest',
            'Primer': 'primer',
            'Probe': 'probe',
            'Prosperity': 'prosperity',
            'Psychic': 'psychic',
            'Puppet': 'puppet',
            'Quest': 'quest',
            'Quote': 'quote',
            'Rage': 'rage',
            'Raid': 'raid',
            'Raise': 'raise',
            'Rally': 'rally',
            'Rapid': 'rapid',
            'Rat': 'rat',
            'Rebound': 'rebound',
            'Reckless': 'reckless',
            'Recoup': 'recoup',
            'Reflect': 'reflect',
            'Refresh': 'refresh',
            'Replicate': 'replicate',
            'Reverberate': 'reverberate',
            'Reveillant': 'reviviant',
            'Rift': 'rift',
            'Rip': 'rip',
            'Ritual': 'ritual',
            'Rite': 'rite',
            'Rogue': 'rogue',
            'Savant': 'savant',
            'Scavenge': 'scavenge',
            'Seek': 'seek',
            'Shadow': 'shadow',
            'Shards': 'shards',
            'Skulk': 'skulk',
            'Smelt': 'smelt',
            'Snap': 'snap',
            'Snow': 'snow',
            'Spectacle': 'spectacle',
            'Splice': 'splice',
            'Spore': 'spore',
            'Sprawl': 'sprawl',
            'Stabilize': 'stabilize',
            'Stasis': 'stasis',
            'Storm': 'storm',
            'Story': 'story',
            'Substitute': 'substitute',
            'Sunder': 'sunder',
            'Surge': 'surge',
            'Survive': 'survive',
            'Swarm': 'swarm',
            'Symbiosis': 'symbiosis',
            'Synchronized': 'synchronized',
            'Synth': 'synth',
            'Table': 'table',
            'Taint': 'taint',
            'Tank': 'tank',
            'Thorn': 'thorn',
            'Thwart': 'thwart',
            'Time': 'time',
            'Tinker': 'tinker',
            'Toxin': 'toxin',
            'Trail': 'trail',
            'Transfigure': 'transfigure',
            'Transform': 'transform',
            'Transport': 'transport',
            'Trouble': 'trouble',
            'Tunnel': 'tunnel',
            'Unearth': 'unearth',
            'Unleash': 'unleash',
            'Unmask': 'unmask',
            'Unstoppable': 'unstoppable',
            'Urborg': 'urborg',
            'Urgent': 'urgent',
            'Utility': 'utility',
            'Vengeful': 'vengeful',
            'Vanish': 'vanish',
            'Vanish': 'vanish',
            'Venom': 'venom',
            'Victory': 'victory',
            'Villainous': 'villainous',
            'Vitalize': 'vitalize',
            'Void': 'void',
            'Voyage': 'voyage',
            'Ward': 'ward',
            'Watch': 'watch',
            'Weave': 'weave',
            'Wed': 'wed',
            'Whammy': 'whammy',
            'Wild': 'wild',
            'Will': 'will',
            'Wisp': 'wisp',
            'Witch': 'witch',
            'Woe': 'woe',
            'Wounded': 'wounded',
            'Wrap': 'wrap',
            'Wrought': 'wrought',
            'Wurm': 'wurm',
            'Wythe': 'wythe',
        }
        
        # Insert mechanics from type lines
        self.conn.execute(text("""
            INSERT INTO mtg_card_mechanics (card_id, mechanic)
            SELECT DISTINCT c.id, LOWER(UNNEST(string_to_array(c.subtypes, ',')))
            FROM mtg_cards c
            WHERE c.subtypes IS NOT NULL 
            AND c.subtypes != ''
            AND c.subtypes != 'null'
            AND LOWER(UNNEST(string_to_array(c.subtypes, ','))) IN (
                'flying', 'first_strike', 'double_strike', 'deathtouch', 'lifelink',
                'haste', 'trample', 'menace', 'vigilance', 'reach', 'indestructible',
                'hexproof', 'shroud', 'defender', 'landfall', 'delve', 'soulshift',
                'suspend', 'convoke', 'rampage', 'toxic', 'crew', 'equip', 'annihilator',
                'spectacle', 'prowess', 'aftermath', 'adapt', 'amplify', 'awaken',
                'banding', 'bestow', 'burst', 'channel', 'clash', 'crawl', 'curse',
                'day_night', 'decay', 'defiant', 'demolish', 'detain', 'detect',
                'devour', 'disguise', 'disturb', 'dome', 'double_strike', 'dredge',
                'emerge', 'encore', 'endure', 'evoke', 'evolve', 'exalted', 'exile',
                'exploit', 'extort', 'fairy', 'fanatic', 'fathom', 'fear', 'feline',
                'flash', 'flight', 'foretell', 'frenzy', 'fumble', 'galvanize',
                'gateway', 'genesis', 'graft', 'grave', 'grit', 'guardian', 'harvest',
                'healer', 'heroic', 'hideaway', 'hinterland', 'hoard', 'hour', 'illusion',
                'immortal', 'impulse', 'inspiration', 'instill', 'iron', 'junk', 'kicker',
                'knight', 'land', 'leech', 'lich', 'lifespan', 'lightning', 'living',
                'lurk', 'madness', 'manifest', 'map', 'meld', 'miracle', 'mitosis',
                'modular', 'moon', 'mother', 'morph', 'mutate', 'ninja', 'night',
                'nightmare', 'pact', 'paradox', 'persist', 'pillage', 'pivot', 'planar',
                'polar', 'pour', 'prey', 'priest', 'primer', 'probe', 'prosperity',
                'psychic', 'puppet', 'quest', 'quote', 'rage', 'raid', 'raise', 'rally',
                'rapid', 'rat', 'rebound', 'reckless', 'recoup', 'reflect', 'refresh',
                'replicate', 'reverberate', 'reviviant', 'rift', 'rip', 'ritual', 'rite',
                'rogue', 'savant', 'scavenge', 'seek', 'shadow', 'shards', 'skulk',
                'smelt', 'snap', 'snow', 'spectacle', 'splice', 'spore', 'sprawl',
                'stabilize', 'stasis', 'storm', 'story', 'substitute', 'sunder', 'surge',
                'survive', 'swarm', 'symbiosis', 'synchronized', 'synth', 'table', 'taint',
                'tank', 'thorn', 'thwart', 'time', 'tinker', 'toxin', 'trail', 'transfigure',
                'transform', 'transport', 'trouble', 'tunnel', 'unearth', 'unleash', 'unmask',
                'unstoppable', 'urborg', 'urgent', 'utility', 'vengeful', 'vanish', 'venom',
                'victory', 'villainous', 'vitalize', 'void', 'voyage', 'ward', 'watch', 'weave',
                'wed', 'whammy', 'wild', 'will', 'wisp', 'witch', 'woe', 'wounded', 'wrap',
                'wrought', 'wurm', 'wythe'
            )
            ON CONFLICT DO NOTHING
        """))
        
        print("  ✓ Populated mechanics from type lines")
    
    def populate_archetypes_from_subtypes(self):
        """Populate archetypes from card subtypes."""
        print("\n🔄 Populating archetypes from subtypes...")
        
        # Define archetype mappings
        archetype_map = {
            'Goblin': 'goblins',
            'Elf': 'elves',
            'Vampire': 'vampires',
            'Angel': 'angels',
            'Dragon': 'dragons',
            'Human': 'humans',
            'Zombie': 'zombies',
            'Soldier': 'soldiers',
            'Knight': 'knights',
            'Wizard': 'wizards',
            'Spirit': 'spirits',
            'Demon': 'demons',
            'Snake': 'snakes',
            'Cat': 'cats',
            'Wolf': 'wolves',
            'Bear': 'bears',
            'Bird': 'birds',
            'Insect': 'insects',
            'Horror': 'horrors',
            'Goat': 'goats',
            'Ox': 'oxen',
            'Elephant': 'elephants',
            'Whale': 'whales',
            'Shark': 'sharks',
            'Fish': 'fish',
            'Serpent': 'serpents',
            'Lizard': 'lizards',
            'Scorpion': 'scorpions',
            'Spider': 'spiders',
            'Rat': 'rats',
            'Snake': 'snakes',
            'Drake': 'drakes',
            'Wyvern': 'wyverns',
            'Phoenix': 'phoenixes',
            'Lynx': 'lynxes',
            'Jaguar': 'jaguars',
            'Hydra': 'hydrae',
            'Leviathan': 'leviathans',
            'Kraken': 'krakens',
            'Cyclops': 'cyclopes',
            'Golem': 'golems',
            'Homunculus': 'homunculi',
            'Clay': 'clay',
            'Construct': 'constructs',
            'Myr': 'myr',
            'Aether': 'aether',
            'Pumpkin': 'pumpkins',
            'Pirate': 'pirates',
            'Pegasus': 'pegasuses',
            'Unicorn': 'unicorns',
            'Centaur': 'centaurs',
            'Merfolk': 'merfolk',
            'Mermaid': 'mermaids',
            'Naga': 'nagas',
            'Satyr': 'satyrs',
            'Dryad': 'dryads',
            'Treant': 'treants',
            'Elemental': 'elementals',
            'Fiend': 'fiends',
            'Imp': 'imps',
            'Faerie': 'faeries',
            'Minion': 'minions',
            'Abomination': 'abominations',
            'Beast': 'beasts',
            'Demigod': 'demigods',
            'God': 'gods',
            'Avatar': 'avatars',
            'Guardian': 'guardians',
            'Warrior': 'warriors',
            'Rogue': 'rogues',
            'Artificer': 'artificers',
            'Bard': 'bards',
            'Monk': 'monks',
            'Ninja': 'ninjas',
            'Samurai': 'samurai',
            'Assassin': 'assassins',
            'Thief': 'thieves',
            'Acrobat': 'acrobats',
            'Explorer': 'explorers',
            'Farmer': 'farmers',
            'Myth': 'myths',
            'Illusion': 'illusions',
            'Mirror': 'mirrors',
            'Phantom': 'phantoms',
            'Shapeshifter': 'shapeshifters',
            'Shaman': 'shamans',
            'Shark': 'sharks',
            'Skeleton': 'skeletons',
            'Slime': 'slimes',
            'Squirrel': 'squirrels',
            'Troll': 'trolls',
            'Tyrannosaur': 'tyrannosaurs',
            'Utility': 'utilities',
            'Warrior': 'warriors',
            'Wraith': 'wraiths',
            'Wurm': 'wurms',
        }
        
        # Insert archetypes
        self.conn.execute(text("""
            INSERT INTO mtg_card_archetypes (card_id, archetype)
            SELECT DISTINCT c.id, LOWER(UNNEST(string_to_array(c.subtypes, ',')))
            FROM mtg_cards c
            WHERE c.subtypes IS NOT NULL 
            AND c.subtypes != ''
            AND c.subtypes != 'null'
            AND LOWER(UNNEST(string_to_array(c.subtypes, ','))) IN (
                'goblin', 'elf', 'vampire', 'angel', 'dragon', 'human', 'zombie',
                'soldier', 'knight', 'wizard', 'spirit', 'demon', 'snake', 'cat',
                'wolf', 'bear', 'bird', 'insect', 'horror', 'goat', 'ox', 'elephant',
                'whale', 'shark', 'fish', 'serpent', 'lizard', 'scorpion', 'spider',
                'rat', 'drake', 'wyvern', 'phoenix', 'lynx', 'jaguar', 'hydra',
                'leviathan', 'kraken', 'cyclops', 'golem', 'homunculus', 'clay',
                'construct', 'myr', 'aether', 'pumpkin', 'pirate', 'pegasus',
                'unicorn', 'centaur', 'merfolk', 'mermaid', 'naga', 'satyr', 'dryad',
                'treant', 'elemental', 'fiend', 'imp', 'faerie', 'minion', 'abomination',
                'beast', 'demigod', 'god', 'avatar', 'guardian', 'warrior', 'rogue',
                'artificer', 'bard', 'monk', 'ninja', 'samurai', 'assassin', 'thief',
                'acrobat', 'explorer', 'farmer', 'myth', 'illusion', 'mirror', 'phantom',
                'shapeshifter', 'shaman', 'skeleton', 'slime', 'squirrel', 'troll',
                'tyrannosaur', 'wraith', 'wurm'
            )
            ON CONFLICT DO NOTHING
        """))
        
        print("  ✓ Populated archetypes from subtypes")
    
    def populate_themes_from_oracle_text(self):
        """Populate themes from oracle text patterns."""
        print("\n🔄 Populating themes from oracle text...")
        
        # Define theme patterns to search for
        theme_patterns = [
            ('storm', 'oracle_text LIKE \'%cast %spell%\' OR oracle_text LIKE \'%copy spell%\' OR oracle_text LIKE \'%cast additional spell%\''),
            ('tokens', 'oracle_text LIKE \'%create %token%\' OR oracle_text LIKE \'%put %token%\' OR oracle_text LIKE \'%you get %token%\''),
            ('mill', 'oracle_text LIKE \'%mill%\' OR oracle_text LIKE \'%put cards from top of your library into your graveyard%\''),
            ('flicker', 'oracle_text LIKE \'%exile %and return%\' OR oracle_text LIKE \'%unmark%\' OR oracle_text LIKE \'%bounce%\''),
            ('draw', 'oracle_text LIKE \'%draw %cards%\' OR oracle_text LIKE \'%you may draw%\''),
            ('life_gain', 'oracle_text LIKE \'%gain life%\' OR oracle_text LIKE \'%you gain % life%\''),
            ('board_wipe', 'oracle_text LIKE \'%all creatures get -%\' OR oracle_text LIKE \'%destroy all creatures%\''),
            ('deck_out', 'oracle_text LIKE \'%lose the game%\' OR oracle_text LIKE \'%you lose the game%\''),
            ('reanimate', 'oracle_text LIKE \'%put card from graveyard%\' OR oracle_text LIKE \'%return card from graveyard%\''),
            ('countermagic', 'oracle_text LIKE \'%counter target spell%\' OR oracle_text LIKE \'%counter target spell%\''),
            ('card_advantage', 'oracle_text LIKE \'%draw %card%\' OR oracle_text LIKE \'%draw two cards%\''),
            ('mana_acceleration', 'oracle_text LIKE \'%add %mana%\' OR oracle_text LIKE \'%add {C}%\' OR oracle_text LIKE \'%add {R}%\' OR oracle_text LIKE \'%add {U}%\' OR oracle_text LIKE \'%add {B}%\' OR oracle_text LIKE \'%add {G}%\' OR oracle_text LIKE \'%add {W}%\''),
            ('combat_tricks', 'oracle_text LIKE \'%gain first strike%\' OR oracle_text LIKE \'%gain trample%\' OR oracle_text LIKE \'%gain deathtouch%\' OR oracle_text LIKE \'%gain lifelink%\' OR oracle_text LIKE \'%gain vigilance%\' OR oracle_text LIKE \'%until end of turn%\''),
            ('etb_effects', 'oracle_text LIKE \'%when %enters the battlefield%\' OR oracle_text LIKE \'%enters the battlefield with%\' OR oracle_text LIKE \'%enters the battlefield tapped%\''),
            ('ltb_effects', 'oracle_text LIKE \'%when %leaves the battlefield%\' OR oracle_text LIKE \'%leaves the battlefield, exile%\'\'' ),
            ('synergy', 'oracle_text LIKE \'%copy %spell%\' OR oracle_text LIKE \'%create %token%\' OR oracle_text LIKE \'%gain % life%\'' ),
        ]
        
        # This is a complex query, let's simplify for demonstration
        # In production, you'd want to use more sophisticated NLP or pattern matching
        
        print("  ℹ️ Theme population requires complex pattern matching")
        print("  ℹ️ Skipping for now - can be added as a separate step")
    
    def run_migration(self):
        """Run the full migration."""
        print("=" * 60)
        print("🚀 Creating Card Interaction Graph Schema")
        print("=" * 60)
        
        self.connect()
        
        # Create all interaction tables
        self.create_card_mechanics_table()
        self.create_card_archetypes_table()
        self.create_card_themes_table()
        self.create_card_relationships_table()
        self.create_card_synergies_table()
        self.create_card_counters_table()
        self.create_card_evolution_table()
        self.create_card_partners_table()
        self.create_card_mana_relations_table()
        self.create_card_set_relations_table()
        self.create_card_power_relations_table()
        self.create_card_history_table()
        self.create_card_interaction_stats_table()
        
        # Populate some data
        self.populate_mechanics_from_type_line()
        self.populate_archetypes_from_subtypes()
        # Skip themes for now (complex pattern matching)
        # self.populate_themes_from_oracle_text()
        
        self.disconnect()
        
        print("\n" + "=" * 60)
        print("✅ Card Interaction Graph created successfully!")
        print("=" * 60)


def main():
    """Main entry point."""
    graph = CardInteractionGraph()
    graph.run_migration()


if __name__ == "__main__":
    main()
