package swapapi

import (
	"github.com/deltaswapio/swaprouter/v3/mongodb"
	"github.com/deltaswapio/swaprouter/v3/router"
	"github.com/deltaswapio/swaprouter/v3/tokens"
)

// ConvertMgoSwapToSwapInfo convert
func ConvertMgoSwapToSwapInfo(ms *mongodb.MgoSwap) *SwapInfo {
	return &SwapInfo{
		SwapType:    ms.SwapType,
		TxID:        ms.TxID,
		TxTo:        ms.TxTo,
		TxHeight:    ms.TxHeight,
		From:        ms.From,
		Bind:        ms.Bind,
		Value:       ms.Value,
		LogIndex:    ms.LogIndex,
		FromChainID: ms.FromChainID,
		ToChainID:   ms.ToChainID,
		SwapInfo:    ms.SwapInfo,
		Status:      ms.Status,
		StatusMsg:   ms.Status.String(),
		InitTime:    ms.InitTime,
		Timestamp:   ms.Timestamp,
		Memo:        ms.Memo,
	}
}

// ConvertMgoSwapsToSwapInfos convert
func ConvertMgoSwapsToSwapInfos(msSlice []*mongodb.MgoSwap) []*SwapInfo {
	result := make([]*SwapInfo, len(msSlice))
	for k, v := range msSlice {
		result[k] = ConvertMgoSwapToSwapInfo(v)
	}
	return result
}

// ConvertMgoSwapResultToSwapInfo convert
func ConvertMgoSwapResultToSwapInfo(mr *mongodb.MgoSwapResult) *SwapInfo {
	var confirmations uint64
	if mr.SwapHeight != 0 {
		latest := router.GetCachedLatestBlockNumber(mr.ToChainID)
		if latest > mr.SwapHeight {
			confirmations = latest - mr.SwapHeight
		}
	}
	return &SwapInfo{
		SwapType:      mr.SwapType,
		TxID:          mr.TxID,
		TxTo:          mr.TxTo,
		TxHeight:      mr.TxHeight,
		From:          mr.From,
		To:            mr.To,
		Bind:          mr.Bind,
		Value:         mr.Value,
		LogIndex:      mr.LogIndex,
		FromChainID:   mr.FromChainID,
		ToChainID:     mr.ToChainID,
		SwapInfo:      mr.SwapInfo,
		SwapTx:        mr.SwapTx,
		SwapHeight:    mr.SwapHeight,
		SwapValue:     mr.SwapValue,
		SwapNonce:     mr.SwapNonce,
		Status:        mr.Status,
		StatusMsg:     mr.Status.String(),
		InitTime:      mr.InitTime,
		Timestamp:     mr.Timestamp,
		Memo:          mr.Memo,
		ReplaceCount:  len(mr.OldSwapTxs),
		Confirmations: confirmations,
	}
}

// ConvertMgoSwapResultsToSwapInfos convert
func ConvertMgoSwapResultsToSwapInfos(mrSlice []*mongodb.MgoSwapResult) []*SwapInfo {
	result := make([]*SwapInfo, len(mrSlice))
	for k, v := range mrSlice {
		result[k] = ConvertMgoSwapResultToSwapInfo(v)
	}
	return result
}

// ConvertChainConfig convert chain config
func ConvertChainConfig(c *tokens.ChainConfig) *ChainConfig {
	if c == nil {
		return nil
	}
	return &ChainConfig{
		ChainID:        c.ChainID,
		BlockChain:     c.BlockChain,
		RouterContract: c.RouterContract,
		RouterVersion:  c.RouterVersion,
		Confirmations:  c.Confirmations,
		InitialHeight:  c.InitialHeight,
	}
}

// ConvertTokenConfig convert token config
func ConvertTokenConfig(c *tokens.TokenConfig) *TokenConfig {
	if c == nil {
		return nil
	}
	return &TokenConfig{
		TokenID:         c.TokenID,
		Decimals:        c.Decimals,
		ContractAddress: c.ContractAddress,
		ContractVersion: c.ContractVersion,
		RouterContract:  c.RouterContract,
		RouterVersion:   c.RouterVersion,
		Underlying:      c.GetUnderlying(),
	}
}

// ConvertSwapConfig convert swap config
func ConvertSwapConfig(c *tokens.SwapConfig) *SwapConfig {
	if c == nil {
		return nil
	}
	return &SwapConfig{
		MaximumSwap:       c.MaximumSwap.String(),
		MinimumSwap:       c.MinimumSwap.String(),
		BigValueThreshold: c.BigValueThreshold.String(),
	}
}

// ConvertFeeConfig convert fee config
func ConvertFeeConfig(c *tokens.FeeConfig) *FeeConfig {
	if c == nil {
		return nil
	}
	return &FeeConfig{
		SwapFeeRatePerMillion: c.SwapFeeRatePerMillion,
		MaximumSwapFee:        c.MaximumSwapFee.String(),
		MinimumSwapFee:        c.MinimumSwapFee.String(),
	}
}
