use solana_sdk::{
    instruction::Instruction, pubkey::Pubkey, system_instruction,
};
use spl_associated_token_account::{
    get_associated_token_address, instruction::create_associated_token_account_idempotent,
};
use spl_token::native_mint;

/// Returns true if the given mint is the native SOL (wSOL) mint.
pub fn is_native_mint(mint: &Pubkey) -> bool {
    *mint == native_mint::id()
}

/// Build instructions to wrap native SOL into a wSOL ATA.
///
/// Returns \[createATA (idempotent), transfer SOL, syncNative\] instructions.
pub fn wrap_sol_instructions(user: &Pubkey, lamports: u64) -> Vec<Instruction> {
    let ata = get_associated_token_address(user, &native_mint::id());
    vec![
        create_associated_token_account_idempotent(
            user,
            user,
            &native_mint::id(),
            &spl_token::id(),
        ),
        system_instruction::transfer(user, &ata, lamports),
        spl_token::instruction::sync_native(&spl_token::id(), &ata).unwrap(),
    ]
}

/// Build instruction to ensure the user's wSOL ATA exists (idempotent create).
/// Needed before withdraw/swap-output so the program has somewhere to send wSOL.
pub fn create_wsol_ata_instruction(user: &Pubkey) -> Instruction {
    create_associated_token_account_idempotent(
        user,
        user,
        &native_mint::id(),
        &spl_token::id(),
    )
}

/// Build instruction to unwrap wSOL — closes the ATA and sends lamports back to the user.
pub fn unwrap_sol_instruction(user: &Pubkey) -> Instruction {
    let ata = get_associated_token_address(user, &native_mint::id());
    spl_token::instruction::close_account(&spl_token::id(), &ata, user, user, &[]).unwrap()
}
