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

use crate::constants::{MAX_DRIFT_SUB_ACCOUNTS, SUPPORTED_KAMINO_MARKETS};

pub struct CloseUserParams {
    pub owner: Pubkey,
    pub admin: Pubkey,
}

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

    let mut accounts = crate::pyra_program::client::accounts::CloseUser {
        vault,
        admin: params.admin,
    }
    .to_account_metas(None);

    // Get remaining accounts
    let valid_drift_user_accounts = (0..MAX_DRIFT_SUB_ACCOUNTS)
        .map(|i| {
            let address = pyra_accounts::get_drift_user(&params.owner, i);
            AccountMeta::new(address, false)
        })
        .collect::<Vec<AccountMeta>>();

    let valid_kamino_user_accounts = SUPPORTED_KAMINO_MARKETS
        .iter()
        .map(|market| {
            let address = pyra_accounts::get_kamino_obligation(&params.owner, market);
            AccountMeta::new(address, false)
        })
        .collect::<Vec<AccountMeta>>();

    accounts.extend(valid_drift_user_accounts);
    accounts.extend(valid_kamino_user_accounts);

    let data = crate::pyra_program::client::args::CloseUser {}.data();

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