const crypto = require('crypto');
const fs = require('fs');
const path = require('path');
const { ethers } = require('ethers');

const SELFCLAW_API = 'https://selfclaw.ai/api/selfclaw/v1';
const KEYS_FILE = path.join(__dirname, '.selfclaw-keys.json');
const WALLET_FILE = path.join(__dirname, '.selfclaw-wallet.json');

const keys = JSON.parse(fs.readFileSync(KEYS_FILE, 'utf8'));
const wallet = JSON.parse(fs.readFileSync(WALLET_FILE, 'utf8'));
const privKey = crypto.createPrivateKey({ key: Buffer.from(keys.privateKey, 'base64'), format: 'der', type: 'pkcs8' });

function signRequest(extraFields = {}) {
  const timestamp = Date.now();
  const nonce = crypto.randomBytes(16).toString('hex');
  const message = JSON.stringify({ agentPublicKey: keys.publicKey, timestamp, nonce });
  const signature = crypto.sign(null, Buffer.from(message), privKey).toString('hex');
  return { agentPublicKey: keys.publicKey, signature, timestamp, nonce, ...extraFields };
}

async function apiCall(endpoint, extraFields = {}) {
  const body = signRequest(extraFields);
  const res = await fetch(SELFCLAW_API + endpoint, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(body)
  });
  const text = await res.text();
  try { return { ok: res.ok, status: res.status, data: JSON.parse(text) }; }
  catch { return { ok: res.ok, status: res.status, data: text }; }
}

async function run() {
  const cmd = process.argv[2] || 'help';

  if (cmd === 'register-wallet') {
    console.log('1️⃣  Registering wallet:', wallet.address);
    const r = await apiCall('/create-wallet', { walletAddress: wallet.address });
    console.log(r.ok ? '✅ Wallet registered!' : '❌ Failed:', JSON.stringify(r.data, null, 2));
  }

  else if (cmd === 'request-gas') {
    console.log('2️⃣  Requesting 1 CELO for gas...');
    const r = await apiCall('/request-gas', { walletAddress: wallet.address });
    console.log(r.ok ? '✅ Gas received!' : '❌ Failed:', JSON.stringify(r.data, null, 2));
  }

  else if (cmd === 'mint-erc8004') {
    console.log('3️⃣  Requesting ERC-8004 unsigned tx...');
    const r = await apiCall('/register-erc8004', { walletAddress: wallet.address });
    if (!r.ok) { console.log('❌ Failed:', JSON.stringify(r.data, null, 2)); return; }
    console.log('✅ Got unsigned tx');

    const unsignedTx = r.data.transaction || r.data.unsignedTx || r.data.tx;
    if (!unsignedTx) { console.log('Response:', JSON.stringify(r.data, null, 2)); return; }

    console.log('4️⃣  Signing and submitting to Celo...');
    const provider = new ethers.JsonRpcProvider('https://forno.celo.org');
    const signer = new ethers.Wallet(wallet.privateKey, provider);

    const tx = await signer.sendTransaction(unsignedTx);
    console.log('📋 TX Hash:', tx.hash);
    console.log('⏳ Waiting for confirmation...');
    const receipt = await tx.wait();
    console.log('✅ Confirmed! Block:', receipt.blockNumber);

    console.log('5️⃣  Confirming with SelfClaw...');
    const c = await apiCall('/confirm-erc8004', { txHash: tx.hash, walletAddress: wallet.address });
    console.log(c.ok ? '🎉 ERC-8004 IDENTITY MINTED!' : '❌ Confirm failed:', JSON.stringify(c.data, null, 2));
  }

  else if (cmd === 'all') {
    console.log('═══ FULL ERC-8004 MINT FLOW ═══\n');
    
    console.log('1️⃣  Registering wallet:', wallet.address);
    const r1 = await apiCall('/create-wallet', { walletAddress: wallet.address });
    console.log(r1.ok ? '✅ Wallet registered!' : '⚠️', JSON.stringify(r1.data).substring(0, 200));

    console.log('\n2️⃣  Requesting gas...');
    const r2 = await apiCall('/request-gas', { walletAddress: wallet.address });
    console.log(r2.ok ? '✅ Gas received!' : '⚠️', JSON.stringify(r2.data).substring(0, 200));

    // Wait for gas to arrive
    if (r2.ok) {
      console.log('⏳ Waiting 10s for gas to arrive...');
      await new Promise(r => setTimeout(r, 10000));
    }

    console.log('\n3️⃣  Requesting ERC-8004 tx...');
    const r3 = await apiCall('/register-erc8004', { walletAddress: wallet.address });
    if (!r3.ok) { console.log('❌ Failed:', JSON.stringify(r3.data, null, 2)); return; }

    const unsignedTx = r3.data.transaction || r3.data.unsignedTx || r3.data.tx;
    if (!unsignedTx) { console.log('📋 Response:', JSON.stringify(r3.data, null, 2)); return; }

    console.log('\n4️⃣  Signing and submitting...');
    const provider = new ethers.JsonRpcProvider('https://forno.celo.org');
    const signer = new ethers.Wallet(wallet.privateKey, provider);
    const tx = await signer.sendTransaction(unsignedTx);
    console.log('📋 TX:', tx.hash);
    const receipt = await tx.wait();
    console.log('✅ Block:', receipt.blockNumber);

    console.log('\n5️⃣  Confirming...');
    const c = await apiCall('/confirm-erc8004', { txHash: tx.hash, walletAddress: wallet.address });
    console.log(c.ok ? '\n🎉 ERC-8004 IDENTITY MINTED ON CELO!' : '❌', JSON.stringify(c.data, null, 2));
  }

  else {
    console.log('Usage: node erc8004-mint.js [register-wallet|request-gas|mint-erc8004|all]');
    console.log('  all  = run the full flow in sequence');
  }
}

run().catch(e => { console.error('Error:', e.message); process.exit(1); });
