package wallet

import (
	"context"
	"fmt"

	"github.com/tech/sendico/gateway/chain/internal/service/gateway/driver"
	"github.com/tech/sendico/gateway/chain/storage/model"
	"github.com/tech/sendico/pkg/merrors"
	moneyv1 "github.com/tech/sendico/pkg/proto/common/money/v1"
	"go.uber.org/zap"
)

func OnChainWalletBalances(ctx context.Context, deps Deps, wallet *model.ManagedWallet) (*moneyv1.Money, *moneyv1.Money, error) {
	logger := deps.Logger
	if wallet == nil {
		return nil, nil, merrors.InvalidArgument("wallet is required")
	}
	if deps.Networks == nil {
		return nil, nil, merrors.Internal("rpc clients not initialised")
	}
	if deps.Drivers == nil {
		return nil, nil, merrors.Internal("chain drivers not configured")
	}

	network, ok := deps.Networks.Network(wallet.Network)
	if !ok {
		logger.Warn("Requested network is not configured",
			zap.String("wallet_ref", wallet.WalletRef),
			zap.String("network", string(wallet.Network)),
		)
		return nil, nil, merrors.Internal(fmt.Sprintf("Requested network '%s' is not configured", wallet.Network))
	}

	chainDriver, err := deps.Drivers.Driver(wallet.Network)
	if err != nil {
		logger.Warn("Chain driver not configured",
			zap.String("wallet_ref", wallet.WalletRef),
			zap.String("network", string(wallet.Network)),
			zap.Error(err),
		)
		return nil, nil, merrors.InvalidArgument("unsupported chain")
	}

	driverDeps := driver.Deps{
		Logger:     deps.Logger,
		Registry:   deps.Networks,
		KeyManager: deps.KeyManager,
		RPCTimeout: deps.RPCTimeout,
	}
	tokenBalance, err := chainDriver.Balance(ctx, driverDeps, network, wallet)
	if err != nil {
		return nil, nil, err
	}
	nativeBalance, err := chainDriver.NativeBalance(ctx, driverDeps, network, wallet)
	if err != nil {
		return nil, nil, err
	}
	return tokenBalance, nativeBalance, nil
}
