use crate::balance_changed::BalanceChanged;
use crate::transaction::EncodedTransaction;
use crate::{AssetId, MerkleNode, WalletRegisterId};
use ex3_serde::bincode;
use serde::{Deserialize, Serialize};
use serde_bytes::ByteBuf;

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

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

    /// Transactions in the block that are rejected
    /// Note:
    ///   The index of the rejected transaction in the `txs` field
    pub rejected_tx_indexes: Vec<u32>,
}

#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
pub struct BlockBodyExt {
    /// Balances changed in the block
    pub balances_changed: Vec<(WalletRegisterId, Vec<(AssetId, BalanceChanged)>)>,
}

#[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")
    }
}
