use crate::bitcoin::{self, driver};
use crate::utils;
use bdk::wallet::AddressIndex::New;
use bdk::SignOptions;

pub(crate) async fn run() -> anyhow::Result<()> {
    tracing::info!("starting htlc flow");
    let (dave, sammy) = driver::setup().await?;
    let _ = dave.sync();
    let _ = sammy.sync();

    // Create an HTLC descriptor with a redeem identity, a hashlock from the preimage,
    // a refund timelock, and a refund identity
    let value = 500;
    let recipient = sammy.wallet.get_address(New)?.script_pubkey();
    let hash_preimage = "blah".to_string();
    let hashlock = utils::sha256(hash_preimage);
    let htlc = bitcoin::htlc::Htlc::new(dave.public_key, hashlock, 100, sammy.public_key);
    let htlc_descriptor = htlc.to_miniscript_descriptor();

    // format a new commitment transaction like in Lightning
    let mut commitment_builder = dave.wallet.build_tx();
    commitment_builder.add_recipient(recipient, value);
    commitment_builder.enable_rbf();
    let (psbt, _) = commitment_builder
        .finish()
        .expect("unable to build commitment");

    // sign the commitment transaction
    let mut dave_psbt = dave.sign(&mut psbt.clone(), false)?;
    let sammy_psbt = sammy.sign(&mut psbt.clone(), false)?;

    dave_psbt
        .combine(sammy_psbt)
        .expect("problem combining bitcoin PSBTs"); // these guys love mutability

    let finalized = dave
        .wallet
        .finalize_psbt(&mut dave_psbt, SignOptions::default())
        .expect("couldn't finalize");

    assert!(finalized);
    let tx = dave_psbt.extract_tx();

    let _ = dave.broadcast(&tx)?;

    let _ = sammy.sync();
    let sammy_balance = sammy.wallet.get_balance()?;
    tracing::info!("sammy balance: {}", sammy_balance);

    Ok(())
}
