package quote_computation_service

import (
	"context"
	"strings"

	"github.com/tech/sendico/payments/storage/model"
	"github.com/tech/sendico/pkg/merrors"
	paymenttypes "github.com/tech/sendico/pkg/payments/types"
	"go.uber.org/zap"
)

type managedWalletAssetResolver interface {
	ResolveManagedWalletAsset(ctx context.Context, managedWalletRef string) (*paymenttypes.Asset, error)
}

func (s *QuoteComputationService) enrichManagedWalletEndpointNetwork(
	ctx context.Context,
	endpoint *model.PaymentEndpoint,
	cache map[string]string,
) error {
	if s == nil || endpoint == nil {
		return nil
	}
	if endpoint.Type != model.EndpointTypeManagedWallet || endpoint.ManagedWallet == nil {
		return nil
	}
	walletRef := strings.TrimSpace(endpoint.ManagedWallet.ManagedWalletRef)
	if walletRef == "" {
		return merrors.InvalidArgument("managed_wallet_ref is required")
	}
	asset := endpoint.ManagedWallet.Asset
	if asset == nil {
		asset = &paymenttypes.Asset{}
		endpoint.ManagedWallet.Asset = asset
	}
	if resolver, ok := s.managedWalletNetworkResolver.(managedWalletAssetResolver); ok && resolver != nil {
		if strings.TrimSpace(asset.GetChain()) == "" || strings.TrimSpace(asset.GetTokenSymbol()) == "" {
			if resolved, err := resolver.ResolveManagedWalletAsset(ctx, walletRef); err == nil && resolved != nil {
				if strings.TrimSpace(asset.GetChain()) == "" {
					asset.Chain = strings.ToUpper(strings.TrimSpace(resolved.GetChain()))
				}
				if strings.TrimSpace(asset.GetTokenSymbol()) == "" {
					asset.TokenSymbol = strings.ToUpper(strings.TrimSpace(resolved.GetTokenSymbol()))
				}
				if strings.TrimSpace(asset.GetContractAddress()) == "" {
					asset.ContractAddress = strings.TrimSpace(resolved.GetContractAddress())
				}
			}
		}
	}
	if strings.TrimSpace(asset.GetChain()) != "" {
		asset.Chain = strings.ToUpper(strings.TrimSpace(asset.GetChain()))
		asset.TokenSymbol = strings.ToUpper(strings.TrimSpace(asset.GetTokenSymbol()))
		asset.ContractAddress = strings.TrimSpace(asset.GetContractAddress())
		return nil
	}
	if s.managedWalletNetworkResolver == nil {
		return nil
	}

	network := ""
	if cache != nil {
		network = strings.ToUpper(strings.TrimSpace(cache[walletRef]))
	}
	if network == "" {
		resolved, err := s.managedWalletNetworkResolver.ResolveManagedWalletNetwork(ctx, walletRef)
		if err != nil {
			return err
		}
		network = strings.ToUpper(strings.TrimSpace(resolved))
		if network == "" {
			return merrors.NoData("managed wallet network is missing")
		}
		if cache != nil {
			cache[walletRef] = network
		}
	}

	if s.logger != nil {
		s.logger.Debug("Managed wallet network resolved for quote planning",
			zap.String("wallet_ref", walletRef),
			zap.String("network", network),
		)
	}

	asset.Chain = network
	asset.TokenSymbol = strings.ToUpper(strings.TrimSpace(asset.TokenSymbol))
	asset.ContractAddress = strings.TrimSpace(asset.ContractAddress)
	return nil
}
