import { PublicKey } from '@solana/web3.js';
import { BN } from '@coral-xyz/anchor';

/**
 * Program ID for the Merkle Distributor program
 */
export const PROGRAM_ID = new PublicKey('mERKcfxMC5SqJn4Ld4BUris3WKZZ1ojjWJ3A3J5CKxv');

/**
 * Account types
 */
export interface MerkleDistributor {
  bump: number;
  version: BN;
  root: number[];
  mint: PublicKey;
  tokenVault: PublicKey;
  maxTotalClaim: BN;
  maxNumNodes: BN;
  totalAmountClaimed: BN;
  numNodesClaimed: BN;
  startTs: BN;
  endTs: BN;
  clawbackStartTs: BN;
  clawbackReceiver: PublicKey;
  admin: PublicKey;
  clawedBack: boolean;
}

export interface ClaimStatus {
  claimant: PublicKey;
  lockedAmount: BN;
  lockedAmountWithdrawn: BN;
  unlockedAmount: BN;
}

/**
 * Instruction parameter types
 */
export interface NewDistributorParams {
  version: BN;
  root: number[];
  maxTotalClaim: BN;
  maxNumNodes: BN;
  startVestingTs: BN;
  endVestingTs: BN;
  clawbackStartTs: BN;
}

export interface NewClaimParams {
  amountUnlocked: BN;
  amountLocked: BN;
  proof: number[][];
}

/**
 * Event types
 */
export interface NewClaimEvent {
  claimant: PublicKey;
  timestamp: BN;
}

export interface ClaimedEvent {
  claimant: PublicKey;
  amount: BN;
}

/**
 * Error codes
 */
export enum DistributorError {
  InsufficientUnlockedTokens = 6000,
  StartTooFarInFuture = 6001,
  InvalidProof = 6002,
  ExceededMaxClaim = 6003,
  MaxNodesExceeded = 6004,
  Unauthorized = 6005,
  OwnerMismatch = 6006,
  ClawbackDuringVesting = 6007,
  ClawbackBeforeStart = 6008,
  ClawbackAlreadyClaimed = 6009,
  InsufficientClawbackDelay = 6010,
  SameClawbackReceiver = 6011,
  SameAdmin = 6012,
  ClaimExpired = 6013,
  ArithmeticError = 6014,
  StartTimestampAfterEnd = 6015,
  TimestampsNotInFuture = 6016,
  InvalidVersion = 6017,
}

/**
 * Helper types for SDK functions
 */
export interface CreateDistributorArgs {
  mint: PublicKey;
  version: bigint;
  root: Uint8Array;
  maxTotalClaim: bigint;
  maxNumNodes: bigint;
  startVestingTs: bigint;
  endVestingTs: bigint;
  clawbackStartTs: bigint;
  clawbackReceiver: PublicKey;
  admin: PublicKey;
}

export interface ClaimArgs {
  claimant: PublicKey;
  distributor: PublicKey;
  claimantTokenAccount: PublicKey;
  amountUnlocked: bigint;
  amountLocked: bigint;
  proof: Uint8Array[];
}

export interface ClaimLockedArgs {
  claimant: PublicKey;
  distributor: PublicKey;
  claimantTokenAccount: PublicKey;
} 