// Package bridge provides cross-chain asset transfer functionality.
//
// The Bridge SDK enables transferring assets between Synor and other blockchain
// networks using a lock-mint and burn-unlock pattern.
package bridge

import (
	"time"
)

// ChainID represents a supported blockchain network.
type ChainID string

const (
	ChainSynor     ChainID = "synor"
	ChainEthereum  ChainID = "ethereum"
	ChainPolygon   ChainID = "polygon"
	ChainArbitrum  ChainID = "arbitrum"
	ChainOptimism  ChainID = "optimism"
	ChainBSC       ChainID = "bsc"
	ChainAvalanche ChainID = "avalanche"
	ChainSolana    ChainID = "solana"
	ChainCosmos    ChainID = "cosmos"
)

// NativeCurrency represents a chain's native currency.
type NativeCurrency struct {
	Name     string `json:"name"`
	Symbol   string `json:"symbol"`
	Decimals int    `json:"decimals"`
}

// Chain represents a supported blockchain network.
type Chain struct {
	ID                 ChainID        `json:"id"`
	Name               string         `json:"name"`
	ChainID            int64          `json:"chainId"`
	RPCURL             string         `json:"rpcUrl"`
	ExplorerURL        string         `json:"explorerUrl"`
	NativeCurrency     NativeCurrency `json:"nativeCurrency"`
	Confirmations      int            `json:"confirmations"`
	EstimatedBlockTime int            `json:"estimatedBlockTime"` // seconds
	Supported          bool           `json:"supported"`
}

// AssetType represents the type of asset.
type AssetType string

const (
	AssetTypeNative  AssetType = "native"
	AssetTypeERC20   AssetType = "erc20"
	AssetTypeERC721  AssetType = "erc721"
	AssetTypeERC1155 AssetType = "erc1155"
)

// Asset represents a blockchain asset.
type Asset struct {
	ID              string    `json:"id"`
	Symbol          string    `json:"symbol"`
	Name            string    `json:"name"`
	Type            AssetType `json:"type"`
	Chain           ChainID   `json:"chain"`
	ContractAddress string    `json:"contractAddress,omitempty"`
	Decimals        int       `json:"decimals"`
	LogoURL         string    `json:"logoUrl,omitempty"`
	Verified        bool      `json:"verified"`
}

// WrappedAsset represents a mapping between original and wrapped assets.
type WrappedAsset struct {
	OriginalAsset  Asset   `json:"originalAsset"`
	WrappedAsset   Asset   `json:"wrappedAsset"`
	Chain          ChainID `json:"chain"`
	BridgeContract string  `json:"bridgeContract"`
}

// TransferStatus represents the status of a bridge transfer.
type TransferStatus string

const (
	TransferStatusPending    TransferStatus = "pending"
	TransferStatusLocked     TransferStatus = "locked"
	TransferStatusConfirming TransferStatus = "confirming"
	TransferStatusMinting    TransferStatus = "minting"
	TransferStatusCompleted  TransferStatus = "completed"
	TransferStatusFailed     TransferStatus = "failed"
	TransferStatusRefunded   TransferStatus = "refunded"
)

// TransferDirection represents the direction of a bridge transfer.
type TransferDirection string

const (
	TransferDirectionLockMint   TransferDirection = "lock_mint"
	TransferDirectionBurnUnlock TransferDirection = "burn_unlock"
)

// ValidatorSignature represents a validator's signature for proof.
type ValidatorSignature struct {
	Validator string `json:"validator"`
	Signature string `json:"signature"`
	Timestamp int64  `json:"timestamp"`
}

// LockReceipt represents a lock receipt from the source chain.
type LockReceipt struct {
	ID                    string  `json:"id"`
	TxHash                string  `json:"txHash"`
	SourceChain           ChainID `json:"sourceChain"`
	TargetChain           ChainID `json:"targetChain"`
	Asset                 Asset   `json:"asset"`
	Amount                string  `json:"amount"`
	Sender                string  `json:"sender"`
	Recipient             string  `json:"recipient"`
	LockTimestamp         int64   `json:"lockTimestamp"`
	Confirmations         int     `json:"confirmations"`
	RequiredConfirmations int     `json:"requiredConfirmations"`
}

// LockProof represents proof for minting on the target chain.
type LockProof struct {
	LockReceipt LockReceipt          `json:"lockReceipt"`
	MerkleProof []string             `json:"merkleProof"`
	BlockHeader string               `json:"blockHeader"`
	Signatures  []ValidatorSignature `json:"signatures"`
}

