'use client';

/**
 * One-tap "Update Agent URI" sign page for ERC-8004 IdentityRegistry.
 *
 * Designed for Base App mobile users — connects via injected provider
 * (Base App, Coinbase Wallet) or WalletConnect QR for desktop wallets.
 *
 * Calls updateAgentURI(string) on the Vaultfire ERC8004IdentityRegistry
 * to point the caller's existing agent record at the canonical agent card.
 */

import React, { useEffect, useState } from 'react';
import { useWalletAuth } from '../../lib/WalletAuthContext';

const REGISTRY_ADDRESS = '0xa7BD20bf5De63df949cA5Be2F20835978eCba81A';
const NEW_AGENT_URI = 'https://theloopbreaker.com/.well-known/agent-card.json';
// Pre-encoded calldata for updateAgentURI("https://theloopbreaker.com/.well-known/agent-card.json")
// pragma: allowlist secret — this is ABI-encoded calldata, not a private key
const CALLDATA =
  '0x9f34dace0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003668747470733a2f2f7468656c6f6f70627265616b65722e636f6d2f2e77656c6c2d6b6e6f776e2f6167656e742d636172642e6a736f6e00000000000000000000'; // pragma: allowlist secret
const BASE_CHAIN_ID = 8453;
const BASE_CHAIN_HEX = '0x2105';

type Phase = 'idle' | 'connecting' | 'switching' | 'sending' | 'pending' | 'success' | 'error';

