package key

import (
	"crypto/ecdsa"
	"github.com/btcsuite/btcd/btcec"
	"github.com/ethereum/go-ethereum/common"
	"github.com/ethereum/go-ethereum/crypto"
	tronAddr "github.com/fbsobreira/gotron-sdk/pkg/address"
	"key-manager/hd"
)

type Account interface {
	GetIndex() uint64
	GetPriKey() *ecdsa.PrivateKey
	GetAddr() string
}

type TronAccount struct {
	Index   uint64
	PriKey  *ecdsa.PrivateKey
	Address tronAddr.Address
}

func (t *TronAccount) GetIndex() uint64 {
	return t.Index
}

func (t *TronAccount) GetPriKey() *ecdsa.PrivateKey {
	return t.PriKey
}

func (t *TronAccount) GetAddr() string {
	return t.Address.String()
}

type EthAccount struct {
	Index   uint64
	PriKey  *ecdsa.PrivateKey
	Address common.Address
}

func (e *EthAccount) GetIndex() uint64 {
	return e.Index
}

func (e *EthAccount) GetPriKey() *ecdsa.PrivateKey {
	return e.PriKey
}

func (e *EthAccount) GetAddr() string {
	return e.Address.String()
}

func NewEthAccount(mnemonic string, index uint64) (*EthAccount, error) {
	seed, err := hd.GenerateSeedFromMnemonic(mnemonic, "")
	if err != nil {
		return nil, err
	}

	path := hd.EthPath(index)
	extendSeed, err := hd.GetExtendSeedFromPath(path, seed)
	if err != nil {
		return nil, err
	}

	privateKey, _ := btcec.PrivKeyFromBytes(btcec.S256(), extendSeed)
	privateKeyECDSA := privateKey.ToECDSA()

	return &EthAccount{
		Index:   index,
		PriKey:  privateKeyECDSA,
		Address: crypto.PubkeyToAddress(privateKeyECDSA.PublicKey),
	}, nil
}

func NewTronAccount(mnemonic string, index uint64) (*TronAccount, error) {
	seed, err := hd.GenerateSeedFromMnemonic(mnemonic, "")
	if err != nil {
		return nil, err
	}

	path := hd.TronPath(index)
	extendSeed, err := hd.GetExtendSeedFromPath(path, seed)
	if err != nil {
		return nil, err
	}

	privateKey, _ := btcec.PrivKeyFromBytes(btcec.S256(), extendSeed)
	privateKeyECDSA := privateKey.ToECDSA()

	return &TronAccount{
		Index:   index,
		PriKey:  privateKeyECDSA,
		Address: tronAddr.PubkeyToAddress(privateKeyECDSA.PublicKey),
	}, nil

}
