use ex3_serde::bincode;
use serde::{Deserialize, Serialize};
use serde_bytes::ByteBuf;

use crate::balance_changed::BalanceChanged;
use crate::transaction::{EncodedRejectedTransaction, EncodedTransaction};
use crate::{AssetId, MerkleNode, WalletRegisterId};

#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
pub struct BlockBody {
    /// Transactions in the block that are accepted
    pub txs: Vec<EncodedTransaction>,

    /// Balances changed in the block
    pub balances_changed: Vec<(WalletRegisterId, Vec<(AssetId, BalanceChanged)>)>,

    /// Data integrity of sharding vaults
    pub data_integrity: Vec<MerkleNode>,

    /// Transactions in the block that are rejected
    pub rejected_txs: Vec<EncodedRejectedTransaction>,
}

#[derive(Deserialize, Serialize, Debug, Clone, PartialEq, Eq)]
pub struct EncodedBlockBody(pub ByteBuf);

impl From<BlockBody> for EncodedBlockBody {
    fn from(body: BlockBody) -> Self {
        let bytes = bincode::serialize(&body).expect("Failed to serialize block body");
        EncodedBlockBody(ByteBuf::from(bytes))
    }
}

impl From<EncodedBlockBody> for BlockBody {
    fn from(encoded_body: EncodedBlockBody) -> Self {
        bincode::deserialize(encoded_body.0.as_ref()).expect("Failed to deserialize block body")
    }
}
