/**
 * Synor Bridge SDK Types
 *
 * Cross-chain asset transfers with lock-mint and burn-unlock patterns.
 */

// ==================== Chain Types ====================

/** Supported blockchain networks */
export type ChainId =
  | 'synor'
  | 'ethereum'
  | 'polygon'
  | 'arbitrum'
  | 'optimism'
  | 'bsc'
  | 'avalanche'
  | 'solana'
  | 'cosmos';

/** Chain information */
export interface Chain {
  id: ChainId;
  name: string;
  chainId: number;
  rpcUrl: string;
  explorerUrl: string;
  nativeCurrency: {
    name: string;
    symbol: string;
    decimals: number;
  };
  confirmations: number;
  estimatedBlockTime: number; // seconds
  supported: boolean;
}

// ==================== Asset Types ====================

/** Asset type */
export type AssetType = 'native' | 'erc20' | 'erc721' | 'erc1155';

/** Asset information */
export interface Asset {
  id: string;
  symbol: string;
  name: string;
  type: AssetType;
  chain: ChainId;
  contractAddress?: string;
  decimals: number;
  logoUrl?: string;
  verified: boolean;
}

/** Wrapped asset mapping */
export interface WrappedAsset {
  originalAsset: Asset;
  wrappedAsset: Asset;
  chain: ChainId;
  bridgeContract: string;
}

// ==================== Transfer Types ====================

/** Transfer status */
export type TransferStatus =
  | 'pending'
  | 'locked'
  | 'confirming'
  | 'minting'
  | 'completed'
  | 'failed'
  | 'refunded';

/** Transfer direction */
export type TransferDirection = 'lock_mint' | 'burn_unlock';

/** Lock receipt from source chain */
export interface LockReceipt {
  id: string;
  txHash: string;
  sourceChain: ChainId;
  targetChain: ChainId;
  asset: Asset;
  amount: string;
  sender: string;
  recipient: string;
  lockTimestamp: number;
  confirmations: number;
  requiredConfirmations: number;
}

/** Proof for minting on target chain */
export interface LockProof {
  lockReceipt: LockReceipt;
  merkleProof: string[];
  blockHeader: string;
  signatures: ValidatorSignature[];
}

/** Validator signature for proof */
export interface ValidatorSignature {
  validator: string;
  signature: string;
  timestamp: number;
}

/** Burn receipt for unlocking */
export interface BurnReceipt {
  id: string;
  txHash: string;
  sourceChain: ChainId;
  targetChain: ChainId;
  wrappedAsset: Asset;
  originalAsset: Asset;
  amount: string;
  sender: string;
  recipient: string;
  burnTimestamp: number;
  confirmations: number;
  requiredConfirmations: number;
}

/** Proof for unlocking on original chain */
export interface BurnProof {
  burnReceipt: BurnReceipt;
  merkleProof: string[];
  blockHeader: string;
  signatures: ValidatorSignature[];
}

/** Complete transfer record */
export interface Transfer {
  id: string;
  direction: TransferDirection;
  status: TransferStatus;
  sourceChain: ChainId;
  targetChain: ChainId;
  asset: Asset;
  amount: string;
  sender: string;
  recipient: string;
  sourceTxHash?: string;
  targetTxHash?: string;
  fee: string;
  feeAsset: Asset;
  createdAt: number;
  updatedAt: number;
  completedAt?: number;
  errorMessage?: string;
}

// ==================== Fee Types ====================

/** Fee estimate for bridge transfer */
export interface FeeEstimate {
  bridgeFee: string;
  gasFeeSource: string;
  gasFeeTarget: string;
  totalFee: string;
  feeAsset: Asset;
  estimatedTime: number; // seconds
  exchangeRate?: string;
}

/** Exchange rate between assets */
export interface ExchangeRate {
  fromAsset: Asset;
  toAsset: Asset;
  rate: string;
  inverseRate: string;
  lastUpdated: number;
  source: string;
}

// ==================== Transaction Types ====================

/** Signed transaction result */
export interface SignedTransaction {
  txHash: string;
  chain: ChainId;
  from: string;
  to: string;
  value: string;
  data: string;
  gasLimit: string;
  gasPrice?: string;
  maxFeePerGas?: string;
  maxPriorityFeePerGas?: string;
  nonce: number;
  signature: string;
}

// ==================== Filter Types ====================

/** Filter for listing transfers */
export interface TransferFilter {
  status?: TransferStatus;
  sourceChain?: ChainId;
  targetChain?: ChainId;
  asset?: string;
  sender?: string;
  recipient?: string;
  fromDate?: number;
  toDate?: number;
  limit?: number;
  offset?: number;
}

// ==================== Config Types ====================

/** Bridge configuration */
export interface BridgeConfig {
  apiKey: string;
  endpoint?: string;
  timeout?: number;
  retries?: number;
  debug?: boolean;
}

/** Default bridge endpoint */
export const DEFAULT_BRIDGE_ENDPOINT = 'https://bridge.synor.io/v1';

// ==================== Options Types ====================

/** Options for lock operation */
export interface LockOptions {
  recipient?: string; // Defaults to sender
  deadline?: number; // Unix timestamp
  slippage?: number; // Percentage (0-100)
}

/** Options for mint operation */
export interface MintOptions {
  gasLimit?: string;
  maxFeePerGas?: string;
  maxPriorityFeePerGas?: string;
}

/** Options for burn operation */
export interface BurnOptions {
  recipient?: string;
  deadline?: number;
}

/** Options for unlock operation */
export interface UnlockOptions {
  gasLimit?: string;
  gasPrice?: string;
}

// ==================== Error Types ====================

/** Bridge-specific error codes */
export type BridgeErrorCode =
  | 'INSUFFICIENT_BALANCE'
  | 'UNSUPPORTED_CHAIN'
  | 'UNSUPPORTED_ASSET'
  | 'TRANSFER_NOT_FOUND'
  | 'PROOF_INVALID'
  | 'PROOF_EXPIRED'
  | 'CONFIRMATIONS_PENDING'
  | 'BRIDGE_PAUSED'
  | 'RATE_LIMITED'
  | 'SLIPPAGE_EXCEEDED';

/** Bridge error */
export class BridgeError extends Error {
  constructor(
    message: string,
    public code?: BridgeErrorCode,
    public statusCode?: number,
    public details?: Record<string, unknown>
  ) {
    super(message);
    this.name = 'BridgeError';
  }
}
