#![cfg(test)]

use crate::sr25519::AuthorityPair;

use crate::mock::*;
use crate::pallet::*;
use crate::types::*;

use frame_support::traits::Hooks;
use ghost_helpers::networks::{NetworkDataBuilder, NetworkType};

use codec::Decode;
use sp_runtime::codec::Encode;
use sp_core::{H256, crypto::Pair};

use sp_runtime::{
    traits::{Dispatchable, ValidateUnsigned},
    transaction_validity::{InvalidTransaction, TransactionSource, TransactionValidityError},
};

use sp_core::offchain::{
    testing::{PendingRequest, TestOffchainExt, TestTransactionPoolExt},
    OffchainDbExt, OffchainWorkerExt, TransactionPoolExt,
};

use parking_lot::RwLock;
use sp_core::offchain::testing::PoolState;
use std::sync::Arc;

fn create_block_numbers(values: &[u64]) -> Vec<crate::ExternalBlockNumber> {
    values.iter().map(|&v| v.into()).collect()
}

fn apply_and_clear_pool_transaction(pool_state: &Arc<RwLock<PoolState>>, tx_index: usize) {
    let raw_extrinsic = {
        let state = pool_state.read();
        assert!(
            state.transactions.len() > tx_index,
            "No transaction found at index {}",
            tx_index
        );
        state.transactions[tx_index].clone()
    };

    let ext_decoded =
        Extrinsic::decode(&mut &raw_extrinsic[..]).expect("Failed to decode extrinsic from pool");

    let runtime_call = ext_decoded.call;

    let RuntimeCall::GhostWeaver(ref local_call) = runtime_call else {
        panic!("Expected a transaction for GhostWeaver pallet, but found another one");
    };

    let validity = GhostWeaver::validate_unsigned(TransactionSource::External, local_call);
    assert!(validity.is_ok());

    let dispatch_result = runtime_call.dispatch(RuntimeOrigin::none());
    assert!(dispatch_result.is_ok());
}

#[test]
fn should_successfully_compute_median_and_start_weaving_round() {
    let pair1 = AuthorityPair::from_string("//Alice", None).expect("Should be valid seed");
    let pair2 = AuthorityPair::from_string("//Bob", None).expect("Should be valid seed");
    let pair3 = AuthorityPair::from_string("//Carol", None).expect("Should be valid seed");

    let network_id = 1;
    let network_data = NetworkDataBuilder::default().build();

    let authorities = vec![pair1.clone(), pair2.clone(), pair3.clone()];
    let networks = vec![(network_id, network_data, Default::default())];

    new_test_ext(authorities, networks).execute_with(|| {
        System::set_block_number(2);

        let context = AttestationContext::default()
            .with_current_block(1)
            .with_network_id(network_id);

        let att1 = context.with_authority_index(0).build_block_attestation(100);
        let att2 = context.with_authority_index(1).build_block_attestation(102);
        let att3 = context.with_authority_index(2).build_block_attestation(101);

        let sig1 = pair1.sign(&att1.encode());
        let sig2 = pair2.sign(&att2.encode());
        let sig3 = pair3.sign(&att3.encode());

        assert!(GhostWeaver::extend_warp(RuntimeOrigin::none(), att1, sig1).is_ok());
        assert!(GhostWeaver::extend_warp(RuntimeOrigin::none(), att2, sig2).is_ok());
        assert!(GhostWeaver::extend_warp(RuntimeOrigin::none(), att3, sig3).is_ok());

        assert!(GhostWeaver::tapestry_drafts(network_id).is_none());

        System::set_block_number(3);
        GhostWeaver::on_initialize(3);

        let round = GhostWeaver::tapestry_drafts(network_id);
        assert!(round.is_some());
        assert_eq!(round.unwrap().until, 3 + WeavingDelay::get());
    });
}

#[test]
fn should_apply_cooldown_delay_on_consensus_failure() {
    let pair1 = AuthorityPair::from_string("//Alice", None).expect("Should be valid seed");
    let pair2 = AuthorityPair::from_string("//Bob", None).expect("Should be valid seed");
    let pair3 = AuthorityPair::from_string("//Carol", None).expect("Should be valid seed");

    let network_id = 1;
    let network_data = NetworkDataBuilder::default()
        .with_block_deviation(5)
        .build();

    let authorities = vec![pair1.clone(), pair2.clone(), pair3.clone()];
    let networks = vec![(network_id, network_data, Default::default())];

    new_test_ext(authorities, networks).execute_with(|| {
        System::set_block_number(10);

        let context = AttestationContext::default()
            .with_current_block(9)
            .with_network_id(network_id);

        let att1 = context.with_authority_index(0).build_block_attestation(100);
        let att2 = context.with_authority_index(1).build_block_attestation(500);
        let att3 = context.with_authority_index(2).build_block_attestation(900);

        let sig1 = pair1.sign(&att1.encode());
        let sig2 = pair2.sign(&att2.encode());
        let sig3 = pair3.sign(&att3.encode());

        assert!(GhostWeaver::extend_warp(RuntimeOrigin::none(), att1, sig1).is_ok());
        assert!(GhostWeaver::extend_warp(RuntimeOrigin::none(), att2, sig2).is_ok());
        assert!(GhostWeaver::extend_warp(RuntimeOrigin::none(), att3, sig3).is_ok());

        System::set_block_number(11);
        GhostWeaver::on_initialize(11);

        let cooldown_block = GhostWeaver::next_consensus_attempt_blocks(network_id);
        assert_eq!(cooldown_block, 14);

        TapestryDrafts::<TestRuntime>::remove(network_id);

        System::set_block_number(12);
        GhostWeaver::on_initialize(12);
        assert!(TapestryDrafts::<TestRuntime>::get(network_id).is_none());

        System::set_block_number(14);
        GhostWeaver::on_initialize(14);
        assert!(TapestryDrafts::<TestRuntime>::get(network_id).is_some());
    });
}

#[test]
fn validate_unsigned_should_prevent_mempool_dos_via_tags() {
    let pair = AuthorityPair::from_string("//Alice", None).expect("Should be valid seed");
    let wrong_pair = AuthorityPair::from_string("//Eve", None).expect("Should be valid seed");

    let network_id = 1;
    let network_data = NetworkDataBuilder::default().build();

    let authorities = vec![pair.clone()];
    let networks = vec![(network_id, network_data, Default::default())];

    new_test_ext(authorities, networks).execute_with(|| {
        System::set_block_number(2);

        let att = AttestationContext::default()
            .with_current_block(1)
            .with_network_id(network_id)
            .with_authority_index(0)
            .build_block_attestation(100);

        let valid_sig = pair.sign(&att.encode());
        let invalid_sig = wrong_pair.sign(&att.encode());

        let call = Call::extend_warp {
            block_attestation: att.clone(),
            signature: valid_sig,
        };

        let validity = GhostWeaver::validate_unsigned(TransactionSource::External, &call);
        assert!(validity.is_ok());
        let valid_info = validity.unwrap();

        let auth_index: crate::AuthIndex = 0u8.into();
        let weaver_context_bytes: Vec<u8> = (auth_index, network_id).encode();
        let mut expected_tag = "WeaverBlock".encode();
        expected_tag.extend(weaver_context_bytes.encode());
        assert!(valid_info.provides.contains(&expected_tag));

        let spam_call = Call::extend_warp {
            block_attestation: att,
            signature: invalid_sig,
        };

        let spam_validity = GhostWeaver::validate_unsigned(TransactionSource::External, &spam_call);
        assert_eq!(
            spam_validity,
            Err(TransactionValidityError::Invalid(InvalidTransaction::BadSigner).into())
        );
    });
}

