import {
  clusterApiUrl,
  Connection,
  PublicKey,
  TransactionMessage,
  VersionedTransaction,
} from "@solana/web3.js";
import { PumpAmmSdk } from "../sdk/pumpAmm";
import BN from "bn.js";
import bs58 from "bs58";

describe("syncUserVolumeAccumulator", () => {
  const connection = new Connection(clusterApiUrl("devnet"), "confirmed");
  const sdk = new PumpAmmSdk(connection);
  const user = new PublicKey("4kBH5H5p9oRkZPGLSx8R4WKoDsmXnEpmzsgkebkKvzSg");

  it("should build the instruction successfully", async () => {
    console.log(
      await connection.simulateTransaction(
        new VersionedTransaction(
          new TransactionMessage({
            payerKey: user,
            recentBlockhash: (await connection.getLatestBlockhash()).blockhash,
            instructions: [await sdk.syncUserVolumeAccumulator(user)],
          }).compileToV0Message(),
        ),
      ),
    );
  });

  it("initUserVolumeAccumulator", async () => {
    console.log(
      await connection.simulateTransaction(
        new VersionedTransaction(
          new TransactionMessage({
            payerKey: user,
            recentBlockhash: (await connection.getLatestBlockhash()).blockhash,
            instructions: [
              await sdk.initUserVolumeAccumulator({ payer: user, user }),
            ],
          }).compileToV0Message(),
        ),
      ),
    );
  });

  it("closeUserVolumeAccumulator", async () => {
    console.log(
      await connection.simulateTransaction(
        new VersionedTransaction(
          new TransactionMessage({
            payerKey: user,
            recentBlockhash: (await connection.getLatestBlockhash()).blockhash,
            instructions: [await sdk.closeUserVolumeAccumulator(user)],
          }).compileToV0Message(),
        ),
      ),
    );
  });

  it("buyBaseInput", async () => {
    const connection = new Connection(
      clusterApiUrl("mainnet-beta"),
      "confirmed",
    );
    const sdk = new PumpAmmSdk(connection);

    const pool = new PublicKey("Gf7sXMoP8iRw4iiXmJ1nq4vxcRycbGXy5RL8a8LnTd3v");

    const swapSolanaState = await sdk.swapSolanaState(pool, user);
    const versionedTransaction = new VersionedTransaction(
      new TransactionMessage({
        payerKey: user,
        recentBlockhash: (await connection.getLatestBlockhash()).blockhash,
        instructions: [
          ...(await sdk.buyBaseInput(swapSolanaState, new BN(10), 0.1)),
          ...(await sdk.sellBaseInput(swapSolanaState, new BN(10), 0.1)),
        ],
      }).compileToV0Message(),
    );

    console.log(bs58.encode(versionedTransaction.serialize()));
    console.log(await connection.simulateTransaction(versionedTransaction));
  });

  it("buyBaseInput", async () => {
    const connection = new Connection(
      clusterApiUrl("mainnet-beta"),
      "confirmed",
    );
    const sdk = new PumpAmmSdk(connection);
    const pool = new PublicKey("Gf7sXMoP8iRw4iiXmJ1nq4vxcRycbGXy5RL8a8LnTd3v");
    console.log(
      await connection.simulateTransaction(
        new VersionedTransaction(
          new TransactionMessage({
            payerKey: user,
            recentBlockhash: (await connection.getLatestBlockhash()).blockhash,
            instructions: await sdk.buyBaseInput(
              await sdk.swapSolanaState(pool, user),
              new BN(10),
              10,
            ),
          }).compileToV0Message(),
        ),
      ),
    );
  });
});
