use anchor_lang::{InstructionData, ToAccountMetas};
use solana_program::{instruction::Instruction, pubkey::Pubkey};

use crate::constants::SYSTEM_PROGRAM_ID;

pub struct InitiateWithdrawParams {
    pub owner: Pubkey,
    pub withdraw_order: Pubkey,
    pub payer: Pubkey,
    pub destination: Pubkey,
    pub amount_base_units: u64,
    pub asset_id: pyra_tokens::AssetId,
    pub reduce_only: bool,
    pub protocol_id: crate::pyra_program::types::ProtocolId,
}

pub fn initiate_withdraw(params: &InitiateWithdrawParams) -> Instruction {
    let vault = pyra_accounts::get_vault(&params.owner);

    let accounts = crate::pyra_program::client::accounts::InitiateWithdraw {
        vault,
        owner: params.owner,
        withdraw_order: params.withdraw_order,
        payer: params.payer,
        system_program: SYSTEM_PROGRAM_ID,
        destination: params.destination,
    }
    .to_account_metas(None);

    let data = crate::pyra_program::client::args::InitiateWithdraw {
        protocol_id: params.protocol_id,
        asset_id: params.asset_id.value(),
        amount_base_units: params.amount_base_units,
        reduce_only: params.reduce_only,
    }
    .data();

    Instruction {
        program_id: pyra_accounts::PYRA_PROGRAM_ID,
        accounts,
        data,
    }
}
