/**
 * Pacifica平台 Ed25519 签名适配器
 * 基于Solana区块链的永续合约DEX签名实现
 */

import * as nacl from 'tweetnacl'
import bs58 from 'bs58'
import { SignatureAdapter, SignatureResult, PacificaSignData, ErrorCode } from '../../shared/credential-types'
import { PACIFICA_CONFIG } from '../../shared/credential-constants'
import { createApiError, formatTimestamp, PerformanceTimer, secureClear } from '../../shared/credential-utils'

/**
 * Pacifica凭据接口
 */
interface PacificaCredentials {
  privateKey: string // base58编码的私钥
}

/**
 * Pacifica Ed25519 签名适配器实现
 */
export class PacificaSignatureAdapter implements SignatureAdapter {
  readonly platformId = 'pacifica'
  readonly algorithm = 'ed25519'

  /**
   * 执行Ed25519签名
   */
  async sign(data: PacificaSignData, credentials: PacificaCredentials): Promise<SignatureResult> {
    const timer = new PerformanceTimer()

    try {
      // 验证输入参数
      this._validateSignData(data)
      this._validateCredentials(credentials)

      // 解码私钥
      const privateKeyBuffer = this._decodePrivateKey(credentials.privateKey)

      // 序列化签名数据
      const messageBuffer = this._serializeSignData(data)

      // 执行Ed25519签名
      const signature = nacl.sign.detached(messageBuffer, privateKeyBuffer)

      // 派生公钥
      const keyPair = nacl.sign.keyPair.fromSecretKey(privateKeyBuffer)
      const publicKey = bs58.encode(keyPair.publicKey)

      // 清理敏感数据
      secureClear(privateKeyBuffer)
      secureClear(keyPair.secretKey)

      const signatureBase58 = bs58.encode(signature)
      const elapsedMs = timer.elapsed()

      console.log(`✅ [PacificaAdapter] Ed25519签名完成: ${elapsedMs.toFixed(1)}ms`)

      return {
        signature: signatureBase58,
        algorithm: 'ed25519',
        encoding: 'base58',
        publicKey,
        signedAt: formatTimestamp(),
        metadata: {
          executionTimeMs: elapsedMs,
          dataType: data.instruction?.type || 'unknown',
          signatureLength: signature.length,
          publicKeyLength: keyPair.publicKey.length,
        },
      }
    } catch (error) {
      const elapsedMs = timer.elapsed()
      console.error(`❌ [PacificaAdapter] 签名失败 (${elapsedMs.toFixed(1)}ms):`, error)

      throw createApiError(ErrorCode.SIGNATURE_FAILED, {
        platform: 'pacifica',
        algorithm: 'ed25519',
        error: error instanceof Error ? error.message : String(error),
        executionTimeMs: elapsedMs,
      })
    }
  }

  /**
   * 验证Ed25519签名（可选实现）
   */
  async verify(signature: string, data: PacificaSignData, publicKey: string): Promise<boolean> {
    try {
      const signatureBuffer = bs58.decode(signature)
      const publicKeyBuffer = bs58.decode(publicKey)
      const messageBuffer = this._serializeSignData(data)

      return nacl.sign.detached.verify(messageBuffer, signatureBuffer, publicKeyBuffer)
    } catch (error) {
      console.error(`❌ [PacificaAdapter] 签名验证失败:`, error)
      return false
    }
  }

  /**
   * 从私钥派生公钥
   */
  derivePublicKey(privateKey: string): string {
    try {
      const privateKeyBuffer = this._decodePrivateKey(privateKey)
      const keyPair = nacl.sign.keyPair.fromSecretKey(privateKeyBuffer)
      const publicKey = bs58.encode(keyPair.publicKey)

      // 清理敏感数据
      secureClear(privateKeyBuffer)
      secureClear(keyPair.secretKey)

      return publicKey
    } catch (error) {
      throw createApiError(ErrorCode.INVALID_DATA_FORMAT, {
        reason: 'Failed to derive public key',
        error: error instanceof Error ? error.message : String(error),
      })
    }
  }

  /**
   * 私有方法：验证签名数据格式
   */
  private _validateSignData(data: PacificaSignData): void {
    if (!data || typeof data !== 'object') {
      throw new Error('签名数据必须是对象')
    }

    if (!data.instruction || typeof data.instruction !== 'object') {
      throw new Error('签名数据缺少instruction字段')
    }

    if (!data.instruction.type || typeof data.instruction.type !== 'string') {
      throw new Error('instruction.type字段是必需的')
    }

    // 验证支持的订单类型
    if (!PACIFICA_CONFIG.SUPPORTED_ORDER_TYPES.includes(data.instruction.type)) {
      console.warn(`⚠️ [PacificaAdapter] 未知的订单类型: ${data.instruction.type}`)
    }

    // 验证nonce字段（可选）
    if (data.nonce !== undefined && (!Number.isInteger(data.nonce) || data.nonce < 0)) {
      throw new Error('nonce必须是非负整数')
    }
  }

  /**
   * 私有方法：验证凭据格式
   */
  private _validateCredentials(credentials: PacificaCredentials): void {
    if (!credentials || typeof credentials !== 'object') {
      throw new Error('凭据必须是对象')
    }

    if (!credentials.privateKey || typeof credentials.privateKey !== 'string') {
      throw new Error('privateKey字段是必需的')
    }

    // 验证base58私钥格式
    if (credentials.privateKey.length !== PACIFICA_CONFIG.BASE58_PRIVATE_KEY_LENGTH) {
      throw new Error(`私钥长度必须是${PACIFICA_CONFIG.BASE58_PRIVATE_KEY_LENGTH}字符`)
    }

    try {
      const decoded = bs58.decode(credentials.privateKey)
      if (decoded.length !== 64) {
        // Ed25519私钥+公钥 = 32+32 = 64字节
        throw new Error('无效的Ed25519私钥格式')
      }
    } catch (error) {
      throw new Error('私钥base58解码失败')
    }
  }

  /**
   * 私有方法：解码base58私钥
   */
  private _decodePrivateKey(privateKeyBase58: string): Uint8Array {
    try {
      return bs58.decode(privateKeyBase58)
    } catch (error) {
      throw new Error(`私钥base58解码失败: ${error instanceof Error ? error.message : String(error)}`)
    }
  }

  /**
   * 私有方法：序列化签名数据
   * 将Pacifica订单数据转换为可签名的字节序列
   */
  private _serializeSignData(data: PacificaSignData): Uint8Array {
    try {
      // 创建标准化的签名消息
      const message = {
        instruction: data.instruction,
        nonce: data.nonce || Date.now(), // 如果没有nonce，使用当前时间戳
      }

      // 将对象转换为JSON字符串，确保字段顺序一致
      const jsonString = JSON.stringify(message, Object.keys(message).sort())

      // 转换为UTF-8字节数组
      return new TextEncoder().encode(jsonString)
    } catch (error) {
      throw new Error(`签名数据序列化失败: ${error instanceof Error ? error.message : String(error)}`)
    }
  }

  /**
   * 获取适配器信息
   */
  getInfo() {
    return {
      platformId: this.platformId,
      algorithm: this.algorithm,
      supportedOrderTypes: PACIFICA_CONFIG.SUPPORTED_ORDER_TYPES,
      keyFormat: 'base58',
      signatureFormat: 'base58',
      maxSignatureTime: '50ms',
    }
  }
}