#[test]
fn offchain_worker_should_fetch_block_and_submit_unsigned_tx() {
    let evm_network_id = 1u32;
    let utxo_network_id = 69u32;

    let pair = AuthorityPair::from_string("//Alice", None).expect("Should be valid seed");

    let new_evm_network_data = NetworkDataBuilder::default()
        .with_network_type(NetworkType::Evm)
        .with_default_endpoints(vec![b"https://super-bad-public-rpc-endpoint.com".to_vec()])
        .build();

    let new_utxo_network_data = NetworkDataBuilder::default()
        .with_network_type(NetworkType::Utxo)
        .with_default_endpoints(vec![b"https://publicbitcoin.io".to_vec()])
        .build();

    let authority_index = 0 as crate::AuthIndex;
    let authorities = vec![pair.clone()];
    let networks = vec![
        (evm_network_id, new_evm_network_data, 0u64),
        (utxo_network_id, new_utxo_network_data, 0u64),
    ];
    let mut ext = new_test_ext(authorities, networks);

    let (offchain, offchain_state) = TestOffchainExt::new();
    let (pool, pool_state) = TestTransactionPoolExt::new();

    ext.register_extension(OffchainWorkerExt::new(offchain.clone()));
    ext.register_extension(OffchainDbExt::new(offchain));
    ext.register_extension(TransactionPoolExt::new(pool));

    ext.execute_with(|| {
        let network_id_encoded = evm_network_id.encode();

        let mut endpoint_key = b"ghost-weaver::".to_vec();
        endpoint_key.extend_from_slice(b"endpoint-");
        endpoint_key.extend_from_slice(&network_id_encoded);

        let mut distance_key = b"ghost-weaver::".to_vec();
        distance_key.extend_from_slice(b"distance-");
        distance_key.extend_from_slice(&network_id_encoded);

        let target_endpoint = b"http://localhost:8545".to_vec();
        let rpc_endpoints: Vec<Vec<u8>> = vec![target_endpoint.clone()];
        sp_io::offchain::local_storage_set(
            sp_core::offchain::StorageKind::PERSISTENT,
            &endpoint_key,
            &rpc_endpoints.encode(),
        );

        let custom_headers: Vec<(Vec<u8>, Vec<u8>)> = vec![
            (b"X-Custom-Provider".to_vec(), b"GhostWeaverNode".to_vec()),
            (
                b"Authorization".to_vec(),
                b"Bearer new-api-token-123".to_vec(),
            ),
        ];

        sp_io::offchain::local_storage_set(
            sp_core::offchain::StorageKind::PERSISTENT,
            &target_endpoint,
            &custom_headers.encode(),
        );

        sp_io::crypto::sr25519_generate(
            sp_core::crypto::KeyTypeId(*b"weav"),
            Some(b"//Alice".to_vec()),
        );
    });

    {
        let mut state = offchain_state.write();

        state.expect_request(PendingRequest {
            method: "POST".into(),
            uri: "https://publicbitcoin.io".into(),
            headers: vec![
                ("Accept".into(), "application/json".into()),
                ("Content-Type".into(), "application/json".into()),
            ],
            body: b"{\"id\":1,\"jsonrpc\":\"2.0\",\"method\":\"getblockcount\"}".to_vec(),
            response: Some(b"{\"jsonrpc\":\"2.0\",\"id\":1,\"result\":960127}".to_vec()),
            sent: true,
            ..Default::default()
        });

        state.expect_request(PendingRequest {
            method: "POST".into(),
            uri: "http://localhost:8545".into(),
            headers: vec![
                ("Accept".into(), "application/json".into()),
                ("Content-Type".into(), "application/json".into()),
                ("X-Custom-Provider".into(), "GhostWeaverNode".into()),
                ("Authorization".into(), "Bearer new-api-token-123".into()),
            ],
            body: b"{\"id\":2,\"jsonrpc\":\"2.0\",\"method\":\"eth_blockNumber\"}".to_vec(),
            response: Some(b"{\"jsonrpc\":\"2.0\",\"id\":2,\"result\":\"0x1873a84\"}".to_vec()),
            sent: true,
            ..Default::default()
        });
    }

    ext.execute_with(|| {
        System::set_block_number(1u64);
        GhostWeaver::offchain_worker(1u64);
        System::set_block_number(2u64);

        let state = pool_state.read();
        assert_eq!(state.transactions.len(), 1);

        let prev_utxo_block = NetworkAttestations::<TestRuntime>::get(utxo_network_id)
            .get(authority_index as usize)
            .and_then(|opt| *opt)
            .unwrap_or(0);

        apply_and_clear_pool_transaction(&pool_state, 0);

        let curr_utxo_block = NetworkAttestations::<TestRuntime>::get(utxo_network_id)
            .get(authority_index as usize)
            .and_then(|opt| *opt)
            .unwrap_or(0);

        assert_eq!(prev_utxo_block, 0);
        assert_eq!(curr_utxo_block, 960127);

        assert!(TapestryDrafts::<TestRuntime>::get(&utxo_network_id).is_none());
        GhostWeaver::on_initialize(3u64);
        assert!(TapestryDrafts::<TestRuntime>::get(&utxo_network_id).is_some());
    });

    ext.execute_with(|| {
        System::set_block_number(2u64);
        GhostWeaver::offchain_worker(2u64);
        System::set_block_number(3u64);

        let state = pool_state.read();
        assert_eq!(state.transactions.len(), 2);

        let prev_evm_block = NetworkAttestations::<TestRuntime>::get(evm_network_id)
            .get(authority_index as usize)
            .and_then(|opt| *opt)
            .unwrap_or(0);

        apply_and_clear_pool_transaction(&pool_state, 1);

        let curr_evm_block = NetworkAttestations::<TestRuntime>::get(evm_network_id)
            .get(authority_index as usize)
            .and_then(|opt| *opt)
            .unwrap_or(0);

        assert_eq!(prev_evm_block, 0);
        assert_eq!(curr_evm_block, 25639556);

        assert!(TapestryDrafts::<TestRuntime>::get(&evm_network_id).is_none());
        GhostWeaver::on_initialize(4u64);
        assert!(TapestryDrafts::<TestRuntime>::get(&evm_network_id).is_some());
    });
}

