/**
 * LOOPUMAN × SELFCLAW INTEGRATION
 * ================================
 * Verifies Loopuman as a human-backed agent on SelfClaw
 * Registers ERC-8004 identity on Celo
 * 
 * Run: node selfclaw-integration.js [command]
 * Commands:
 *   generate-keys   - Generate Ed25519 keypair (run once, save securely)
 *   start-verify    - Start SelfClaw verification (then scan passport)
 *   check-status    - Check verification status
 *   register-wallet - Create and register agent wallet
 *   register-services - List Loopuman's services on SelfClaw
 *   full-setup      - Run everything in sequence
 */

const crypto = require('crypto');
const fs = require('fs');
const path = require('path');

// ═══════════════════════════════════════════════════════════
// CONFIGURATION
// ═══════════════════════════════════════════════════════════

const SELFCLAW_API = 'https://selfclaw.ai/api/selfclaw/v1';
const AGENT_NAME = 'loopuman';
const KEYS_FILE = path.join(__dirname, '.selfclaw-keys.json');
const SESSION_FILE = path.join(__dirname, '.selfclaw-session.json');

// ═══════════════════════════════════════════════════════════
// STEP 1: GENERATE ED25519 KEYPAIR
// ═══════════════════════════════════════════════════════════

function generateKeys() {
  if (fs.existsSync(KEYS_FILE)) {
    console.log('⚠️  Keys already exist at', KEYS_FILE);
    const existing = JSON.parse(fs.readFileSync(KEYS_FILE, 'utf8'));
    console.log('📌 Public Key (SPKI):', existing.publicKey);
    console.log('\nTo regenerate, delete', KEYS_FILE, 'first');
    return existing;
  }

  const { publicKey, privateKey } = crypto.generateKeyPairSync('ed25519');

  // Export in SPKI DER format (base64) — required by SelfClaw
  const publicKeySpki = publicKey.export({ type: 'spki', format: 'der' }).toString('base64');
  const privateKeyPkcs8 = privateKey.export({ type: 'pkcs8', format: 'der' }).toString('base64');

  const keys = {
    publicKey: publicKeySpki,
    privateKey: privateKeyPkcs8,
    generatedAt: new Date().toISOString()
  };

  fs.writeFileSync(KEYS_FILE, JSON.stringify(keys, null, 2));
  fs.chmodSync(KEYS_FILE, '600'); // Owner read/write only

  console.log('✅ Ed25519 keypair generated!');
  console.log('📌 Public Key (SPKI):', publicKeySpki);
  console.log('🔐 Private key saved to:', KEYS_FILE);
  console.log('\n⚠️  IMPORTANT: Back up', KEYS_FILE, 'securely. Never share the private key.');

  return keys;
}

// ═══════════════════════════════════════════════════════════
// STEP 2: START SELFCLAW VERIFICATION
// ═══════════════════════════════════════════════════════════

async function startVerification() {
  const keys = loadKeys();
  if (!keys) return;

  console.log('🚀 Starting SelfClaw verification for agent:', AGENT_NAME);
  console.log('📌 Public Key:', keys.publicKey);

  const response = await fetch(`${SELFCLAW_API}/start-verification`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      agentPublicKey: keys.publicKey,
      agentName: AGENT_NAME
    })
  });

  if (!response.ok) {
    const err = await response.text();
    console.error('❌ Failed to start verification:', response.status, err);
    return null;
  }

  const data = await response.json();
  console.log('\n✅ Verification session started!');
  console.log('📋 Session ID:', data.sessionId);
  console.log('🔑 Challenge:', data.challenge);

  // Save session
  const session = { ...data, startedAt: new Date().toISOString() };
  fs.writeFileSync(SESSION_FILE, JSON.stringify(session, null, 2));

  // Sign the challenge
  console.log('\n⏳ Signing challenge...');
  const signature = await signChallenge(data.sessionId, data.challenge, keys);

  if (signature) {
    console.log('\n═══════════════════════════════════════════════');
    console.log('📱 NOW: Scan your passport with the Self app');
    console.log('═══════════════════════════════════════════════');
    console.log('');
    console.log('Option A: Visit https://selfclaw.ai and enter your public key:');
    console.log('  ', keys.publicKey);
    console.log('');
    console.log('Option B: Use the Self app to scan the QR code');
    if (data.selfApp) {
      console.log('  Self app config:', JSON.stringify(data.selfApp, null, 2));
    }
    console.log('');
    console.log('After scanning, run: node selfclaw-integration.js check-status');
  }

  return data;
}