// BurnReceipt represents a burn receipt for unlocking.
type BurnReceipt struct {
	ID                    string  `json:"id"`
	TxHash                string  `json:"txHash"`
	SourceChain           ChainID `json:"sourceChain"`
	TargetChain           ChainID `json:"targetChain"`
	WrappedAsset          Asset   `json:"wrappedAsset"`
	OriginalAsset         Asset   `json:"originalAsset"`
	Amount                string  `json:"amount"`
	Sender                string  `json:"sender"`
	Recipient             string  `json:"recipient"`
	BurnTimestamp         int64   `json:"burnTimestamp"`
	Confirmations         int     `json:"confirmations"`
	RequiredConfirmations int     `json:"requiredConfirmations"`
}

// BurnProof represents proof for unlocking on the original chain.
type BurnProof struct {
	BurnReceipt BurnReceipt          `json:"burnReceipt"`
	MerkleProof []string             `json:"merkleProof"`
	BlockHeader string               `json:"blockHeader"`
	Signatures  []ValidatorSignature `json:"signatures"`
}

// Transfer represents a complete bridge transfer record.
type Transfer struct {
	ID           string            `json:"id"`
	Direction    TransferDirection `json:"direction"`
	Status       TransferStatus    `json:"status"`
	SourceChain  ChainID           `json:"sourceChain"`
	TargetChain  ChainID           `json:"targetChain"`
	Asset        Asset             `json:"asset"`
	Amount       string            `json:"amount"`
	Sender       string            `json:"sender"`
	Recipient    string            `json:"recipient"`
	SourceTxHash string            `json:"sourceTxHash,omitempty"`
	TargetTxHash string            `json:"targetTxHash,omitempty"`
	Fee          string            `json:"fee"`
	FeeAsset     Asset             `json:"feeAsset"`
	CreatedAt    int64             `json:"createdAt"`
	UpdatedAt    int64             `json:"updatedAt"`
	CompletedAt  int64             `json:"completedAt,omitempty"`
	ErrorMessage string            `json:"errorMessage,omitempty"`
}

// FeeEstimate represents a fee estimate for a bridge transfer.
type FeeEstimate struct {
	BridgeFee     string `json:"bridgeFee"`
	GasFeeSource  string `json:"gasFeeSource"`
	GasFeeTarget  string `json:"gasFeeTarget"`
	TotalFee      string `json:"totalFee"`
	FeeAsset      Asset  `json:"feeAsset"`
	EstimatedTime int    `json:"estimatedTime"` // seconds
	ExchangeRate  string `json:"exchangeRate,omitempty"`
}

// ExchangeRate represents an exchange rate between assets.
type ExchangeRate struct {
	FromAsset   Asset  `json:"fromAsset"`
	ToAsset     Asset  `json:"toAsset"`
	Rate        string `json:"rate"`
	InverseRate string `json:"inverseRate"`
	LastUpdated int64  `json:"lastUpdated"`
	Source      string `json:"source"`
}

// SignedTransaction represents a signed transaction result.
type SignedTransaction struct {
	TxHash               string  `json:"txHash"`
	Chain                ChainID `json:"chain"`
	From                 string  `json:"from"`
	To                   string  `json:"to"`
	Value                string  `json:"value"`
	Data                 string  `json:"data"`
	GasLimit             string  `json:"gasLimit"`
	GasPrice             string  `json:"gasPrice,omitempty"`
	MaxFeePerGas         string  `json:"maxFeePerGas,omitempty"`
	MaxPriorityFeePerGas string  `json:"maxPriorityFeePerGas,omitempty"`
	Nonce                int     `json:"nonce"`
	Signature            string  `json:"signature"`
}

// TransferFilter represents filters for listing transfers.
type TransferFilter struct {
	Status      TransferStatus
	SourceChain ChainID
	TargetChain ChainID
	Asset       string
	Sender      string
	Recipient   string
	FromDate    *time.Time
	ToDate      *time.Time
	Limit       int
	Offset      int
}

// LockOptions represents options for the lock operation.
type LockOptions struct {
	Recipient string
	Deadline  int64
	Slippage  float64
}

// MintOptions represents options for the mint operation.
type MintOptions struct {
	GasLimit             string
	MaxFeePerGas         string
	MaxPriorityFeePerGas string
}

// BurnOptions represents options for the burn operation.
type BurnOptions struct {
	Recipient string
	Deadline  int64
}

// UnlockOptions represents options for the unlock operation.
type UnlockOptions struct {
	GasLimit string
	GasPrice string
}

// Config represents the bridge client configuration.
type Config struct {
	APIKey   string
	Endpoint string
	Timeout  time.Duration
	Retries  int
	Debug    bool
}

// DefaultEndpoint is the default bridge API endpoint.
const DefaultEndpoint = "https://bridge.synor.io/v1"

// DefaultConfig returns a configuration with default values.
func DefaultConfig(apiKey string) Config {
	return Config{
		APIKey:   apiKey,
		Endpoint: DefaultEndpoint,
		Timeout:  60 * time.Second,
		Retries:  3,
		Debug:    false,
	}
}
