// Core dependencies
import { BN, Program } from "@coral-xyz/anchor";
import { PublicKey, SystemProgram } from "@solana/web3.js";
import { TOKEN_PROGRAM_ID } from "@solana/spl-token";

// Local imports
import { BasketsProgram } from "../../idl/types";
import { getAta, getBasketTokenMintAccount, getWithdrawFeesWallet, getWithdrawStateAccount } from "../../utils/programAccounts";
import { ASSOCIATED_PROGRAM_ID } from "@coral-xyz/anchor/dist/cjs/utils/token";
import { AUTOMATION_FEE_WALLET } from "../../utils/constants";


export async function withdrawIx(params: {
    program: Program<BasketsProgram>;
    seller: PublicKey;
    basket: PublicKey;
    withdrawStateSeed: number[];
    amountToWithdraw: number;
    destinationMint: PublicKey;
    rebalance: boolean;
}) {
    // Destructure params
    const { program, seller, basket, withdrawStateSeed, amountToWithdraw, destinationMint, rebalance } = params;

    // Get basket token mint
    const basketTokenMint = getBasketTokenMintAccount(basket);

    // Get withdraw state account
    const withdrawState = getWithdrawStateAccount(withdrawStateSeed);

    // Get token accounts
    const sellerBasketTokenAccount = getAta(seller, basketTokenMint);
    const basketWithdrawFeesWallet = getWithdrawFeesWallet(basket);
    const basketWithdrawFeesTokenAccount = getAta(basketWithdrawFeesWallet, basketTokenMint);
    const automationFeeWallet = AUTOMATION_FEE_WALLET;

    // Build and return instruction
    return await program.methods
        .basketSell(
            withdrawStateSeed,
            new BN(amountToWithdraw),
            rebalance ? 1 : 0,
            destinationMint
        )
        .accountsStrict({
            seller,
            basket,
            basketTokenMint,
            sellerBasketTokenAccount,
            withdrawState,
            basketWithdrawFeesWallet,
            basketWithdrawFeesTokenAccount,
            automationFeeWallet,
            systemProgram: SystemProgram.programId,
            tokenProgram: TOKEN_PROGRAM_ID,
            associatedTokenProgram: ASSOCIATED_PROGRAM_ID,
        })
        .instruction();
}