// ═══════════════════════════════════════════════════════════
// STEP 2b: SIGN CHALLENGE
// ═══════════════════════════════════════════════════════════

async function signChallenge(sessionId, challenge, keys) {
  // Load private key
  const privateKeyDer = Buffer.from(keys.privateKey, 'base64');
  const privateKey = crypto.createPrivateKey({
    key: privateKeyDer,
    format: 'der',
    type: 'pkcs8'
  });

  // Sign the challenge
  const signature = crypto.sign(null, Buffer.from(challenge), privateKey);
  const signatureHex = signature.toString('hex');

  console.log('✍️  Signature:', signatureHex.substring(0, 40) + '...');

  // Submit signature
  const response = await fetch(`${SELFCLAW_API}/sign-challenge`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      sessionId: sessionId,
      signature: signatureHex
    })
  });

  if (!response.ok) {
    const err = await response.text();
    console.error('❌ Failed to sign challenge:', response.status, err);
    return null;
  }

  const data = await response.json();
  console.log('✅ Challenge signed successfully!');
  return data;
}

// ═══════════════════════════════════════════════════════════
// STEP 3: CHECK VERIFICATION STATUS
// ═══════════════════════════════════════════════════════════

async function checkStatus() {
  // Try session file first
  if (fs.existsSync(SESSION_FILE)) {
    const session = JSON.parse(fs.readFileSync(SESSION_FILE, 'utf8'));
    console.log('📋 Session ID:', session.sessionId);

    const response = await fetch(`${SELFCLAW_API}/verification-status/${session.sessionId}`);
    if (response.ok) {
      const data = await response.json();
      console.log('📊 Status:', data.status);

      if (data.status === 'verified') {
        console.log('\n🎉 AGENT VERIFIED! Loopuman is now a verified human-backed agent!');
        // Clean up session file
        fs.unlinkSync(SESSION_FILE);
      } else if (data.status === 'pending') {
        console.log('\n⏳ Still waiting for passport scan...');
        console.log('Visit https://selfclaw.ai and enter your public key to scan.');
      } else if (data.status === 'expired') {
        console.log('\n❌ Session expired. Run: node selfclaw-integration.js start-verify');
        fs.unlinkSync(SESSION_FILE);
      }
      return data;
    }
  }

  // Fallback: check by public key
  const keys = loadKeys();
  if (!keys) return;

  const response = await fetch(`${SELFCLAW_API}/agent?publicKey=${encodeURIComponent(keys.publicKey)}`);
  if (response.ok) {
    const data = await response.json();
    if (data.verified) {
      console.log('🎉 AGENT VERIFIED!');
      console.log('🆔 Human ID:', data.humanId);
      console.log('🤖 Agent Name:', data.agentName);
      console.log('🔗 Swarm:', data.swarm);
    } else {
      console.log('❌ Agent not yet verified.');
      console.log('Run: node selfclaw-integration.js start-verify');
    }
    return data;
  } else {
    console.log('❌ Agent not found. Run: node selfclaw-integration.js start-verify');
  }
}

// ═══════════════════════════════════════════════════════════
// STEP 4: CREATE AND REGISTER WALLET
// ═══════════════════════════════════════════════════════════

