import type { ParsedPayload } from '@pythnetwork/pyth-lazer-sdk';

/**
 * Types mirroring the Aiken Pyth parser (lib/pyth).
 * Use bigint for values that may exceed Number safe integer (2^53 - 1).
 */

export type MarketSession =
  | 'Regular'
  | 'PreMarket'
  | 'PostMarket'
  | 'OverNight'
  | 'Closed';

/** Price-update payload magic (4 bytes). Must match Aiken price_update_magic_le. */
export const PRICE_UPDATE_MAGIC = new Uint8Array([0x75, 0xd3, 0xc7, 0x93]);
/** Pyth message (Solana format) magic (4 bytes). Must match Aiken solana_format_magic_le. */
export const SOLANA_FORMAT_MAGIC = new Uint8Array([0xb9, 0x01, 0x1a, 0x82]);

// Property IDs (must match lib/pyth/pyth.ak feed_property)
export const PROP_ID = {
  Price: 0,
  BestBidPrice: 1,
  BestAskPrice: 2,
  PublisherCount: 3,
  Exponent: 4,
  Confidence: 5,
  FundingRate: 6,
  FundingTimestamp: 7,
  FundingRateInterval: 8,
  MarketSession: 9,
  EmaPrice: 10,
  EmaConfidence: 11,
  FeedUpdateTimestamp: 12,
} as const;

export const MARKET_SESSION_ORDER: MarketSession[] = [
  'Regular',
  'PreMarket',
  'PostMarket',
  'OverNight',
  'Closed',
];

/**
 * Optional<T> = undefined (property not present) | null (explicit None) | T (value)
 * Matches Aiken Option<Option<T>> for feed properties.
 */
export interface Feed {
  feedId: number; // u32
  price?: bigint | null; // 0 encodes as None
  bestBidPrice?: bigint | null;
  bestAskPrice?: bigint | null;
  publisherCount?: number; // u16
  exponent?: number; // i16
  confidence?: bigint | null;
  fundingRate?: bigint | null;
  fundingTimestamp?: bigint | null; // u64
  fundingRateInterval?: bigint | null; // u64
  marketSession?: MarketSession;
  emaPrice?: bigint | null;
  emaConfidence?: bigint | null;
  feedUpdateTimestamp?: bigint | null; // u64
}

/**
 * Price update payload based on the ParsedPayload returned by pyth-lazer-sdk,
 * extended with the channel id used by the on-chain parser.
 */
export interface PriceUpdate extends ParsedPayload {
  /** Channel id (u8) */
  channelId: number;
}

/**
 * Components of a Pyth message (Solana format).
 * To produce a valid on-chain message, payload should be a PriceUpdate payload
 * and signature must be Ed25519 over payload with the given public key.
 */
export interface PythMessageParts {
  /** Ed25519 signature (64 bytes) */
  signature: Uint8Array;
  /** Ed25519 public key (32 bytes) */
  publicKey: Uint8Array;
  /** Payload bytes (e.g. encoded PriceUpdate) */
  payload: Uint8Array;
}