#[test]
fn offchain_worker_should_fetch_hash_and_submit_unsigned_tx() {
    let evm_network_id = 1u32;
    let utxo_network_id = 69u32;

    let pair = AuthorityPair::from_string("//Alice", None).expect("Should be valid seed");

    let new_evm_network_data = NetworkDataBuilder::default()
        .with_network_type(NetworkType::Evm)
        .with_gatekeeper(
            hex::decode("02f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9")
                .expect("Invalid public key"),
        )
        .with_default_endpoints(vec![b"https://super-bad-public-rpc-endpoint.com".to_vec()])
        .build();

    let new_utxo_network_data = NetworkDataBuilder::default()
        .with_network_type(NetworkType::Utxo)
        .with_default_endpoints(vec![b"https://publicbitcoin.io".to_vec()])
        .build();

    let evm_session = 69;
    let utxo_session = 420;

    let authorities = vec![pair.clone()];
    let networks = vec![
        (evm_network_id, new_evm_network_data, 0u64),
        (utxo_network_id, new_utxo_network_data, 0u64),
    ];
    let mut ext = new_test_ext(authorities, networks);

    let (offchain, offchain_state) = TestOffchainExt::new();
    let (pool, pool_state) = TestTransactionPoolExt::new();

    ext.register_extension(OffchainWorkerExt::new(offchain.clone()));
    ext.register_extension(OffchainDbExt::new(offchain));
    ext.register_extension(TransactionPoolExt::new(pool));

    ext.execute_with(|| {
        let tapestry_draft = TapestryDraftBuilder::<crate::ExternalBlockNumber, u32>::default();

        let evm_tapestry_draft = tapestry_draft.with_median_external(25639556).build();

        let utxo_tapestry_draft = tapestry_draft.with_median_external(960129).build();

        CurrentWeavingSession::<TestRuntime>::insert(&evm_network_id, evm_session);
        CurrentWeavingSession::<TestRuntime>::insert(&utxo_network_id, utxo_session);

        TapestryDrafts::<TestRuntime>::insert(&evm_network_id, evm_tapestry_draft);
        TapestryDrafts::<TestRuntime>::insert(&utxo_network_id, utxo_tapestry_draft);

        let network_id_encoded = evm_network_id.encode();

        let mut endpoint_key = b"ghost-weaver::".to_vec();
        endpoint_key.extend_from_slice(b"endpoint-");
        endpoint_key.extend_from_slice(&network_id_encoded);

        let mut distance_key = b"ghost-weaver::".to_vec();
        distance_key.extend_from_slice(b"distance-");
        distance_key.extend_from_slice(&network_id_encoded);

        let target_endpoint = b"http://localhost:8545".to_vec();
        let rpc_endpoints: Vec<Vec<u8>> = vec![target_endpoint.clone()];
        sp_io::offchain::local_storage_set(
            sp_core::offchain::StorageKind::PERSISTENT,
            &endpoint_key,
            &rpc_endpoints.encode(),
        );

        let custom_headers: Vec<(Vec<u8>, Vec<u8>)> = vec![
            (b"X-Custom-Provider".to_vec(), b"GhostWeaverNode".to_vec()),
            (
                b"Authorization".to_vec(),
                b"Bearer new-api-token-123".to_vec(),
            ),
        ];

        sp_io::offchain::local_storage_set(
            sp_core::offchain::StorageKind::PERSISTENT,
            &target_endpoint,
            &custom_headers.encode(),
        );

        sp_io::crypto::sr25519_generate(
            sp_core::crypto::KeyTypeId(*b"weav"),
            Some(b"//Alice".to_vec()),
        );
    });

    {
        let mut state = offchain_state.write();

        state.expect_request(PendingRequest {
            method: "POST".into(),
            uri: "https://publicbitcoin.io".into(),
            headers: vec![
                ("Accept".into(), "application/json".into()),
                ("Content-Type".into(), "application/json".into()),
            ],
            body: b"{\"id\":1,\"jsonrpc\":\"2.0\",\"method\":\"getblockhash\",\"params\":[960129]}".to_vec(),
            response: Some(b"{\"jsonrpc\":\"2.0\",\"id\":1,\"result\":\"0000000000000000000091c72779c83d76dfa8149e950f3a5287377a9708d5c1\"}".to_vec()),
            sent: true,
            ..Default::default()
        });

        state.expect_request(PendingRequest {
            method: "POST".into(),
            uri: "http://localhost:8545".into(),
            headers: vec![
                ("Accept".into(), "application/json".into()),
                ("Content-Type".into(), "application/json".into()),
                ("X-Custom-Provider".into(), "GhostWeaverNode".into()),
                ("Authorization".into(), "Bearer new-api-token-123".into()),
            ],
            // Match the EXACT field order: data first, then to
            body: b"{\"id\":2,\"jsonrpc\":\"2.0\",\"method\":\"eth_call\",\"params\":[{\"data\":\"0x00000000000000000000000000000000000000000000000000000000000000450000000000000000000000000000000000000000000000000000000001873a84\",\"to\":\"0x02f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9\"},\"latest\"]}".to_vec(),
            response: Some(b"{\"jsonrpc\":\"2.0\",\"id\":2,\"result\":\"0xf72b9ef0b66c8cc3952ffd11dc0b85f3b02e6edfa9236da400138f2fcba4668d0000000000000000000000000000000000000000000000000000000000000046\"}".to_vec()),
            sent: true,
            ..Default::default()
        });
    }

    ext.execute_with(|| {
        System::set_block_number(1u64);
        GhostWeaver::offchain_worker(1u64);
        System::set_block_number(2u64);

        let state = pool_state.read();
        assert_eq!(state.transactions.len(), 1);

        let prev_weaving_state = WeavingStates::<TestRuntime>::get(utxo_network_id);
        apply_and_clear_pool_transaction(&pool_state, 0);
        let curr_weaving_state = WeavingStates::<TestRuntime>::get(utxo_network_id);

        assert_eq!(prev_weaving_state.count, 0);
        assert_eq!(prev_weaving_state.next_session, 0);
        assert_eq!(prev_weaving_state.hash, H256::default());

        assert_eq!(curr_weaving_state.count, 1);
        assert_eq!(curr_weaving_state.next_session, crate::WeavingSession::MAX);

        let bytes = hex::decode("0000000000000000000091c72779c83d76dfa8149e950f3a5287377a9708d5c1")
            .expect("UTXO block hash should be valid");
        let block_hash = H256::from_slice(&bytes);

        assert_eq!(curr_weaving_state.hash, block_hash);

        let prev_state = LoomStates::<TestRuntime>::get(&utxo_network_id, &utxo_session);
        GhostWeaver::on_initialize(3u64);
        let curr_state = LoomStates::<TestRuntime>::get(&utxo_network_id, &utxo_session);

        assert_eq!(prev_state, H256::default());
        assert_eq!(curr_state, block_hash);
    });

    ext.execute_with(|| {
        System::set_block_number(2u64);
        GhostWeaver::offchain_worker(2u64);
        System::set_block_number(3u64);

        let state = pool_state.read();
        assert_eq!(state.transactions.len(), 2);

        let prev_weaving_state = WeavingStates::<TestRuntime>::get(evm_network_id);
        apply_and_clear_pool_transaction(&pool_state, 1);
        let curr_weaving_state = WeavingStates::<TestRuntime>::get(evm_network_id);

        assert_eq!(prev_weaving_state.count, 0);
        assert_eq!(prev_weaving_state.next_session, 0);
        assert_eq!(prev_weaving_state.hash, H256::default());

        assert_eq!(curr_weaving_state.count, 1);
        assert_eq!(curr_weaving_state.next_session, evm_session + 1);

        let bytes = hex::decode("f72b9ef0b66c8cc3952ffd11dc0b85f3b02e6edfa9236da400138f2fcba4668d")
            .expect("UTXO block hash should be valid");
        let block_hash = H256::from_slice(&bytes);

        assert_eq!(curr_weaving_state.hash, block_hash);

        let prev_state = LoomStates::<TestRuntime>::get(&evm_network_id, &evm_session);
        GhostWeaver::on_initialize(4u64);
        let curr_state = LoomStates::<TestRuntime>::get(&evm_network_id, &evm_session);

        assert_eq!(prev_state, H256::default());
        assert_eq!(curr_state, block_hash);
    });
}

