package nns

import (
	"errors"

	client "git.frostfs.info/TrueCloudLab/frostfs-contract/rpcclient/nns"
	"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/commonflags"
	"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/config"
	"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/morph/constants"
	"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/morph/helper"
	commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
	"github.com/nspcc-dev/neo-go/pkg/rpcclient/invoker"
	"github.com/nspcc-dev/neo-go/pkg/rpcclient/management"
	"github.com/spf13/cobra"
	"github.com/spf13/viper"
)

func nnsWriter(cmd *cobra.Command) (*client.Contract, *helper.LocalActor) {
	v := viper.GetViper()
	c, err := helper.NewRemoteClient(v)
	commonCmd.ExitOnErr(cmd, "unable to create NEO rpc client: %w", err)

	alphabetWalletPath := config.ResolveHomePath(v.GetString(commonflags.AlphabetWalletsFlag))
	walletPath := config.ResolveHomePath(v.GetString(commonflags.WalletPath))
	adminWalletPath := config.ResolveHomePath(v.GetString(commonflags.AdminWalletPath))

	var (
		alphabet       *helper.AlphabetWallets
		regularWallets []*helper.RegularWallets
	)

	if alphabetWalletPath != "" {
		alphabet = &helper.AlphabetWallets{Path: alphabetWalletPath, Label: constants.ConsensusAccountName}
	}

	if walletPath != "" {
		regularWallets = append(regularWallets, &helper.RegularWallets{Path: walletPath})
	}

	if adminWalletPath != "" {
		regularWallets = append(regularWallets, &helper.RegularWallets{Path: adminWalletPath})
	}

	if alphabet == nil && regularWallets == nil {
		commonCmd.ExitOnErr(cmd, "", errors.New("no wallets provided"))
	}

	ac, err := helper.NewLocalActor(c, alphabet, regularWallets...)
	commonCmd.ExitOnErr(cmd, "can't create actor: %w", err)

	r := management.NewReader(ac.Invoker)
	nnsCs, err := helper.GetContractByID(r, 1)
	commonCmd.ExitOnErr(cmd, "can't get NNS contract state: %w", err)
	return client.New(ac, nnsCs.Hash), ac
}

func nnsReader(cmd *cobra.Command) (*client.ContractReader, *invoker.Invoker) {
	c, err := helper.NewRemoteClient(viper.GetViper())
	commonCmd.ExitOnErr(cmd, "unable to create NEO rpc client: %w", err)

	inv := invoker.New(c, nil)
	r := management.NewReader(inv)
	nnsCs, err := helper.GetContractByID(r, 1)
	commonCmd.ExitOnErr(cmd, "can't get NNS contract state: %w", err)

	return client.NewReader(inv, nnsCs.Hash), inv
}