# frozen_string_literal: true

module SynorBridge
  # Chain identifiers
  module ChainId
    SYNOR = "synor"
    ETHEREUM = "ethereum"
    POLYGON = "polygon"
    ARBITRUM = "arbitrum"
    OPTIMISM = "optimism"
    BSC = "bsc"
    AVALANCHE = "avalanche"
    SOLANA = "solana"
    COSMOS = "cosmos"
  end

  # Asset types
  module AssetType
    NATIVE = "native"
    ERC20 = "erc20"
    ERC721 = "erc721"
    ERC1155 = "erc1155"
  end

  # Transfer status
  module TransferStatus
    PENDING = "pending"
    LOCKED = "locked"
    CONFIRMING = "confirming"
    MINTING = "minting"
    COMPLETED = "completed"
    FAILED = "failed"
    REFUNDED = "refunded"
  end

  # Transfer direction
  module TransferDirection
    LOCK_MINT = "lock_mint"
    BURN_UNLOCK = "burn_unlock"
  end

  # Native currency
  NativeCurrency = Struct.new(
    :name,
    :symbol,
    :decimals,
    keyword_init: true
  )

  # Chain
  Chain = Struct.new(
    :id,
    :name,
    :chain_id,
    :rpc_url,
    :explorer_url,
    :native_currency,
    :confirmations,
    :estimated_block_time,
    :supported,
    keyword_init: true
  )

  # Asset
  Asset = Struct.new(
    :id,
    :symbol,
    :name,
    :type,
    :chain,
    :contract_address,
    :decimals,
    :logo_url,
    :verified,
    keyword_init: true
  )

  # Wrapped asset
  WrappedAsset = Struct.new(
    :original_asset,
    :wrapped_asset,
    :chain,
    :bridge_contract,
    keyword_init: true
  )

  # Validator signature
  ValidatorSignature = Struct.new(
    :validator,
    :signature,
    :timestamp,
    keyword_init: true
  )

  # Lock receipt
  LockReceipt = Struct.new(
    :id,
    :tx_hash,
    :source_chain,
    :target_chain,
    :asset,
    :amount,
    :sender,
    :recipient,
    :lock_timestamp,
    :confirmations,
    :required_confirmations,
    keyword_init: true
  )

  # Lock proof
  LockProof = Struct.new(
    :lock_receipt,
    :merkle_proof,
    :block_header,
    :signatures,
    keyword_init: true
  )

  # Burn receipt
  BurnReceipt = Struct.new(
    :id,
    :tx_hash,
    :source_chain,
    :target_chain,
    :wrapped_asset,
    :original_asset,
    :amount,
    :sender,
    :recipient,
    :burn_timestamp,
    :confirmations,
    :required_confirmations,
    keyword_init: true
  )

  # Burn proof
  BurnProof = Struct.new(
    :burn_receipt,
    :merkle_proof,
    :block_header,
    :signatures,
    keyword_init: true
  )

  # Transfer
  Transfer = Struct.new(
    :id,
    :direction,
    :status,
    :source_chain,
    :target_chain,
    :asset,
    :amount,
    :sender,
    :recipient,
    :source_tx_hash,
    :target_tx_hash,
    :fee,
    :fee_asset,
    :created_at,
    :updated_at,
    :completed_at,
    :error_message,
    keyword_init: true
  )

  # Fee estimate
  FeeEstimate = Struct.new(
    :bridge_fee,
    :gas_fee_source,
    :gas_fee_target,
    :total_fee,
    :fee_asset,
    :estimated_time,
    :exchange_rate,
    keyword_init: true
  )

  # Exchange rate
  ExchangeRate = Struct.new(
    :from_asset,
    :to_asset,
    :rate,
    :inverse_rate,
    :last_updated,
    :source,
    keyword_init: true
  )

  # Signed transaction
  SignedTransaction = Struct.new(
    :tx_hash,
    :chain,
    :from,
    :to,
    :value,
    :data,
    :gas_limit,
    :gas_price,
    :max_fee_per_gas,
    :max_priority_fee_per_gas,
    :nonce,
    :signature,
    keyword_init: true
  )

  # Lock options
  LockOptions = Struct.new(
    :recipient,
    :deadline,
    :slippage,
    keyword_init: true
  )

  # Mint options
  MintOptions = Struct.new(
    :gas_limit,
    :max_fee_per_gas,
    :max_priority_fee_per_gas,
    keyword_init: true
  )

  # Burn options
  BurnOptions = Struct.new(
    :recipient,
    :deadline,
    keyword_init: true
  )

  # Unlock options
  UnlockOptions = Struct.new(
    :gas_limit,
    :gas_price,
    keyword_init: true
  )

  # Transfer filter
  TransferFilter = Struct.new(
    :status,
    :source_chain,
    :target_chain,
    :asset,
    :sender,
    :recipient,
    :limit,
    :offset,
    keyword_init: true
  )

  # Bridge config
  BridgeConfig = Struct.new(
    :api_key,
    :endpoint,
    :timeout,
    :retries,
    :debug,
    keyword_init: true
  ) do
    def initialize(api_key:, endpoint: "https://bridge.synor.io/v1", timeout: 60, retries: 3, debug: false)
      super(api_key: api_key, endpoint: endpoint, timeout: timeout, retries: retries, debug: debug)
    end
  end
end
