package com.durian.tssparty.domain.model

import com.google.gson.annotations.SerializedName

/**
 * Participant in a TSS session
 */
data class Participant(
    @SerializedName("partyId")
    val partyId: String,
    @SerializedName("partyIndex")
    val partyIndex: Int,
    @SerializedName("name")
    val name: String = ""
)

/**
 * TSS Session information
 */
data class TssSession(
    val sessionId: String,
    val sessionType: SessionType,
    val thresholdT: Int,
    val thresholdN: Int,
    val participants: List<Participant>,
    val status: SessionStatus,
    val inviteCode: String? = null,
    val messageHash: String? = null,
    val createdAt: Long = System.currentTimeMillis()
)

enum class SessionType {
    KEYGEN,
    SIGN
}

enum class SessionStatus {
    WAITING,
    IN_PROGRESS,
    COMPLETED,
    FAILED
}

/**
 * Result of key generation
 */
data class KeygenResult(
    @SerializedName("publicKey")
    val publicKey: String,  // base64 encoded
    @SerializedName("encryptedShare")
    val encryptedShare: String  // base64 encoded
)

/**
 * Result of signing
 */
data class SignResult(
    @SerializedName("signature")
    val signature: String,  // base64 encoded (r || s || v, 65 bytes)
    @SerializedName("recoveryId")
    val recoveryId: Int
)

/**
 * Outgoing TSS message
 */
data class TssOutgoingMessage(
    @SerializedName("type")
    val type: String,
    @SerializedName("isBroadcast")
    val isBroadcast: Boolean,
    @SerializedName("toParties")
    val toParties: List<String>?,
    @SerializedName("payload")
    val payload: String  // base64 encoded
)

/**
 * Share record stored in local database
 */
data class ShareRecord(
    val id: Long = 0,
    val sessionId: String,
    val publicKey: String,
    val encryptedShare: String,
    val thresholdT: Int,
    val thresholdN: Int,
    val partyIndex: Int,
    val address: String,
    val createdAt: Long = System.currentTimeMillis()
)

/**
 * Account balance information
 */
data class AccountBalance(
    val address: String,
    val balance: String,
    val denom: String = "ukava"
)

/**
 * Sign session request
 */
data class SignSessionRequest(
    val sessionId: String,
    val messageHash: String,  // hex encoded
    val participants: List<Participant>
)

/**
 * Settings
 * Matches service-party-app settings structure
 */
data class AppSettings(
    val messageRouterUrl: String = "mpc-grpc.szaiai.com:443",
    val accountServiceUrl: String = "https://rwaapi.szaiai.com",
    val kavaRpcUrl: String = "https://evm.kava.io",
    val networkType: NetworkType = NetworkType.MAINNET
)

enum class NetworkType {
    MAINNET,
    TESTNET
}

/**
 * Token type for transfers
 */
enum class TokenType {
    KAVA,           // Native KAVA token
    GREEN_POINTS    // 绿积分 (dUSDT) ERC-20 token
}

/**
 * Green Points (绿积分) Token Contract Configuration
 * dUSDT - Fixed supply ERC-20 token on Kava EVM
 */
object GreenPointsToken {
    const val CONTRACT_ADDRESS = "0xA9F3A35dBa8699c8C681D8db03F0c1A8CEB9D7c3"
    const val NAME = "绿积分"
    const val SYMBOL = "dUSDT"
    const val DECIMALS = 6

    // ERC-20 function signatures (first 4 bytes of keccak256 hash)
    const val BALANCE_OF_SELECTOR = "0x70a08231"  // balanceOf(address)
    const val TRANSFER_SELECTOR = "0xa9059cbb"    // transfer(address,uint256)
    const val APPROVE_SELECTOR = "0x095ea7b3"     // approve(address,uint256)
    const val ALLOWANCE_SELECTOR = "0xdd62ed3e"   // allowance(address,address)
    const val TOTAL_SUPPLY_SELECTOR = "0x18160ddd" // totalSupply()
}

/**
 * Wallet balance containing both native and token balances
 */
data class WalletBalance(
    val address: String,
    val kavaBalance: String = "0",       // Native KAVA balance
    val greenPointsBalance: String = "0" // 绿积分 (dUSDT) balance
)

/**
 * Share backup data for export/import
 * Contains all necessary information to restore a wallet share
 */
data class ShareBackup(
    @SerializedName("version")
    val version: Int = 1,  // Backup format version for future compatibility

    @SerializedName("sessionId")
    val sessionId: String,

    @SerializedName("publicKey")
    val publicKey: String,  // base64 encoded

    @SerializedName("encryptedShare")
    val encryptedShare: String,  // base64 encoded, encrypted with user password

    @SerializedName("thresholdT")
    val thresholdT: Int,

    @SerializedName("thresholdN")
    val thresholdN: Int,

    @SerializedName("partyIndex")
    val partyIndex: Int,

    @SerializedName("address")
    val address: String,

    @SerializedName("createdAt")
    val createdAt: Long,

    @SerializedName("exportedAt")
    val exportedAt: Long = System.currentTimeMillis()
) {
    companion object {
        const val FILE_EXTENSION = "tss-backup"
        const val MIME_TYPE = "application/octet-stream"

        /**
         * Create backup from ShareRecord
         */
        fun fromShareRecord(share: ShareRecord): ShareBackup {
            return ShareBackup(
                sessionId = share.sessionId,
                publicKey = share.publicKey,
                encryptedShare = share.encryptedShare,
                thresholdT = share.thresholdT,
                thresholdN = share.thresholdN,
                partyIndex = share.partyIndex,
                address = share.address,
                createdAt = share.createdAt
            )
        }
    }

    /**
     * Convert backup to ShareRecord for database storage
     */
    fun toShareRecord(): ShareRecord {
        return ShareRecord(
            id = 0,  // Will be auto-generated
            sessionId = sessionId,
            publicKey = publicKey,
            encryptedShare = encryptedShare,
            thresholdT = thresholdT,
            thresholdN = thresholdN,
            partyIndex = partyIndex,
            address = address,
            createdAt = createdAt
        )
    }
}
