use crate::sign_schema::SignatureSchema;
use crate::WalletRegisterId;
use ex3_timestamp::TimeInNs;
use serde::{Deserialize, Serialize};
use serde_bytes::ByteBuf;
use std::fmt::Display;

/// AssetAccountBinding
#[derive(Debug, Clone, PartialEq, Eq, Hash, Deserialize, Serialize, PartialOrd, Ord)]
pub struct AssetAccountBinding {
    /// Signature schema
    /// Note: this is the signature schema of the second wallet
    pub sign_schema: SignatureSchema,

    /// The main wallet id
    pub main: WalletRegisterId,

    /// The asset wallet id
    pub asset: WalletRegisterId,

    /// The initiator wallet id
    ///
    /// Note: this is the wallet id that is used to create the asset account binding tx,
    ///       So it is  main wallet id or asset wallet id
    pub initiator: WalletRegisterId,

    /// The wallet signature schema of the initiator
    pub sign_schema_initiator: SignatureSchema,

    /// The initial wallet signature
    pub sig_initiator: ByteBuf,

    /// Tx timestamp
    pub timestamp: TimeInNs,
}

impl Display for AssetAccountBinding {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(
            f,
            "{}:{}:{}:{}:{}:{}:{}",
            self.sign_schema,
            self.main,
            self.asset,
            self.initiator,
            self.sign_schema_initiator,
            hex::encode(self.sig_initiator.as_ref()),
            self.timestamp,
        )
    }
}

/// Asset Account Unbinding
#[derive(Debug, Clone, PartialEq, Eq, Hash, Deserialize, Serialize, PartialOrd, Ord)]
pub struct AssetAccountUnbinding {
    /// Signature schema
    pub sign_schema: SignatureSchema,

    /// The main wallet id
    pub main: WalletRegisterId,

    /// The asset wallet id
    pub asset: WalletRegisterId,
}

impl Display for AssetAccountUnbinding {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "{}:{}:{}", self.sign_schema, self.main, self.asset,)
    }
}
