//! `Transaction` Javascript interface
#![cfg(target_arch = "wasm32")]
#![allow(non_snake_case)]
use rialo_s_instruction::wasm::Instructions;
use rialo_s_keypair::Keypair;
use rialo_s_message::{ConfigHashPrefix, Message};
use rialo_s_pubkey::Pubkey;
use wasm_bindgen::prelude::*;

use crate::Transaction;

#[wasm_bindgen]
impl Transaction {
    /// Create a new `Transaction`
    #[wasm_bindgen(constructor)]
    pub fn constructor(
        instructions: Instructions,
        payer: Option<Pubkey>,
        config_hash_prefix: u64,
    ) -> Transaction {
        let instructions: Vec<_> = instructions.into();
        Transaction::new_with_payer(
            &instructions,
            payer.as_ref(),
            ConfigHashPrefix::new(config_hash_prefix),
        )
    }

    /// Return a message containing all data that should be signed.
    #[wasm_bindgen(js_name = message)]
    pub fn js_message(&self) -> Message {
        self.message.clone()
    }

    /// Return the serialized message data to sign.
    pub fn messageData(&self) -> Box<[u8]> {
        self.message_data().into()
    }

    #[cfg(feature = "verify")]
    /// Verify the transaction
    #[wasm_bindgen(js_name = verify)]
    pub fn js_verify(&self) -> Result<(), JsValue> {
        self.verify()
            .map_err(|x| std::string::ToString::to_string(&x).into())
    }

    pub fn partialSign(&mut self, keypair: &Keypair, valid_from: i64) {
        self.partial_sign(&[keypair], valid_from);
    }

    pub fn isSigned(&self) -> bool {
        self.is_signed()
    }

    #[cfg(feature = "bincode")]
    pub fn toBytes(&self) -> Box<[u8]> {
        bincode::serialize(self).unwrap().into()
    }

    #[cfg(feature = "bincode")]
    pub fn fromBytes(bytes: &[u8]) -> Result<Transaction, JsValue> {
        bincode::deserialize(bytes).map_err(|x| std::string::ToString::to_string(&x).into())
    }
}
