#!/usr/bin/env python3
"""
WalletConnect v2 Session Manager
Connects our wallet to ApolloX via WalletConnect
"""
import asyncio
import websockets
import json
import os
from dotenv import load_dotenv
from web3 import Web3
from eth_account import Account
import base64
from Crypto.Cipher import AES
from Crypto.Random import get_random_bytes
import hashlib

load_dotenv()

# Our wallet
PRIVATE_KEY = os.getenv('WALLET_PRIVATE_KEY')
account = Account.from_key(PRIVATE_KEY)
WALLET_ADDRESS = account.address

print("="*80)
print("🔗 WALLETCONNECT V2 SESSION")
print("="*80)
print(f"Wallet: {WALLET_ADDRESS}")
print(f"Chain: BSC (56)")

# Parse WalletConnect URI
WC_URI = "wc:b6772184bb7633645084a2eb8cc1194c7962ed572e79f38db8b75ff955469b25@2?relay-protocol=irn&symKey=ffd212f53e90ef68056972e87e46cf957c58c1727c055d3b3e85dec46383bd40"

# Parse URI components
parts = WC_URI.replace("wc:", "").split("@")
topic = parts[0]
version = parts[1].split("?")[0]

# Parse query params
params = {}
for param in parts[1].split("?")[1].split("&"):
    key, value = param.split("=")
    params[key] = value

relay_protocol = params.get('relay-protocol')
sym_key_hex = params.get('symKey')

print(f"\n📋 Connection Details:")
print(f"   Topic: {topic}")
print(f"   Version: {version}")
print(f"   Relay: {relay_protocol}")
print(f"   SymKey: {sym_key_hex[:20]}...")

# Convert symKey from hex to bytes
sym_key = bytes.fromhex(sym_key_hex)

# WalletConnect v2 Relay URL
RELAY_URL = f"wss://relay.walletconnect.com?projectId=demo"

print(f"\n🌐 Connecting to relay: {RELAY_URL}")

async def handle_walletconnect():
    """Handle WalletConnect session"""

    async with websockets.connect(RELAY_URL) as websocket:
        print(f"✅ Connected to relay")

        # Subscribe to the topic
        subscribe_msg = {
            "id": 1,
            "jsonrpc": "2.0",
            "method": "irn_subscribe",
            "params": {
                "topic": topic
            }
        }

        print(f"\n📡 Subscribing to topic...")
        await websocket.send(json.dumps(subscribe_msg))

        # Wait for subscription confirmation
        response = await websocket.recv()
        print(f"✅ Subscription response: {response[:200]}")

        # Listen for session proposal
        print(f"\n⏳ Waiting for session proposal from dApp...")

        timeout = 60  # 60 seconds timeout
        try:
            while True:
                message = await asyncio.wait_for(websocket.recv(), timeout=timeout)
                data = json.loads(message)

                print(f"\n📨 Received message:")
                print(f"   Type: {data.get('method', data.get('id'))}")

                # Check if it's a session proposal
                if 'params' in data and 'request' in data['params']:
                    request = data['params']['request']

                    if request.get('method') == 'wc_sessionPropose':
                        print(f"\n🎯 SESSION PROPOSAL RECEIVED!")
                        proposal = request['params']

                        print(f"\n   Proposer: {proposal.get('proposer', {}).get('metadata', {}).get('name', 'Unknown')}")
                        print(f"   Required chains: {proposal.get('requiredNamespaces', {})}")

                        # Approve the session
                        print(f"\n✅ Approving session...")

                        approval = {
                            "id": data['id'],
                            "jsonrpc": "2.0",
                            "result": {
                                "relay": {"protocol": relay_protocol},
                                "namespaces": {
                                    "eip155": {
                                        "accounts": [f"eip155:56:{WALLET_ADDRESS}"],
                                        "methods": ["eth_sendTransaction", "personal_sign", "eth_signTypedData"],
                                        "events": ["chainChanged", "accountsChanged"]
                                    }
                                }
                            }
                        }

                        # Encrypt and send approval
                        await websocket.send(json.dumps(approval))
                        print(f"✅ Session approval sent!")

                        # Keep listening for requests
                        continue

                    # Handle other requests (sign, sendTransaction, etc.)
                    elif request.get('method') in ['eth_sendTransaction', 'personal_sign', 'eth_signTypedData']:
                        print(f"\n📝 Request to {request['method']}")
                        print(f"   Params: {request.get('params')}")

                        # Here we would sign/send the transaction
                        # For now, just acknowledge

        except asyncio.TimeoutError:
            print(f"\n⏱️  Timeout waiting for messages")
        except KeyboardInterrupt:
            print(f"\n\n👋 Disconnecting...")

        print(f"\n✅ Session completed")

# Run the async handler
try:
    asyncio.run(handle_walletconnect())
except KeyboardInterrupt:
    print(f"\n\n👋 Interrupted by user")