#[test]
fn should_successfully_pull_evm_thread_and_mint_currency() {
    let pair = AuthorityPair::from_string("//Alice", None).expect("Should be valid seed");

    let network_id = 1;
    let network_data = NetworkDataBuilder::default()
        .with_network_type(NetworkType::Evm)
        .build();

    let authorities = vec![pair.clone()];
    let networks = vec![(network_id, network_data, Default::default())];

    // Contract address: 0x9a52C28dA655b69d8ddc430d6ebD04630BA0e845
    //
    // three inserts
    // 69   sfJ9hc4A7r578XM35nd48B3FWcd33XjpVnAbGC5tvtwthMWdU - 0xc477f0a42fdd861485bd854c7a5851614ea163bd295f7844e1c5493d662fdc4e
    // 420  sfDxNicCEPts6CVttVMPCs2eoymDpQahu1GUVyGPWu6dhwADJ - 0x0ae3ba32f8555fe3031461e2cb6feeadb67029ef7490b982824fc90751a4cb3e
    // 1337 sfH6zJ63fcxrFAZ1RmiHbxgy2t3sEufY26WdsBSS359AzJd4w - 0x962a2794f66c89e55d9b9692ce59f67345b99f6fddb51d90462c7eca8b5a7e1b

    // https://sepolia.etherscan.io/address/0x9cffbdbdf29c67c5dbab1b5e8ae897aeafcaf70c#readContract
    // getRoot: atBlock 11383380, globalIndexes from 0 to 2
    let inserts = vec![
        (
            0,
            hex::decode("c477f0a42fdd861485bd854c7a5851614ea163bd295f7844e1c5493d662fdc4e")
                .expect("Bytes32 from EVM should be valid"),
            69u64,
            vec![
                H256::from_slice(
                    &hex::decode(
                        "c7a710c9acbc193692f34ac1f1979013b04240a4c0d02b49b9178f17721350b1",
                    )
                    .expect("Proof should be valid"),
                ),
                H256::from_slice(
                    &hex::decode(
                        "9e0f9c5b8ffa146b74bb614482c0bc65a1ef961a8fa9a3a031a36c97f8c70733",
                    )
                    .expect("Proof should be valid"),
                ),
                H256::from_slice(
                    &hex::decode(
                        "890740a8eb06ce9be422cb8da5cdafc2b58c0a5e24036c578de2a433c828ff7d",
                    )
                    .expect("Proof should be valid"),
                ),
                H256::from_slice(
                    &hex::decode(
                        "3b8ec09e026fdc305365dfc94e189a81b38c7597b3d941c279f042e8206e0bd8",
                    )
                    .expect("Proof should be valid"),
                ),
                H256::from_slice(
                    &hex::decode(
                        "ecd50eee38e386bd62be9bedb990706951b65fe053bd9d8a521af753d139e2da",
                    )
                    .expect("Proof should be valid"),
                ),
                H256::from_slice(
                    &hex::decode(
                        "defff6d330bb5403f63b14f33b578274160de3a50df4efecf0e0db73bcdd3da5",
                    )
                    .expect("Proof should be valid"),
                ),
                H256::from_slice(
                    &hex::decode(
                        "617bdd11f7c0a11f49db22f629387a12da7596f9d1704d7465177c63d88ec7d7",
                    )
                    .expect("Proof should be valid"),
                ),
                H256::from_slice(
                    &hex::decode(
                        "292c23a9aa1d8bea7e2435e555a4a60e379a5a35f3f452bae60121073fb6eead",
                    )
                    .expect("Proof should be valid"),
                ),
            ],
            vec![H256::from_slice(
                &hex::decode("350a78f78c810898b7c60ddba671543bfbe683ffb0ac393df0e132f607b5f738")
                    .expect("Slot should be valid hex"),
            )],
        ),
        (
            1,
            hex::decode("0ae3ba32f8555fe3031461e2cb6feeadb67029ef7490b982824fc90751a4cb3e")
                .expect("Bytes32 from EVM should be valid"),
            420u64,
            vec![
                H256::from_slice(
                    &hex::decode(
                        "6dfb19f049f557abff273ce9efb9195924d41e5699b1b7755be2c515b25ef7b6",
                    )
                    .expect("Proof should be valid"),
                ),
                H256::from_slice(
                    &hex::decode(
                        "9e0f9c5b8ffa146b74bb614482c0bc65a1ef961a8fa9a3a031a36c97f8c70733",
                    )
                    .expect("Proof should be valid"),
                ),
                H256::from_slice(
                    &hex::decode(
                        "890740a8eb06ce9be422cb8da5cdafc2b58c0a5e24036c578de2a433c828ff7d",
                    )
                    .expect("Proof should be valid"),
                ),
                H256::from_slice(
                    &hex::decode(
                        "3b8ec09e026fdc305365dfc94e189a81b38c7597b3d941c279f042e8206e0bd8",
                    )
                    .expect("Proof should be valid"),
                ),
                H256::from_slice(
                    &hex::decode(
                        "ecd50eee38e386bd62be9bedb990706951b65fe053bd9d8a521af753d139e2da",
                    )
                    .expect("Proof should be valid"),
                ),
                H256::from_slice(
                    &hex::decode(
                        "defff6d330bb5403f63b14f33b578274160de3a50df4efecf0e0db73bcdd3da5",
                    )
                    .expect("Proof should be valid"),
                ),
                H256::from_slice(
                    &hex::decode(
                        "617bdd11f7c0a11f49db22f629387a12da7596f9d1704d7465177c63d88ec7d7",
                    )
                    .expect("Proof should be valid"),
                ),
                H256::from_slice(
                    &hex::decode(
                        "292c23a9aa1d8bea7e2435e555a4a60e379a5a35f3f452bae60121073fb6eead",
                    )
                    .expect("Proof should be valid"),
                ),
            ],
            vec![H256::from_slice(
                &hex::decode("2e474dabf492786b3505d7b7cf0bf07c9dbce92c91982fa7344c77e24fd4310d")
                    .expect("Slot should be valid hex"),
            )],
        ),
        (
            2,
            hex::decode("962a2794f66c89e55d9b9692ce59f67345b99f6fddb51d90462c7eca8b5a7e1b")
                .expect("Bytes32 from EVM should be valid"),
            1337u64,
            vec![
                H256::from_slice(
                    &hex::decode(
                        "290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563",
                    )
                    .expect("Proof should be valid"),
                ),
                H256::from_slice(
                    &hex::decode(
                        "82ca531d09faff937c9b68f53d473c9f2c88bdbc8b1629af894479367881db5c",
                    )
                    .expect("Proof should be valid"),
                ),
                H256::from_slice(
                    &hex::decode(
                        "890740a8eb06ce9be422cb8da5cdafc2b58c0a5e24036c578de2a433c828ff7d",
                    )
                    .expect("Proof should be valid"),
                ),
                H256::from_slice(
                    &hex::decode(
                        "3b8ec09e026fdc305365dfc94e189a81b38c7597b3d941c279f042e8206e0bd8",
                    )
                    .expect("Proof should be valid"),
                ),
                H256::from_slice(
                    &hex::decode(
                        "ecd50eee38e386bd62be9bedb990706951b65fe053bd9d8a521af753d139e2da",
                    )
                    .expect("Proof should be valid"),
                ),
                H256::from_slice(
                    &hex::decode(
                        "defff6d330bb5403f63b14f33b578274160de3a50df4efecf0e0db73bcdd3da5",
                    )
                    .expect("Proof should be valid"),
                ),
                H256::from_slice(
                    &hex::decode(
                        "617bdd11f7c0a11f49db22f629387a12da7596f9d1704d7465177c63d88ec7d7",
                    )
                    .expect("Proof should be valid"),
                ),
                H256::from_slice(
                    &hex::decode(
                        "292c23a9aa1d8bea7e2435e555a4a60e379a5a35f3f452bae60121073fb6eead",
                    )
                    .expect("Proof should be valid"),
                ),
            ],
            vec![H256::from_slice(
                &hex::decode("bde870fce92d701a7a5d6f63003e1cd2cb61c3266fc1be256844b8ca61d9c9ab")
                    .expect("Slot should be valid hex"),
            )],
        ),
    ];

    new_test_ext(authorities, networks).execute_with(|| {
        // https://sepolia.etherscan.io/address/0x9cffbdbdf29c67c5dbab1b5e8ae897aeafcaf70c#readContract
        // getRoot: session 0, atBlock 11383380
        let session = 0;
        let root_string =
            hex::decode("f72b9ef0b66c8cc3952ffd11dc0b85f3b02e6edfa9236da400138f2fcba4668d")
                .expect("Root hex should be valid");
        let expected_root = H256::from_slice(&root_string);
        LoomStates::<TestRuntime>::insert(&network_id, &session, expected_root);

        for insert in inserts.into_iter() {
            let index_usize = insert.0 as crate::ThreadId;
            let proof_index = index_usize % 256; // tree depth is fixed to 8
            let slot_index = index_usize / 256; // slots depth is fixed to 8

            let receiver_32: [u8; 32] = insert
                .1
                .try_into()
                .expect("Hex string must be exactly 32 bytes long");

            let receiver_account = sp_runtime::AccountId32::from(receiver_32);
            let transfer_amount = insert.2;

            let payload =
                ThreadPayload::new(proof_index, transfer_amount, receiver_account.clone());

            let proof = insert.3;
            let slots = insert.4;

            let evm_thread_proof = EvmThreadProof::new(slot_index, payload, proof, slots);

            let thread_info = ThreadProof::EvmThreadProof(evm_thread_proof);
            let pulled_thread_key = thread_info.get_unique_key(session);

            assert_eq!(Balances::free_balance(&receiver_account), 0);
            assert!(!PulledThreads::<TestRuntime>::contains_key(
                &pulled_thread_key
            ));
            assert!(GhostWeaver::pull_thread(
                RuntimeOrigin::none(),
                network_id,
                session,
                thread_info
            )
            .is_ok());

            assert!(PulledThreads::<TestRuntime>::contains_key(
                &pulled_thread_key
            ));

            let expected_commission = 0u64;
            let expected_pure_amount = transfer_amount - expected_commission;

            assert_eq!(
                Balances::free_balance(&receiver_account),
                expected_pure_amount
            );

            System::assert_last_event(RuntimeEvent::GhostWeaver(Event::ThreadPulled {
                pulled_thread_key,
                network_id,
                receiver: receiver_account,
                amount: transfer_amount,
            }));
        }
    });
}

