import '../utils/formatters.dart';

/// 合约 ABI 编码工具
///
/// 提供 Coupon / CouponFactory / Settlement 等合约的函数签名编码
class ContractAbis {
  ContractAbis._();

  // ─── 函数选择器 (Keccak256 前4字节) ────────────────────

  /// Coupon.getConfig(uint256) → 0x...
  static const couponGetConfig = '0xe3161ddd';

  /// ERC721.balanceOf(address) → 0x70a08231
  static const balanceOf = '0x70a08231';

  /// ERC721Enumerable.tokenOfOwnerByIndex(address,uint256) → 0x2f745c59
  static const tokenOfOwnerByIndex = '0x2f745c59';

  /// CouponFactory.getBatchInfo(uint256) → 0x...
  static const factoryGetBatchInfo = '0x2d1fb389';

  /// Settlement.getOrderStatus(bytes32) → 0x...
  static const getOrderStatus = '0xa8bba7b4';

  /// Compliance.isAddressFrozen(address) → 0x...
  static const isAddressFrozen = '0xe5839836';

  // ─── 编码方法 ──────────────────────────────────────────

  /// 编码 Coupon.getConfig(uint256 tokenId) 调用数据
  static String encodeCouponGetConfig(BigInt tokenId) {
    return '$couponGetConfig${Formatters.padUint256(tokenId)}';
  }

  /// 编码 balanceOf(address) 调用数据
  static String encodeBalanceOf(String address) {
    final addr = address.startsWith('0x') ? address.substring(2) : address;
    return '$balanceOf${addr.padLeft(64, '0')}';
  }

  /// 编码 tokenOfOwnerByIndex(address, uint256 index) 调用数据
  static String encodeTokenOfOwnerByIndex(String address, int index) {
    final addr = address.startsWith('0x') ? address.substring(2) : address;
    return '$tokenOfOwnerByIndex${addr.padLeft(64, '0')}${Formatters.padUint256(BigInt.from(index))}';
  }

  /// 编码 getBatchInfo(uint256 batchId)
  static String encodeGetBatchInfo(BigInt batchId) {
    return '$factoryGetBatchInfo${Formatters.padUint256(batchId)}';
  }

  /// 编码 isAddressFrozen(address)
  static String encodeIsAddressFrozen(String address) {
    final addr = address.startsWith('0x') ? address.substring(2) : address;
    return '$isAddressFrozen${addr.padLeft(64, '0')}';
  }

  // ─── 事件签名 (Topic0) ─────────────────────────────────

  /// CouponBatchMinted(uint256 batchId, address issuer, uint256 quantity)
  static const couponBatchMinted =
      '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef';

  /// Transfer(address from, address to, uint256 tokenId)
  static const transferEvent =
      '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef';

  /// OrderSettled(bytes32 orderId, address buyer, address seller, uint256 amount)
  static const orderSettled =
      '0x3ecf3be0e15f3d39b8e23b01a9a1609d13e3c56c080ea45b8e5e85ced3a4e3a0';
}
