use solana_sdk::{
    instruction::{AccountMeta, Instruction},
    pubkey::Pubkey,
};
use spl_associated_token_account::get_associated_token_address_with_program_id;

use crate::constants::Discriminator;
use crate::types::DepositParams;

/// Build a Deposit instruction (discriminator 1).
///
/// Accounts (8): user, vaultX, vaultY, userX, userY, config,
/// tokenProgramX, tokenProgramY.
pub fn build_deposit(
    user: &Pubkey,
    config_pda: &Pubkey,
    mint_x: &Pubkey,
    mint_y: &Pubkey,
    token_program_x: &Pubkey,
    token_program_y: &Pubkey,
    params: &DepositParams,
    program_id: &Pubkey,
) -> Instruction {
    let vault_x =
        get_associated_token_address_with_program_id(config_pda, mint_x, token_program_x);
    let vault_y =
        get_associated_token_address_with_program_id(config_pda, mint_y, token_program_y);
    let user_x = get_associated_token_address_with_program_id(user, mint_x, token_program_x);
    let user_y = get_associated_token_address_with_program_id(user, mint_y, token_program_y);

    let expiration = params.expiration.unwrap_or_else(default_expiration);

    let mut data = Vec::with_capacity(25);
    data.push(Discriminator::Deposit as u8);
    data.extend_from_slice(&params.amount_x.to_le_bytes());
    data.extend_from_slice(&params.amount_y.to_le_bytes());
    data.extend_from_slice(&expiration.to_le_bytes());

    let keys = vec![
        AccountMeta::new_readonly(*user, true),
        AccountMeta::new(vault_x, false),
        AccountMeta::new(vault_y, false),
        AccountMeta::new(user_x, false),
        AccountMeta::new(user_y, false),
        AccountMeta::new_readonly(*config_pda, false),
        AccountMeta::new_readonly(*token_program_x, false),
        AccountMeta::new_readonly(*token_program_y, false),
    ];

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

fn default_expiration() -> i64 {
    std::time::SystemTime::now()
        .duration_since(std::time::UNIX_EPOCH)
        .unwrap()
        .as_secs() as i64
        + 3600
}