#[test]
fn should_successfully_pull_utxo_thread_and_mint_currency() {
    let pair = AuthorityPair::from_string("//Alice", None).expect("Should be valid seed");

    let network_id = 69;
    let network_data = NetworkDataBuilder::default()
        .with_network_type(NetworkType::Utxo)
        .with_gatekeeper(
            // Transaction: https://blockstream.info/tx/c41999f86269d5a22f39e18530b065854f447ef64a48be4013c4a9faa657f418
            hex::decode("c6e4e0f822c31540b4b05903ce3c67b6cff8e6d4000000000000000000000000")
                .expect("Bytes32 from UTXO should be valid"),
        )
        .build();

    let authorities = vec![pair.clone()];
    let networks = vec![(network_id, network_data, Default::default())];

    // Real world tx at block #960127
    // Block: https://blockstream.info/block/0000000000000000000091c72779c83d76dfa8149e950f3a5287377a9708d5c1
    let inserts = vec![
        (
        	// Transaction: https://blockstream.info/tx/c41999f86269d5a22f39e18530b065854f447ef64a48be4013c4a9faa657f418
        	// We are looking into second output and first witness
         	// NOTE: would be nice to use on of our txs
            hex::decode("6969696969696969696969696969696969696969696969696969696969696969").expect("Bytes32 from UTXO should be valid"),
            140_693u64,
            1,
            0,
            // curl --data-binary '{"jsonrpc": "2.0", "id": "test-proof", "method": "gettxoutproof", "params": [["c41999f86269d5a22f39e18530b065854f447ef64a48be4013c4a9faa657f418"], "0000000000000000000091c72779c83d76dfa8149e950f3a5287377a9708d5c1"]}' -H 'Content-Type: application/json' https://bitcoin-rpc.publicnode.com
            hex::decode("008008201643a05d24fe1f015bf472fdedd8ef39dd8247568d3901000000000000000000569ac8f0aed0c5b632dd1dcc031f3d826a170e13cd8176430a2873a33d4694c2501f6a6ad43a02178dbac0d66b1600000e88be94dbcedc3f32bce789eb4512c68b39b91b54c4f2913e84baf7bae21bdc466d954b10876c1e8ad6591461027236c9a471883f96c028a7d1f08deb833f56fa18f457a6faa9c41340be484af67e444f8565b03085e1392fa2d56962f89919c4fcfff99fc6e92be067d01028fb54e8dc1e8425f0ef6bf1cc64220a2ba22163666eb01f99648e8c2af1bb1a0e1ba297f0244a09aa6a6ff87092312b02e8d75aef61e5c08f5b59184a45855e987c5ea114e5da61e55337bfae99f3a2e9601e72ae6036633dc97631609813a30d1185f98e7d6effc4a0330db0394da388c0058e9a730a62d8c679c35bf8d270ca8b95cec7d848729cdfd94a284f060f353b379bfc36310ac78306183a056a04156efd7e77661ce7ba50a4ef9f9e6b3681dfb39d8d0161ad0d2ec46834b5f270b67aa63a8a5b69287e8606b8a438785f8a5af66f84a2641438ba4a5fa22029227e9c2ddb6f23867b112c027d2fc2cf031a46c874701768b5c4983959b98d98736a2ed5ab0dd064ee24e49a3a7dac63e8b857ad4c8b5aa0cf22a7eac3180f3a54630b486de928ecf590e807d2e821818e2fe7e86610187d6673a6f95c639af80a7a7710b0088d44057ca61bdf5f4d5ba68d46b88e4304ffb70000").expect("Bytes32 from UTXO should be valid"),
            // curl --data-binary '{"jsonrpc": "2.0", "id": "test-proof", "method": "getrawtransaction", "params": ["c41999f86269d5a22f39e18530b065854f447ef64a48be4013c4a9faa657f418", true]}' -H 'Content-Type: application/json' https://bitcoin-rpc.publicnode.com
            hex::decode("020000000001029ee4235efd4a3cb183d4c311ce858eeee7748263a28afd3d861bac1cb4a8d368010000000001000000d7c5869bfffaa1877d0ecd37e46dc70c232a16f7955e635d57f926d1b3e640bf0100000000ffffffff02ff490b0000000000160014f635b17877709ba3c5acbe153f38a47a733f5b169525020000000000160014c6e4e0f822c31540b4b05903ce3c67b6cff8e6d40247304402200f2f3763fad59d38b4e101b9675450c0a54d45fe17e2b1babde0d0ce6051ea5b0220643e71d66752c0f1bd30dc0897305da77f223d14c781e86063ac181ad7fb90b6012102aad4cca3dab6427bc754a5a123de32cd037e7177fade9f72d83088b00066cffc0247304402200c8f1ff8230813e5e4ab8ec802c614bc8705c407c5958d64dd79cc8422d85a6202203ea832d581c404200b5974fd1a11abfe1ebac213842083cb02eba3f253c8c2aa012102d70df1d4d58701adab82b4816e0640c27403d1fab859ca9f47cb6eccca3dd96200000000").expect("Bytes32 from UTXO should be valid"),
            vec![
                // curl --data-binary '{"jsonrpc": "2.0", "id": "test-proof", "method": "getblockheader", "params": ["0000000000000000000084bd8092a07bc89245c2bf05f2cf75851bcc5ef92f70", false]}' -H 'Content-Type: application/json' https://bitcoin-rpc.publicnode.com
                hex::decode("00a01520c1d508977a3787523a0f959e14a8df763dc87927c7910000000000000000000036303f2bcf94f752a1d4b0641d1adbc2d80aa89628feefd7f837a74792e26ab8bb276a6ad43a0217bece2e64").expect("Bytes32 from UTXO should be valid"),
                // curl --data-binary '{"jsonrpc": "2.0", "id": "test-proof", "method": "getblockheader", "params": ["000000000000000000016792d9c1460bfa4db07da3b724db76c3dd0640ca5754", false]}' -H 'Content-Type: application/json' https://bitcoin-rpc.publicnode.com
                hex::decode("0400e020702ff95ecc1b8575cff205bfc24592c87ba09280bd84000000000000000000008ca9c40d5ab762f160661635cade50fd14571dcf5fdf8c463b617caf9b07dc5a3b296a6ad43a02171340d661").expect("Bytes32 from UTXO should be valid"),
                // curl --data-binary '{"jsonrpc": "2.0", "id": "test-proof", "method": "getblockheader", "params": ["0000000000000000000078eb1af63fe8d57f93079121e19968a8563c05af370e", false]}' -H 'Content-Type: application/json' https://bitcoin-rpc.publicnode.com
                hex::decode("000000345457ca4006ddc376db24b7a37db04dfa0b46c1d99267010000000000000000009409d64eb06a6dd83ae2937f70d07222d75505a07f12e756b61a27189851e3bbfe2c6a6ad43a0217a06575b5").expect("Bytes32 from UTXO should be valid"),
            ],
        )
    ];

    new_test_ext(authorities, networks).execute_with(|| {
        let session = 0;
        let root_string =
            hex::decode("0000000000000000000078eb1af63fe8d57f93079121e19968a8563c05af370e")
                .expect("Bitcoin Root hex should be valid");
        let expected_root = H256::from_slice(&root_string);

        LoomStates::<TestRuntime>::insert(&network_id, &session, expected_root);

        for insert in inserts.into_iter() {
            let receiver_32: [u8; 32] = insert
                .0
                .try_into()
                .expect("Receiver address must be exactly 32 bytes");
            let receiver_account = sp_runtime::AccountId32::from(receiver_32);
            let transfer_amount = insert.1;

            let payload = ThreadPayload::new(12, transfer_amount, receiver_account.clone());
            let utxo_thread_proof = UtxoThreadProof::new(
                insert.2,
                insert.3,
                transfer_amount,
                payload,
                insert.4,
                insert.5,
                insert.6,
            );

            let thread_info = ThreadProof::UtxoThreadProof(utxo_thread_proof);
            let pulled_thread_key = thread_info.get_unique_key(session);

            assert_eq!(Balances::free_balance(&receiver_account), 0);
            assert!(!PulledThreads::<TestRuntime>::contains_key(
                &pulled_thread_key
            ));

            assert!(GhostWeaver::pull_thread(
                RuntimeOrigin::none(),
                network_id,
                session,
                thread_info
            )
            .is_ok());

            assert!(PulledThreads::<TestRuntime>::contains_key(
                &pulled_thread_key
            ));

            let expected_commission = 0u64;
            let expected_pure_amount = transfer_amount - expected_commission;

            assert_eq!(
                Balances::free_balance(&receiver_account),
                expected_pure_amount
            );

            System::assert_last_event(RuntimeEvent::GhostWeaver(Event::ThreadPulled {
                pulled_thread_key,
                network_id,
                receiver: receiver_account,
                amount: transfer_amount,
            }));
        }
    });
}

