package swap

import (
	"context"
	"fmt"
)

// Aggregator aggregates quotes from multiple DEX aggregators
type Aggregator struct {
	providers []QuoteProvider
}

// NewAggregator creates a new swap aggregator
func NewAggregator() *Aggregator {
	return &Aggregator{
		providers: []QuoteProvider{
			NewOneInchProvider(),
			NewZeroXProvider(),
			NewParaswapProvider(),
		},
	}
}

// QuoteProvider interface for DEX aggregators
type QuoteProvider interface {
	GetQuote(ctx context.Context, req *QuoteRequest) (*Quote, error)
	Name() string
}

// QuoteRequest represents a swap quote request
type QuoteRequest struct {
	FromToken  string
	ToToken    string
	Amount     string
	FromChain  int
	ToChain    int
	Slippage   float64
}

// Quote represents a swap quote
type Quote struct {
	Provider      string
	FromToken     string
	ToToken       string
	FromAmount    string
	ToAmount      string
	EstimatedGas  string
	PriceImpact   float64
	Route         []RouteStep
}

// RouteStep represents a step in the swap route
type RouteStep struct {
	Protocol string
	From     string
	To       string
}

// GetBestQuote gets the best quote from all providers
func (a *Aggregator) GetBestQuote(ctx context.Context, req *QuoteRequest) (*Quote, error) {
	var bestQuote *Quote
	var bestAmount string

	for _, provider := range a.providers {
		quote, err := provider.GetQuote(ctx, req)
		if err != nil {
			continue
		}

		if bestQuote == nil || quote.ToAmount > bestAmount {
			bestQuote = quote
			bestAmount = quote.ToAmount
		}
	}

	if bestQuote == nil {
		return nil, fmt.Errorf("no quotes available")
	}

	return bestQuote, nil
}

// OneInchProvider implements QuoteProvider for 1inch
type OneInchProvider struct{}

func NewOneInchProvider() *OneInchProvider {
	return &OneInchProvider{}
}

func (p *OneInchProvider) Name() string {
	return "1inch"
}

func (p *OneInchProvider) GetQuote(ctx context.Context, req *QuoteRequest) (*Quote, error) {
	// Implementation would call 1inch API
	return nil, fmt.Errorf("not implemented - requires 1inch API integration")
}

// ZeroXProvider implements QuoteProvider for 0x
type ZeroXProvider struct{}

func NewZeroXProvider() *ZeroXProvider {
	return &ZeroXProvider{}
}

func (p *ZeroXProvider) Name() string {
	return "0x"
}

func (p *ZeroXProvider) GetQuote(ctx context.Context, req *QuoteRequest) (*Quote, error) {
	// Implementation would call 0x API
	return nil, fmt.Errorf("not implemented - requires 0x API integration")
}

// ParaswapProvider implements QuoteProvider for Paraswap
type ParaswapProvider struct{}

func NewParaswapProvider() *ParaswapProvider {
	return &ParaswapProvider{}
}

func (p *ParaswapProvider) Name() string {
	return "Paraswap"
}

func (p *ParaswapProvider) GetQuote(ctx context.Context, req *QuoteRequest) (*Quote, error) {
	// Implementation would call Paraswap API
	return nil, fmt.Errorf("not implemented - requires Paraswap API integration")
}

