package io.novafoundation.nova.feature_account_impl.domain.account.model

import io.novafoundation.nova.core.model.CryptoType
import io.novafoundation.nova.feature_account_api.domain.model.LightMetaAccount
import io.novafoundation.nova.feature_account_api.domain.model.MetaAccount
import io.novafoundation.nova.feature_account_api.domain.model.SecretsMetaAccount
import io.novafoundation.nova.feature_account_api.domain.model.hasChainAccountIn
import io.novafoundation.nova.feature_account_api.domain.model.substrateFrom
import io.novafoundation.nova.runtime.multiNetwork.chain.model.Chain
import io.novafoundation.nova.runtime.multiNetwork.chain.model.ChainId
import io.novasama.substrate_sdk_android.encrypt.MultiChainEncryption

class RealSecretsMetaAccount(
    id: Long,
    globallyUniqueId: String,
    substratePublicKey: ByteArray?,
    substrateCryptoType: CryptoType?,
    substrateAccountId: ByteArray?,
    ethereumAddress: ByteArray?,
    ethereumPublicKey: ByteArray?,
    isSelected: Boolean,
    name: String,
    status: LightMetaAccount.Status,
    chainAccounts: Map<ChainId, MetaAccount.ChainAccount>,
    parentMetaId: Long?,
    tronAddress: ByteArray? = null,
    tronPublicKey: ByteArray? = null,
    bitcoinAddress: ByteArray? = null,
    bitcoinPublicKey: ByteArray? = null,
    solanaAddress: ByteArray? = null,
    solanaPublicKey: ByteArray? = null,
) : DefaultMetaAccount(
    id = id,
    globallyUniqueId = globallyUniqueId,
    substratePublicKey = substratePublicKey,
    substrateCryptoType = substrateCryptoType,
    substrateAccountId = substrateAccountId,
    ethereumAddress = ethereumAddress,
    ethereumPublicKey = ethereumPublicKey,
    isSelected = isSelected,
    name = name,
    type = LightMetaAccount.Type.SECRETS,
    status = status,
    chainAccounts = chainAccounts,
    parentMetaId = parentMetaId,
    tronAddress = tronAddress,
    tronPublicKey = tronPublicKey,
    bitcoinAddress = bitcoinAddress,
    bitcoinPublicKey = bitcoinPublicKey,
    solanaAddress = solanaAddress,
    solanaPublicKey = solanaPublicKey
),
    SecretsMetaAccount {

    override fun multiChainEncryptionIn(chain: Chain): MultiChainEncryption? {
        return when {
            hasChainAccountIn(chain.id) -> {
                val cryptoType = chainAccounts.getValue(chain.id).cryptoType ?: return null

                // Tron and Bitcoin both reuse the same secp256k1 keypair/signing as Ethereum - see
                // RealTronTransactionService/RealBitcoinTransactionService's use of
                // Signer.sign(MultiChainEncryption.Ethereum, ...). Solana is Ed25519, not
                // secp256k1, so it can't join that group - it reuses MultiChainEncryption.Substrate
                // (EncryptionType.ED25519) instead, the exact same code path Substrate's own
                // ed25519 accounts already use (Signer.signEd25519 doesn't care which chain family
                // the keypair belongs to, only that it's a raw Ed25519 keypair - confirmed by
                // reading substrate-sdk-android's Signer.kt directly).
                if (chain.isEthereumBased || chain.isTronBased || chain.isBitcoinBased) {
                    MultiChainEncryption.Ethereum
                } else if (chain.isSolanaBased) {
                    MultiChainEncryption.substrateFrom(CryptoType.ED25519)
                } else {
                    MultiChainEncryption.substrateFrom(cryptoType)
                }
            }

            chain.isEthereumBased -> MultiChainEncryption.Ethereum

            chain.isTronBased -> MultiChainEncryption.Ethereum

            chain.isBitcoinBased -> MultiChainEncryption.Ethereum

            chain.isSolanaBased -> MultiChainEncryption.substrateFrom(CryptoType.ED25519)

            else -> substrateCryptoType?.let(MultiChainEncryption.Companion::substrateFrom)
        }
    }
}