#[test]
fn on_initialize_should_finalize_session_when_threshold_or_timeout_is_reached() {
    let pair1 = AuthorityPair::from_string("//Alice", None).expect("Should be valid seed");
    let pair2 = AuthorityPair::from_string("//Bob", None).expect("Should be valid seed");
    let pair3 = AuthorityPair::from_string("//Charlie", None).expect("Should be valid seed");

    let network_id = 1;

    let new_network_data = NetworkDataBuilder::default()
        .with_network_type(NetworkType::Evm)
        .build();

    let authorities = vec![pair1.clone(), pair2.clone(), pair3.clone()];
    let networks = vec![(network_id, new_network_data, 0u64)];

    new_test_ext(authorities, networks).execute_with(|| {
        let current_substrate_block = 10;
        System::set_block_number(current_substrate_block + 1);

        let tapestry_draft = TapestryDraftBuilder::default()
            .with_current_block(current_substrate_block)
            .with_block_delay(5u32)
            .with_median_external(100)
            .build();

        TapestryDrafts::<TestRuntime>::insert(&network_id, tapestry_draft);

        let target_hash = H256::repeat_byte(0xAA);
        let next_session = 69;

        let attestation = AttestationContext::default()
            .with_current_block(current_substrate_block)
            .with_network_id(network_id)
            .with_weaving_session(next_session);

        let hash_att1 = attestation
            .with_authority_index(0)
            .build_hash_attestation(target_hash, next_session);

        let hash_att2 = attestation
            .with_authority_index(1)
            .build_hash_attestation(target_hash, next_session);

        assert!(GhostWeaver::weave_weft(
            RuntimeOrigin::none(),
            hash_att1,
            pair1.sign(&hash_att1.encode())
        )
        .is_ok());
        assert!(GhostWeaver::weave_weft(
            RuntimeOrigin::none(),
            hash_att2,
            pair2.sign(&hash_att2.encode())
        )
        .is_ok());

        let state_before = WeavingStates::<TestRuntime>::get(&network_id);
        assert_eq!(state_before.count, 2);
        assert_eq!(state_before.hash, target_hash);

        let current_session = CurrentWeavingSession::<TestRuntime>::get(&network_id);
        GhostWeaver::on_initialize(current_substrate_block);

        let saved_loot = LoomStates::<TestRuntime>::get(&network_id, current_session);
        assert_eq!(saved_loot, target_hash);

        let updated_session = CurrentWeavingSession::<TestRuntime>::get(&network_id);
        assert_eq!(updated_session, current_session + 1);

        System::set_block_number(15);
        GhostWeaver::on_initialize(15);
    });
}

