"""
aeknow Wallet Module
=======================
HD Wallet and Mnemonic Wallet utilities.

Core Features:
- Generate new mnemonic wallet
- Import from mnemonic
- Save/load mnemonic keystore
- Derive child accounts

Usage:
    from aeknow.wallet import MnemonicWallet
    
    # Generate new wallet
    wallet = MnemonicWallet.generate()
    print(wallet.mnemonic)
    print(wallet.address)
    
    # Import from mnemonic
    wallet = MnemonicWallet.from_mnemonic("word1 word2 ...")
    
    # Save to keystore
    wallet.save_keystore("wallet.json", "password")
    
    # Load from keystore
    wallet = MnemonicWallet.from_keystore("wallet.json", "password")
"""

from aeknow.hdwallet import HDWallet
from aeknow.signing import Account


class MnemonicWallet:
    """
    Mnemonic-based HD Wallet
    
    Wraps HDWallet with convenient methods for common operations.
    """
    
    def __init__(self, hdwallet: HDWallet):
        """
        Initialize from HDWallet instance.
        Use class methods generate(), from_mnemonic(), or from_keystore() instead.
        """
        self._hdwallet = hdwallet
        self._master_account = hdwallet.get_master_account()
    
    @classmethod
    def generate(cls) -> 'MnemonicWallet':
        """
        Generate a new random mnemonic wallet.
        
        :return: New MnemonicWallet instance
        """
        return cls(HDWallet())
    
    @classmethod
    def from_mnemonic(cls, mnemonic: str) -> 'MnemonicWallet':
        """
        Import wallet from existing mnemonic phrase.
        
        :param mnemonic: BIP39 mnemonic phrase (12 or 24 words)
        :return: MnemonicWallet instance
        :raises ValueError: If mnemonic is invalid
        """
        return cls(HDWallet(mnemonic.strip()))
    
    @classmethod
    def from_keystore(cls, path: str, password: str) -> 'MnemonicWallet':
        """
        Load wallet from mnemonic keystore file.
        
        :param path: Path to keystore file
        :param password: Keystore password
        :return: MnemonicWallet instance
        """
        hdwallet = HDWallet.from_keystore(path, password)
        return cls(hdwallet)
    
    @property
    def mnemonic(self) -> str:
        """Get the mnemonic phrase."""
        return self._hdwallet.mnemonic
    
    @property
    def address(self) -> str:
        """Get the master account address."""
        return self._master_account.get_address()
    
    @property
    def account(self) -> Account:
        """Get the master account."""
        return self._master_account
    
    def derive_account(self, index: int, account_index: int = 0) -> Account:
        """
        Derive a child account at specified index.
        
        :param index: Address index (0, 1, 2, ...)
        :param account_index: Account index (usually 0)
        :return: Derived Account
        """
        _, account = self._hdwallet.derive_child(index, account_index)
        return account
    
    def derive_accounts(self, count: int, account_index: int = 0) -> list:
        """
        Derive multiple child accounts.
        
        :param count: Number of accounts to derive
        :param account_index: Account index (usually 0)
        :return: List of (path, Account) tuples
        """
        accounts = []
        for i in range(count):
            path, account = self._hdwallet.derive_child(i, account_index)
            accounts.append((path, account))
        return accounts
    
    def save_keystore(self, path: str, password: str) -> str:
        """
        Save mnemonic to keystore file.
        
        :param path: Output file path
        :param password: Keystore password
        :return: Saved file path
        """
        return self._hdwallet.save_mnemonic_to_keystore_file(path, password)
    
    def save_account_keystore(self, path: str, password: str, index: int = None) -> str:
        """
        Save a single account to keystore file.
        
        :param path: Output file path
        :param password: Keystore password
        :param index: Account index (None for master account)
        :return: Saved file path
        """
        if index is None:
            account = self._master_account
        else:
            account = self.derive_account(index)
        return account.save_to_keystore_file(path, password)


# Convenience functions

def generate_wallet() -> MnemonicWallet:
    """Generate a new mnemonic wallet."""
    return MnemonicWallet.generate()


def import_wallet(mnemonic: str) -> MnemonicWallet:
    """Import wallet from mnemonic phrase."""
    return MnemonicWallet.from_mnemonic(mnemonic)


def load_wallet(path: str, password: str) -> MnemonicWallet:
    """Load wallet from keystore file."""
    return MnemonicWallet.from_keystore(path, password)
