import { createPublicClient, createWalletClient, http } from 'viem';
import { privateKeyToAccount } from 'viem/accounts';
import { 
  ViemPassportSDK, 
  createViemPassportSDK, 
  Environment, 
  tRexTestnet 
} from '../src';

// 方式1: 使用便利函数创建SDK（推荐）
const easySDK = createViemPassportSDK({
  rpcUrl: 'https://testnetrpc.trex.xyz',
  env: Environment.DEV,
  // 如果有私钥，可以这样添加账户
  // account: privateKeyToAccount('0xYOUR_PRIVATE_KEY'),
});

// 方式2: 手动创建客户端（更灵活）
async function createManualSDK() {
  // 创建 Public Client
  const publicClient = createPublicClient({
    chain: tRexTestnet,
    transport: http('https://testnetrpc.trex.xyz'),
  });

  // 创建 Wallet Client（如果需要发送交易）
  const account = privateKeyToAccount('0xYOUR_PRIVATE_KEY'); // 实际使用时替换为真实私钥
  const walletClient = createWalletClient({
    account,
    chain: tRexTestnet,
    transport: http('https://testnetrpc.trex.xyz'),
  });

  // 创建 SDK 实例
  const sdk = new ViemPassportSDK({
    publicClient,
    walletClient,
    network: tRexTestnet,
    env: Environment.DEV,
  });

  return sdk;
}

// 使用示例
async function viemSDKExample() {
  const walletAddress = '0x...'; // 用户钱包地址
  
  try {
    // 1. 检查钱包是否有 Passport
    console.log('检查钱包是否有 Passport...');
    const hasPassport = await easySDK.checkWalletHasPassport(walletAddress);
    
    if (hasPassport.hasPassport) {
      console.log('找到 Passport!');
      console.log('Passport ID:', hasPassport.passportId);
      console.log('Passport 地址:', hasPassport.passportAddress);
      
      // 2. 获取 Passport 详细信息
      const passportInfo = await easySDK.getPassportInfo(hasPassport.passportAddress!);
      console.log('绑定的钱包:', passportInfo.boundWallets);
      console.log('钱包数量:', passportInfo.walletCount);
      
      // 3. 获取待处理绑定钱包列表
      const pendingWallets = await easySDK.getPendingBindWallets(
        hasPassport.passportAddress!, 
        walletAddress
      );
      console.log('待处理绑定钱包:', pendingWallets);
      
      // 4. 查询待处理绑定请求
      const pendingRequest = await easySDK.getPendingBindRequest(
        hasPassport.passportAddress!, 
        walletAddress
      );
      if (pendingRequest.exists) {
        console.log('发现待处理请求，来自:', pendingRequest.requester);
      }
      
    } else {
      console.log('该钱包没有 Passport');
      
      // 5. 预测 Passport 地址
      const predictedAddress = await easySDK.predictPassportAddress(walletAddress);
      console.log('预测的 Passport 地址:', predictedAddress);
    }
    
  } catch (error) {
    console.error('错误:', error);
  }
}

// 交易示例（需要用户签名）
async function viemTransactionExample() {
  const walletAddress = '0x...'; // 用户钱包地址
  const passportAddress = '0x...'; // Passport 地址
  
  // 需要有wallet client才能发送交易
  const sdkWithWallet = await createManualSDK();
  
  try {
    // 1. 创建 Passport
    console.log('创建 Passport...');
    const createTxHash = await sdkWithWallet.createPassport();
    console.log('创建交易哈希:', createTxHash);
    
    // 2. 请求绑定钱包
    console.log('请求绑定钱包...');
    const bindTxHash = await sdkWithWallet.requestBindWallet(passportAddress, walletAddress);
    console.log('绑定请求交易哈希:', bindTxHash);
    
    // 3. 解绑钱包
    console.log('解绑钱包...');
    const unbindTxHash = await sdkWithWallet.unbindWallet(passportAddress);
    console.log('解绑交易哈希:', unbindTxHash);
    
    // 4. 接受绑定请求
    console.log('接受绑定请求...');
    const acceptTxHash = await sdkWithWallet.acceptBindRequest(passportAddress);
    console.log('接受请求交易哈希:', acceptTxHash);
    
    // 5. 拒绝绑定请求
    console.log('拒绝绑定请求...');
    const rejectTxHash = await sdkWithWallet.rejectBindRequest(passportAddress);
    console.log('拒绝请求交易哈希:', rejectTxHash);
    
    // 6. 取消绑定请求
    console.log('取消绑定请求...');
    const cancelTxHash = await sdkWithWallet.cancelBindRequest(passportAddress, walletAddress);
    console.log('取消请求交易哈希:', cancelTxHash);
    
  } catch (error) {
    console.error('错误:', error);
  }
}

// 连接钱包示例
async function connectWalletExample() {
  try {
    // 检查是否有 MetaMask 或其他钱包
    if (typeof window.ethereum !== 'undefined') {
      // 请求用户连接钱包
      const accounts = await window.ethereum.request({
        method: 'eth_requestAccounts'
      });
      
      // 创建 wallet client
      const walletClient = createWalletClient({
        chain: tRexTestnet,
        transport: window.ethereum,
      });

      // 动态设置 wallet client
      easySDK.setWalletClient(walletClient);
      
      console.log('钱包已连接:', accounts[0]);
      return accounts[0];
    } else {
      throw new Error('请安装 MetaMask 或其他以太坊钱包');
    }
  } catch (error) {
    console.error('连接钱包失败:', error);
    throw error;
  }
}

// 批量操作示例
async function batchOperationsExample(customerId: string) {
  try {
    // 并行获取多个信息
    const walletAddress = '0x...';
    
    const [
      hasPassport,
      implementation,
      counter,
      isAbolished
    ] = await Promise.all([
      easySDK.checkWalletHasPassport(walletAddress),
      easySDK.getPassportImplementation(),
      easySDK.getPassportIdCounter(),
      easySDK.isWalletAbolished(walletAddress)
    ]);
    
    console.log('批量查询结果:');
    console.log('- 是否有 Passport:', hasPassport.hasPassport);
    console.log('- 实现地址:', implementation);
    console.log('- ID 计数器:', counter);
    console.log('- 是否被废除:', isAbolished);
    
    return {
      hasPassport,
      implementation,
      counter,
      isAbolished
    };
  } catch (error) {
    console.error('批量操作失败:', error);
    throw error;
  }
}

// 错误处理示例
async function errorHandlingExample() {
  try {
    const result = await easySDK.checkWalletHasPassport('invalid-address');
  } catch (error) {
    if (error instanceof Error) {
      switch (error.message) {
        case 'Invalid address format':
          console.log('地址格式无效');
          break;
        case 'Network not supported':
          console.log('不支持的网络');
          break;
        case 'RPC error':
          console.log('RPC 连接错误');
          break;
        default:
          console.error('未知错误:', error.message);
      }
    }
  }
}

// 运行示例
// viemSDKExample();
// viemTransactionExample();
// connectWalletExample();

export {
  viemSDKExample,
  viemTransactionExample,
  connectWalletExample,
  batchOperationsExample,
  errorHandlingExample
}; 