async function registerWallet() {
  const keys = loadKeys();
  if (!keys) return;

  // Check if already verified
  const agentRes = await fetch(`${SELFCLAW_API}/agent?publicKey=${encodeURIComponent(keys.publicKey)}`);
  if (!agentRes.ok) {
    console.error('❌ Agent not found. Verify first: node selfclaw-integration.js start-verify');
    return;
  }
  const agent = await agentRes.json();
  if (!agent.verified) {
    console.error('❌ Agent not verified yet. Complete passport verification first.');
    return;
  }

  console.log('🎉 Agent verified! Human ID:', agent.humanId);

  // Check if you already have a Celo wallet from your existing setup
  // If so, use that. Otherwise generate a new one.
  let walletAddress;
  let walletPrivateKey;

  const WALLET_FILE = path.join(__dirname, '.selfclaw-wallet.json');
  
  if (fs.existsSync(WALLET_FILE)) {
    const existing = JSON.parse(fs.readFileSync(WALLET_FILE, 'utf8'));
    walletAddress = existing.address;
    console.log('📌 Using existing wallet:', walletAddress);
  } else {
    // Generate new EVM wallet for the agent
    const { ethers } = require('ethers');
    const wallet = ethers.Wallet.createRandom();
    walletAddress = wallet.address;
    walletPrivateKey = wallet.privateKey;

    fs.writeFileSync(WALLET_FILE, JSON.stringify({
      address: walletAddress,
      privateKey: walletPrivateKey,
      generatedAt: new Date().toISOString(),
      note: 'Loopuman agent wallet on Celo - KEEP SECURE'
    }, null, 2));
    fs.chmodSync(WALLET_FILE, '600');

    console.log('✅ New agent wallet created!');
    console.log('📌 Address:', walletAddress);
    console.log('🔐 Saved to:', WALLET_FILE);
  }

  // Register wallet with SelfClaw
  // Sign the wallet address with Ed25519 key to prove ownership
  const privateKeyDer = Buffer.from(keys.privateKey, 'base64');
  const privateKey = crypto.createPrivateKey({
    key: privateKeyDer,
    format: 'der',
    type: 'pkcs8'
  });

  const message = `register-wallet:${walletAddress}:${Date.now()}`;
  const signature = crypto.sign(null, Buffer.from(message), privateKey).toString('hex');

  const response = await fetch(`${SELFCLAW_API}/register-wallet`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      agentPublicKey: keys.publicKey,
      walletAddress: walletAddress,
      message: message,
      signature: signature
    })
  });

  if (response.ok) {
    const data = await response.json();
    console.log('✅ Wallet registered with SelfClaw!');
    console.log('📋 Response:', JSON.stringify(data, null, 2));
    console.log('\n🔗 Next: Mint ERC-8004 identity NFT on Celo');
  } else {
    const err = await response.text();
    console.error('❌ Wallet registration failed:', response.status, err);
  }
}

// ═══════════════════════════════════════════════════════════
// STEP 5: REGISTER LOOPUMAN SERVICES
// ═══════════════════════════════════════════════════════════

async function registerServices() {
  const keys = loadKeys();
  if (!keys) return;

  // Check verification
  const agentRes = await fetch(`${SELFCLAW_API}/agent?publicKey=${encodeURIComponent(keys.publicKey)}`);
  if (!agentRes.ok || !(await agentRes.json()).verified) {
    console.error('❌ Agent not verified. Complete verification first.');
    return;
  }

  const agent = await (await fetch(`${SELFCLAW_API}/agent?publicKey=${encodeURIComponent(keys.publicKey)}`)).json();

  // Sign request
  const privateKeyDer = Buffer.from(keys.privateKey, 'base64');
  const privateKey = crypto.createPrivateKey({
    key: privateKeyDer,
    format: 'der',
    type: 'pkcs8'
  });

  const services = [
    {
      name: 'Human Task Completion',
      description: 'Route tasks to verified human workers via Telegram & WhatsApp. Tasks completed in 24-48 hours with quality checks. Categories: data labeling, content moderation, surveys, translation, transcription, research, local verification.',
      pricing: '100 VAE ($1 USD) minimum per task',
      currency: 'cUSD',
      endpoint: 'https://api.loopuman.com/api/v1/tasks/sync'
    },
    {
      name: 'Bulk Task API',
      description: 'Submit batches of tasks for parallel human completion. Up to 1000 tasks per request. Enterprise SLA with guaranteed turnaround.',
      pricing: 'Volume discounts available',
      currency: 'cUSD',
      endpoint: 'https://api.loopuman.com/api/v1/tasks/bulk'
    },
    {
      name: 'Human Verification Oracle',
      description: 'When AI confidence is low, route to human workers for ground-truth verification. Use as fallback oracle for AI pipelines. Real-time results via webhook.',
      pricing: '50 VAE ($0.50 USD) per verification',
      currency: 'cUSD',
      endpoint: 'https://api.loopuman.com/api/v1/tasks/sync'
    },
    {
      name: 'Voice-to-Task',
      description: 'Send voice notes via WhatsApp, automatically transcribed and posted as tasks for human workers. Mobile-first task creation for emerging markets.',
      pricing: 'Free transcription, standard task pricing',
      currency: 'cUSD',
      endpoint: 'https://api.loopuman.com/api/v1/voice-task'
    }
  ];

  for (const service of services) {
    const timestamp = Date.now();
    const message = `register-service:${service.name}:${timestamp}`;
    const signature = crypto.sign(null, Buffer.from(message), privateKey).toString('hex');

    const response = await fetch(`${SELFCLAW_API}/services`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        agentPublicKey: keys.publicKey,
        ...service,
        message: message,
        signature: signature
      })
    });

    if (response.ok) {
      const data = await response.json();
      console.log(`✅ Registered: ${service.name}`);
    } else {
      const err = await response.text();
      console.log(`⚠️  ${service.name}: ${response.status} - ${err}`);
    }
  }

  console.log('\n🎉 Services registered! Other agents can now discover Loopuman.');
  console.log(`🔗 View: ${SELFCLAW_API}/services/${agent.humanId}`);
}

