#[allow(deprecated)]
use solana_sdk::system_program;
use solana_sdk::{
    instruction::{AccountMeta, Instruction},
    pubkey::Pubkey,
};

use crate::constants::Discriminator;
use crate::helpers::derive::get_spread_config_address;
use crate::types::*;

/// Build an InitializeSpreadConfig instruction (discriminator 13).
///
/// Accounts (5): payer(signer,w), authority(signer), config(w), spreadConfig(w), systemProgram.
pub fn build_initialize_spread_config(
    payer: &Pubkey,
    authority: &Pubkey,
    config_pda: &Pubkey,
    params: &InitializeSpreadConfigParams,
    program_id: &Pubkey,
) -> Instruction {
    let (spread_config_pda, _) = get_spread_config_address(config_pda, program_id);

    let mut data = Vec::with_capacity(33);
    data.push(Discriminator::InitializeSpreadConfig as u8);
    data.extend_from_slice(params.admin.as_ref());

    let keys = vec![
        AccountMeta::new(*payer, true),
        AccountMeta::new_readonly(*authority, true),
        AccountMeta::new(*config_pda, false),
        AccountMeta::new(spread_config_pda, false),
        AccountMeta::new_readonly(system_program::id(), false),
    ];

    Instruction {
        program_id: *program_id,
        accounts: keys,
        data,
    }
}

/// Build an UpdateSpreadConfig instruction (discriminator 14).
///
/// Accounts (3): admin(signer), config, spreadConfig(w).
pub fn build_update_spread_config(
    admin: &Pubkey,
    config_pda: &Pubkey,
    params: &UpdateSpreadConfigParams,
    program_id: &Pubkey,
) -> Instruction {
    let (spread_config_pda, _) = get_spread_config_address(config_pda, program_id);

    let mut data = Vec::with_capacity(2 + params.triggers.len() * 34);
    data.push(Discriminator::UpdateSpreadConfig as u8);
    data.push(params.triggers.len() as u8);

    for trigger in &params.triggers {
        data.extend_from_slice(trigger.account.as_ref());
        data.extend_from_slice(&trigger.spread_bps.to_le_bytes());
    }

    let keys = vec![
        AccountMeta::new_readonly(*admin, true),
        AccountMeta::new_readonly(*config_pda, false),
        AccountMeta::new(spread_config_pda, false),
    ];

    Instruction {
        program_id: *program_id,
        accounts: keys,
        data,
    }
}