#[test]
fn test_validate_block_numbers_consensus_comprehensive() {
    // Test 1: Not enough blocks (below threshold)
    {
        let mut blocks = create_block_numbers(&[1, 2, 3]);
        let result = GhostWeaver::validate_block_numbers_consensus(&mut blocks, 10u64, 5);
        assert_eq!(result, None, "Should return None when below threshold");
    }

    // Test 2: Single block with threshold 1
    {
        let mut blocks = create_block_numbers(&[42]);
        let result = GhostWeaver::validate_block_numbers_consensus(&mut blocks, 10u64, 1);
        assert_eq!(result, Some(42u8.into()), "Should accept single block");
    }

    // Test 3: All blocks within deviation
    {
        let mut blocks = create_block_numbers(&[10, 11, 12, 13, 14]);
        let result = GhostWeaver::validate_block_numbers_consensus(&mut blocks, 5u64, 3);
        assert_eq!(
            result,
            Some(12u8.into()),
            "Should find median when all within deviation"
        );
    }

    // Test 4: Blocks with outliers
    {
        let mut blocks = create_block_numbers(&[1, 10, 11, 12, 13]);
        let result = GhostWeaver::validate_block_numbers_consensus(&mut blocks, 3u64, 3);
        assert_eq!(
            result,
            Some(11u8.into()),
            "Should find consensus among 10,11,12,13"
        );
    }

    // Test 5: Even number of blocks in consensus window
    {
        let mut blocks = create_block_numbers(&[1, 5, 6, 7, 8, 9, 10, 100]);
        let result = GhostWeaver::validate_block_numbers_consensus(&mut blocks, 5u64, 4);
        assert_eq!(
            result,
            Some(7u8.into()),
            "Even window should average middle two"
        );
    }

    // Test 6: Large deviations
    {
        let mut blocks = create_block_numbers(&[1, 2, 3, 100, 101, 102]);
        let result = GhostWeaver::validate_block_numbers_consensus(&mut blocks, 2u64, 3);
        assert_eq!(
            result,
            Some(101u8.into()),
            "Should pick majority cluster 1,2,3"
        );
    }

    // Test 7: Multiple clusters
    {
        let mut blocks = create_block_numbers(&[1, 2, 3, 20, 21, 22, 23]);
        let result = GhostWeaver::validate_block_numbers_consensus(&mut blocks, 3u64, 4);
        assert_eq!(
            result,
            Some(21u8.into()),
            "Should pick larger cluster 20-23"
        );
    }

    // Test 8: Max deviation = 0 (all must be equal)
    {
        let mut blocks = create_block_numbers(&[5, 5, 5, 6, 5]);
        let result = GhostWeaver::validate_block_numbers_consensus(&mut blocks, 0u64, 3);
        assert_eq!(result, Some(5u8.into()), "Should only accept exact matches");
    }

    // Test 9: Max deviation = 0 with no consensus
    {
        let mut blocks = create_block_numbers(&[1, 2, 3, 4, 5]);
        let result = GhostWeaver::validate_block_numbers_consensus(&mut blocks, 0u64, 3);
        assert_eq!(result, None, "Should reject when no exact matches");
    }

    // Test 10: Duplicate values
    {
        let mut blocks = create_block_numbers(&[1, 1, 1, 2, 2, 2, 2, 3]);
        let result = GhostWeaver::validate_block_numbers_consensus(&mut blocks, 1u64, 4);
        assert_eq!(
            result,
            Some(2u8.into()),
            "Should handle duplicates correctly"
        );
    }

    // Test 11: Unsorted input (should sort internally)
    {
        let mut blocks = create_block_numbers(&[5, 1, 4, 2, 3]);
        let result = GhostWeaver::validate_block_numbers_consensus(&mut blocks, 10u64, 5);
        assert_eq!(result, Some(3u8.into()), "Should sort and find median");
    }
}