export default function UpdateAgentURIPage() {
  const { address, chainId, connect, isUnlocked } = useWalletAuth();
  const [phase, setPhase] = useState<Phase>('idle');
  const [txHash, setTxHash] = useState<string | null>(null);
  const [errorMsg, setErrorMsg] = useState<string | null>(null);
  const [currentURI, setCurrentURI] = useState<string | null>(null);
  const [registered, setRegistered] = useState<boolean | null>(null);
  const [loadingStatus, setLoadingStatus] = useState(true);

  // Read current registration status from the contract
  useEffect(() => {
    if (!address) {
      setLoadingStatus(false);
      return;
    }
    setLoadingStatus(true);
    // getAgent(address) selector: 0xfb3551ff (keccak256("getAgent(address)")[:4])
    const selector = '0xfb3551ff';
    const padded = address.slice(2).padStart(64, '0');
    const data = selector + padded;
    fetch('https://mainnet.base.org', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        jsonrpc: '2.0',
        method: 'eth_call',
        params: [{ to: REGISTRY_ADDRESS, data }, 'latest'],
        id: 1,
      }),
    })
      .then((r) => r.json())
      .then((res) => {
        const hex = res.result as string | undefined;
        if (!hex || hex === '0x') {
          setRegistered(false);
        } else {
          // Decode (string, bool, string, uint256). Active flag is at the second 32-byte slot.
          // Layout: [offset_str1][bool][offset_str2][uint256][...str1...][...str2...]
          // We just need the bool at slot 2 (offset 0x40)
          const activeWord = hex.slice(2 + 64 * 1, 2 + 64 * 2);
          const isActive = parseInt(activeWord, 16) === 1;
          setRegistered(isActive);
          // Decode first string (agentURI) — at offset specified by first 32 bytes
          try {
            const off1 = parseInt(hex.slice(2, 2 + 64), 16) * 2;
            const lenHex = hex.slice(2 + off1, 2 + off1 + 64);
            const len = parseInt(lenHex, 16);
            const strHex = hex.slice(2 + off1 + 64, 2 + off1 + 64 + len * 2);
            const decoded = Buffer.from(strHex, 'hex').toString('utf-8');
            setCurrentURI(decoded);
          } catch {
            setCurrentURI(null);
          }
        }
      })
      .catch(() => setRegistered(null))
      .finally(() => setLoadingStatus(false));
  }, [address]);

  async function handleSign() {
    setErrorMsg(null);
    setTxHash(null);
    if (!isUnlocked) {
      connect();
      return;
    }
    const eth = (typeof window !== 'undefined' && (window as any).ethereum) || null;
    if (!eth) {
      setErrorMsg('No wallet provider detected. Open this page inside Base App or connect a wallet.');
      setPhase('error');
      return;
    }
    try {
      // Switch to Base if needed
      if (chainId !== BASE_CHAIN_ID) {
        setPhase('switching');
        try {
          await eth.request({
            method: 'wallet_switchEthereumChain',
            params: [{ chainId: BASE_CHAIN_HEX }],
          });
        } catch (switchErr: any) {
          if (switchErr.code === 4902) {
            await eth.request({
              method: 'wallet_addEthereumChain',
              params: [
                {
                  chainId: BASE_CHAIN_HEX,
                  chainName: 'Base',
                  nativeCurrency: { name: 'Ethereum', symbol: 'ETH', decimals: 18 },
                  rpcUrls: ['https://mainnet.base.org'],
                  blockExplorerUrls: ['https://basescan.org'],
                },
              ],
            });
          } else {
            throw switchErr;
          }
        }
      }
      setPhase('sending');
      const hash = await eth.request({
        method: 'eth_sendTransaction',
        params: [
          {
            from: address,
            to: REGISTRY_ADDRESS,
            data: CALLDATA,
            value: '0x0',
          },
        ],
      });
      setTxHash(hash);
      setPhase('pending');
      // Poll for receipt
      const start = Date.now();
      const poll = setInterval(async () => {
        try {
          const r = await fetch('https://mainnet.base.org', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({
              jsonrpc: '2.0',
              method: 'eth_getTransactionReceipt',
              params: [hash],
              id: 1,
            }),
          });
          const j = await r.json();
          if (j.result) {
            clearInterval(poll);
            if (j.result.status === '0x1') setPhase('success');
            else {
              setErrorMsg('Transaction reverted on-chain. Check BaseScan for details.');
              setPhase('error');
            }
          } else if (Date.now() - start > 120000) {
            clearInterval(poll);
            setErrorMsg('Confirmation timeout — tx may still confirm. Check BaseScan.');
          }
        } catch {
          /* keep polling */
        }
      }, 3000);
    } catch (e: any) {
      setErrorMsg(e?.message || 'Transaction rejected or failed.');
      setPhase('error');
    }
  }

  const buttonLabel = (() => {
    if (!isUnlocked) return 'Connect Wallet';
    if (phase === 'switching') return 'Switching to Base…';
    if (phase === 'sending') return 'Awaiting wallet confirmation…';
    if (phase === 'pending') return 'Confirming on-chain…';
    if (phase === 'success') return 'Updated ✓';
    return 'Update Agent URI';
  })();

  const buttonDisabled = ['switching', 'sending', 'pending', 'success'].includes(phase);

  return (
    <div className="min-h-screen bg-black text-white px-5 py-8 flex flex-col">
      <div className="max-w-md mx-auto w-full">
        <div className="mb-6">
          <div className="text-orange-500 text-xs font-mono tracking-widest mb-2">VAULTFIRE · ERC-8004</div>
          <h1 className="text-2xl font-bold leading-tight">Update Agent URI</h1>
          <p className="text-zinc-400 text-sm mt-2">
            Point your existing on-chain agent record at the canonical Vaultfire agent card.
            Costs roughly $0.002 on Base.
          </p>
        </div>

        <div className="bg-zinc-900 border border-zinc-800 rounded-2xl p-4 mb-4 text-sm">
          <div className="flex justify-between mb-2">
            <span className="text-zinc-500">Network</span>
            <span className="font-mono">Base · 8453</span>
          </div>
          <div className="flex justify-between mb-2">
            <span className="text-zinc-500">Contract</span>
            <a
              href={`https://basescan.org/address/${REGISTRY_ADDRESS}`}
              target="_blank"
              rel="noopener noreferrer"
              className="font-mono text-orange-400 underline"
            >
              0xa7BD…a81A
            </a>
          </div>
          <div className="flex justify-between mb-2">
            <span className="text-zinc-500">Function</span>
            <span className="font-mono">updateAgentURI</span>
          </div>
          <div className="flex justify-between">
            <span className="text-zinc-500">Value</span>
            <span className="font-mono">0 ETH</span>
          </div>
        </div>

        <div className="bg-zinc-900 border border-zinc-800 rounded-2xl p-4 mb-4 text-sm break-all">
          <div className="text-zinc-500 mb-1">New agent URI</div>
          <div className="font-mono text-orange-300">{NEW_AGENT_URI}</div>
        </div>

        {address && (
          <div className="bg-zinc-900 border border-zinc-800 rounded-2xl p-4 mb-4 text-sm">
            <div className="text-zinc-500 mb-1">Connected</div>
            <div className="font-mono break-all">{address}</div>
            {loadingStatus ? (
              <div className="text-zinc-500 mt-2 text-xs">Checking on-chain status…</div>
            ) : registered === true ? (
              <div className="mt-3 text-xs">
                <div className="text-emerald-400 mb-1">✓ You are registered on ERC-8004</div>
                {currentURI && (
                  <div className="text-zinc-500 break-all">
                    Current URI: <span className="font-mono text-zinc-300">{currentURI.slice(0, 80)}{currentURI.length > 80 ? '…' : ''}</span>
                  </div>
                )}
              </div>
            ) : registered === false ? (
              <div className="mt-3 text-xs text-amber-400">
                You are NOT yet registered. This page only updates an existing record. Register via the agent hub first.
              </div>
            ) : null}
          </div>
        )}

        <button
          onClick={handleSign}
          disabled={buttonDisabled || (isUnlocked && registered === false)}
          className="w-full bg-orange-500 hover:bg-orange-600 disabled:bg-zinc-700 disabled:text-zinc-500 disabled:cursor-not-allowed text-black font-bold py-4 rounded-2xl text-lg transition"
        >
          {buttonLabel}
        </button>

        {phase === 'success' && txHash && (
          <div className="mt-4 bg-emerald-950 border border-emerald-800 rounded-2xl p-4 text-sm">
            <div className="text-emerald-400 font-bold mb-2">Agent URI updated on-chain.</div>
            <a
              href={`https://basescan.org/tx/${txHash}`}
              target="_blank"
              rel="noopener noreferrer"
              className="text-orange-400 underline font-mono break-all text-xs"
            >
              View tx · {txHash.slice(0, 10)}…{txHash.slice(-8)}
            </a>
          </div>
        )}

        {phase === 'pending' && txHash && (
          <div className="mt-4 bg-zinc-900 border border-zinc-800 rounded-2xl p-4 text-sm">
            <div className="text-zinc-400 mb-2">Transaction submitted, waiting for confirmation…</div>
            <a
              href={`https://basescan.org/tx/${txHash}`}
              target="_blank"
              rel="noopener noreferrer"
              className="text-orange-400 underline font-mono break-all text-xs"
            >
              {txHash.slice(0, 10)}…{txHash.slice(-8)}
            </a>
          </div>
        )}

        {errorMsg && (
          <div className="mt-4 bg-red-950 border border-red-800 rounded-2xl p-4 text-sm text-red-300 break-words">
            {errorMsg}
          </div>
        )}

        <div className="mt-8 text-xs text-zinc-600 text-center">
          Open this page inside Base App or any mobile wallet browser for one-tap signing.
        </div>
      </div>
    </div>
  );
}