// ═══════════════════════════════════════════════════════════
// UTILITIES
// ═══════════════════════════════════════════════════════════

function loadKeys() {
  if (!fs.existsSync(KEYS_FILE)) {
    console.error('❌ No keys found. Run: node selfclaw-integration.js generate-keys');
    return null;
  }
  return JSON.parse(fs.readFileSync(KEYS_FILE, 'utf8'));
}

// ═══════════════════════════════════════════════════════════
// FULL SETUP (GUIDED)
// ═══════════════════════════════════════════════════════════

async function fullSetup() {
  console.log('═══════════════════════════════════════════════');
  console.log('  LOOPUMAN × SELFCLAW FULL SETUP');
  console.log('  Agent Identity Verification on Celo');
  console.log('═══════════════════════════════════════════════\n');

  // Step 1: Generate keys
  console.log('── STEP 1: Generate Ed25519 Keypair ──\n');
  const keys = generateKeys();

  // Step 2: Start verification
  console.log('\n── STEP 2: Start SelfClaw Verification ──\n');
  const session = await startVerification();

  if (session) {
    console.log('\n═══════════════════════════════════════════════');
    console.log('📱 MANUAL STEP REQUIRED');
    console.log('═══════════════════════════════════════════════');
    console.log('');
    console.log('1. Open the Self app on your phone');
    console.log('2. Visit https://selfclaw.ai');
    console.log('3. Enter your public key:', keys.publicKey);
    console.log('4. Scan the QR code with Self app');
    console.log('5. Hold your passport to your phone (NFC)');
    console.log('');
    console.log('After scanning, run:');
    console.log('  node selfclaw-integration.js check-status');
    console.log('');
    console.log('Once verified, run:');
    console.log('  node selfclaw-integration.js register-wallet');
    console.log('  node selfclaw-integration.js register-services');
  }
}

// ═══════════════════════════════════════════════════════════
// CLI
// ═══════════════════════════════════════════════════════════

const command = process.argv[2] || 'help';

const commands = {
  'generate-keys': generateKeys,
  'start-verify': startVerification,
  'check-status': checkStatus,
  'register-wallet': registerWallet,
  'register-services': registerServices,
  'full-setup': fullSetup,
  'help': () => {
    console.log(`
LOOPUMAN × SELFCLAW INTEGRATION
================================

Commands:
  generate-keys      Generate Ed25519 keypair (run once)
  start-verify       Start SelfClaw verification
  check-status       Check verification status
  register-wallet    Create & register agent wallet on Celo
  register-services  List Loopuman services on SelfClaw
  full-setup         Guided full setup

Usage:
  node selfclaw-integration.js [command]

Flow:
  1. generate-keys → 2. start-verify → 3. [scan passport] → 
  4. check-status → 5. register-wallet → 6. register-services
    `);
  }
};

const fn = commands[command];
if (!fn) {
  console.error(`Unknown command: ${command}`);
  commands.help();
  process.exit(1);
}

const result = fn();
if (result instanceof Promise) {
  result.catch(err => {
    console.error('❌ Error:', err.message);
    process.exit(1);
  });
}