#[test]
fn test_validate_block_numbers_consensus_edge_cases() {
    // Edge 1: Empty vector
    {
        let mut blocks: Vec<crate::ExternalBlockNumber> = vec![];
        let result = GhostWeaver::validate_block_numbers_consensus(&mut blocks, 10u64, 1);
        assert_eq!(result, None, "Empty vector should return None");
    }

    // Edge 2: Very large deviation
    {
        let mut blocks = create_block_numbers(&[1, 100, 200, 300, 400]);
        let result = GhostWeaver::validate_block_numbers_consensus(&mut blocks, 1000u64, 3);
        assert_eq!(
            result,
            Some(200u8.into()),
            "Should find consensus with large deviation"
        );
    }

    // Edge 3: Threshold equals total blocks
    {
        let mut blocks = create_block_numbers(&[1, 2, 3, 4, 5]);
        let result = GhostWeaver::validate_block_numbers_consensus(&mut blocks, 10u64, 5);
        assert_eq!(
            result,
            Some(3u8.into()),
            "Should work when threshold equals total"
        );
    }

    // Edge 4: Threshold = 1 (minimum)
    {
        let mut blocks = create_block_numbers(&[10, 20, 30, 40, 50]);
        let result = GhostWeaver::validate_block_numbers_consensus(&mut blocks, 100u64, 1);
        assert_eq!(
            result,
            Some(30u8.into()),
            "Threshold 1 should return median of all"
        );
    }

    // Edge 5: Max deviation = usize::MAX
    {
        let mut blocks = create_block_numbers(&[1, 1000, 2000]);
        let result = GhostWeaver::validate_block_numbers_consensus(&mut blocks, u64::MAX, 2);
        assert_eq!(
            result,
            Some(1000u16.into()),
            "Should handle maximum deviation"
        );
    }

    // Edge 6: All values identical
    {
        let mut blocks = create_block_numbers(&[5, 5, 5, 5, 5]);
        let result = GhostWeaver::validate_block_numbers_consensus(&mut blocks, 0u64, 3);
        assert_eq!(
            result,
            Some(5u8.into()),
            "Should return the identical value"
        );
    }

    // Edge 7: Sequential numbers with tight deviation
    {
        let mut blocks = create_block_numbers(&[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
        let result = GhostWeaver::validate_block_numbers_consensus(&mut blocks, 5u64, 5);
        assert_eq!(
            result,
            Some(3u8.into()),
            "Sequential numbers with small deviation"
        );
    }
}

#[test]
fn test_validate_block_numbers_consensus_boundary_conditions() {
    // Boundary 1: Exactly at threshold
    {
        let mut blocks = create_block_numbers(&[10, 11, 12]);
        let result = GhostWeaver::validate_block_numbers_consensus(&mut blocks, 2u64, 3);
        assert_eq!(
            result,
            Some(11u8.into()),
            "Exactly at threshold should work"
        );
    }

    // Boundary 2: One less than threshold
    {
        let mut blocks = create_block_numbers(&[10, 11, 12]);
        let result = GhostWeaver::validate_block_numbers_consensus(&mut blocks, 1u64, 3);
        assert_eq!(result, None, "Below threshold should return None");
    }

    // Boundary 3: Exactly at max deviation
    {
        let mut blocks = create_block_numbers(&[10, 15, 20]);
        let result = GhostWeaver::validate_block_numbers_consensus(&mut blocks, 10u64, 3);
        assert_eq!(
            result,
            Some(15u8.into()),
            "Deviation exactly at max should be accepted"
        );
    }

    // Boundary 4: Just over max deviation
    {
        let mut blocks = create_block_numbers(&[10, 16, 20]);
        let result = GhostWeaver::validate_block_numbers_consensus(&mut blocks, 15u64, 3);
        assert_eq!(
            result,
            Some(16u8.into()),
            "Deviation just over max for some pairs"
        );
    }

    // Boundary 5: Two equal-sized clusters
    {
        let mut blocks = create_block_numbers(&[1, 2, 3, 100, 101, 102]);
        let result = GhostWeaver::validate_block_numbers_consensus(&mut blocks, 2u64, 3);
        assert_eq!(
            result,
            Some(101u8.into()),
            "Should pick first cluster when equal"
        );
    }
}

#[test]
fn test_validate_block_numbers_consensus_complex_scenarios() {
    // Scenario 1: Multi-modal distribution
    {
        let mut blocks = create_block_numbers(&[
            1, 2, 3, // Cluster 1
            10, 11, // Cluster 2
            20, 21, 22, 23,  // Cluster 3 (largest)
            100, // Outlier
        ]);
        let result = GhostWeaver::validate_block_numbers_consensus(&mut blocks, 3u64, 4);
        assert_eq!(result, Some(21u8.into()), "Should pick largest cluster");
    }

    // Scenario 2: Even spread with no clear consensus
    {
        let mut blocks = create_block_numbers(&[1, 5, 10, 15, 20, 25, 30]);
        let result = GhostWeaver::validate_block_numbers_consensus(&mut blocks, 21u64, 4);
        assert_eq!(
            result,
            Some(10u8.into()),
            "Should find best fit even with spread"
        );
    }

    // Scenario 3: Clusters with different densities
    {
        let mut blocks = create_block_numbers(&[
            1, 2, 2, 2, 3, // Dense cluster
            10, 11, 12, // Sparse cluster
        ]);
        let result = GhostWeaver::validate_block_numbers_consensus(&mut blocks, 3u64, 4);
        assert_eq!(
            result,
            Some(2u8.into()),
            "Dense cluster should be preferred"
        );
    }

    // Scenario 4: Decreasing order input
    {
        let mut blocks = create_block_numbers(&[10, 9, 8, 7, 6, 5]);
        let result = GhostWeaver::validate_block_numbers_consensus(&mut blocks, 10u64, 5);
        assert_eq!(
            result,
            Some(7u8.into()),
            "Should sort and handle decreasing order"
        );
    }

    // Scenario 5: Values at type boundaries
    {
        let min_val: crate::ExternalBlockNumber = 0u64.into();
        let max_val: crate::ExternalBlockNumber = u64::MAX.into();
        let mut blocks = vec![
            min_val,
            (u64::MAX / 2).into(),
            max_val,
            (u64::MAX / 4).into(),
            (3 * (u64::MAX / 4)).into(),
        ];
        let result = GhostWeaver::validate_block_numbers_consensus(&mut blocks, u64::MAX / 8, 3);
        // Should work with large numbers
        assert!(
            result.is_some() || result.is_none(),
            "Should handle boundary values"
        );
    }
}

#[test]
fn test_block_numbers_consensus_median_calculation() {
    // Test median for odd number of elements
    {
        let mut blocks = create_block_numbers(&[1, 2, 3, 100, 101]);
        let result = GhostWeaver::validate_block_numbers_consensus(&mut blocks, 200u64, 5);
        assert_eq!(
            result,
            Some(3u8.into()),
            "Should return median for odd count"
        );
    }

    // Test median for even number of elements
    {
        let mut blocks = create_block_numbers(&[1, 2, 3, 4]);
        let result = GhostWeaver::validate_block_numbers_consensus(&mut blocks, 0u64, 4);
        // When no consensus, should return None for max_deviation=0
        assert!(
            result.is_none() || result.is_some(),
            "Even median calculation"
        );
    }

    // Test median with duplicate values
    {
        let mut blocks = create_block_numbers(&[1, 2, 2, 2, 2, 2, 3, 3, 4]);
        let result = GhostWeaver::validate_block_numbers_consensus(&mut blocks, 1u64, 5);
        assert_eq!(
            result,
            Some(2u8.into()),
            "Should handle duplicates in median"
        );
    }
}

#[test]
fn test_validate_block_numbers_consensus_expansion_strategy() {
    // Test left expansion preference
    {
        let mut blocks = create_block_numbers(&[1, 2, 3, 100, 101]);
        let result = GhostWeaver::validate_block_numbers_consensus(&mut blocks, 2u64, 3);
        assert_eq!(result, Some(2u8.into()), "Should expand left when closer");
    }

    // Test right expansion preference
    {
        let mut blocks = create_block_numbers(&[1, 2, 100, 101, 102]);
        let result = GhostWeaver::validate_block_numbers_consensus(&mut blocks, 2u64, 3);
        assert_eq!(
            result,
            Some(101u8.into()),
            "Should expand right when closer"
        );
    }

    // Test tie-breaking (expand right)
    {
        let mut blocks = create_block_numbers(&[1, 2, 13, 14, 15]);
        let result = GhostWeaver::validate_block_numbers_consensus(&mut blocks, 3u64, 3);
        assert_eq!(
            result,
            Some(14u8.into()),
            "Should break ties by expanding right"
        );
    }
}
