/**
 * Trading Service 事件定义
 * 这些事件通过 Outbox 模式发布到 Kafka
 */

// ==================== 事件类型常量 ====================

export const TradingEventTypes = {
  // 订单事件
  ORDER_CREATED: 'order.created',
  ORDER_CANCELLED: 'order.cancelled',
  ORDER_COMPLETED: 'order.completed',

  // 成交事件
  TRADE_EXECUTED: 'trade.executed',

  // 转账事件
  TRANSFER_INITIATED: 'transfer.initiated',
  TRANSFER_COMPLETED: 'transfer.completed',
  TRANSFER_FAILED: 'transfer.failed',

  // 销毁事件
  BURN_EXECUTED: 'burn.executed',
  MINUTE_BURN_EXECUTED: 'burn.minute-executed',

  // 价格事件
  PRICE_UPDATED: 'price.updated',

  // 账户事件
  TRADING_ACCOUNT_CREATED: 'trading-account.created',
} as const;

export type TradingEventType =
  (typeof TradingEventTypes)[keyof typeof TradingEventTypes];

// ==================== Kafka Topic 常量 ====================

export const TradingTopics = {
  ORDERS: 'trading.orders',
  TRADES: 'trading.trades',
  TRANSFERS: 'trading.transfers',
  BURNS: 'trading.burns',
  PRICES: 'trading.prices',
  ACCOUNTS: 'trading.accounts',
} as const;

// ==================== 事件 Payload 类型 ====================

/**
 * 订单创建事件
 */
export interface OrderCreatedPayload {
  orderId: string;
  orderNo: string;
  accountSequence: string;
  type: 'BUY' | 'SELL';
  price: string;
  quantity: string;
  createdAt: string;
}

/**
 * 订单取消事件
 */
export interface OrderCancelledPayload {
  orderId: string;
  orderNo: string;
  accountSequence: string;
  type: 'BUY' | 'SELL';
  cancelledQuantity: string;
  cancelledAt: string;
}

/**
 * 订单完成事件
 */
export interface OrderCompletedPayload {
  orderId: string;
  orderNo: string;
  accountSequence: string;
  type: 'BUY' | 'SELL';
  filledQuantity: string;
  averagePrice: string;
  totalAmount: string;
  completedAt: string;
}

/**
 * 成交事件
 */
export interface TradeExecutedPayload {
  tradeId: string;
  tradeNo: string;
  buyOrderId: string;
  sellOrderId: string;
  buyerSequence: string;
  sellerSequence: string;
  price: string;
  quantity: string;
  amount: string;
  burnQuantity: string;
  effectiveQuantity: string;
  createdAt: string;
}

/**
 * 转账发起事件
 */
export interface TransferInitiatedPayload {
  transferId: string;
  transferNo: string;
  accountSequence: string;
  direction: 'IN' | 'OUT';
  amount: string;
  initiatedAt: string;
}

/**
 * 转账完成事件
 */
export interface TransferCompletedPayload {
  transferId: string;
  transferNo: string;
  accountSequence: string;
  direction: 'IN' | 'OUT';
  amount: string;
  miningTxId?: string;
  completedAt: string;
}

/**
 * 转账失败事件
 */
export interface TransferFailedPayload {
  transferId: string;
  transferNo: string;
  accountSequence: string;
  direction: 'IN' | 'OUT';
  amount: string;
  errorMessage: string;
  failedAt: string;
}

/**
 * 销毁执行事件（卖出触发）
 */
export interface BurnExecutedPayload {
  burnRecordId: string;
  sourceType: 'SELL' | 'SCHEDULED';
  sourceAccountSeq?: string;
  sourceOrderNo?: string;
  burnAmount: string;
  burnMultiplier?: string;
  remainingTarget: string;
  executedAt: string;
}

/**
 * 每分钟定时销毁事件
 */
export interface MinuteBurnExecutedPayload {
  burnRecordId: string;
  burnMinute: string;
  burnAmount: string;
  totalBurned: string;
  remainingTarget: string;
  executedAt: string;
}

/**
 * 价格更新事件
 */
export interface PriceUpdatedPayload {
  snapshotId: string;
  price: string;
  greenPoints: string;
  blackHoleAmount: string;
  circulationPool: string;
  effectiveDenominator: string;
  minuteBurnRate: string;
  snapshotTime: string;
}

/**
 * 交易账户创建事件
 */
export interface TradingAccountCreatedPayload {
  accountId: string;
  accountSequence: string;
  createdAt: string;
}

// ==================== 事件基类 ====================

export interface TradingEvent<T = unknown> {
  eventId: string;
  eventType: TradingEventType;
  aggregateType: string;
  aggregateId: string;
  payload: T;
  timestamp: string;
  version: number;
}

// ==================== 辅助函数 ====================

/**
 * 创建标准事件结构
 */
export function createTradingEvent<T>(
  eventType: TradingEventType,
  aggregateType: string,
  aggregateId: string,
  payload: T,
): Omit<TradingEvent<T>, 'eventId'> {
  return {
    eventType,
    aggregateType,
    aggregateId,
    payload,
    timestamp: new Date().toISOString(),
    version: 1,
  };
}
