/**
 * 账户模型实现
 *
 * 提供账户信息的封装和验证功能
 */

import { Account, Platform, Credentials, AccountStatus, CredentialManagerError, ErrorType } from './types';

/**
 * 账户实体类
 */
export class AccountEntity implements Account {
  public readonly id: string;
  public readonly platform: Platform;
  public readonly credentials: Credentials;
  public status: AccountStatus;
  public readonly metadata?: Record<string, any>;

  constructor(config: {
    id: string;
    platform: Platform;
    credentials: Credentials;
    metadata?: Record<string, any>;
  }) {
    this.validateAccountConfig(config);

    this.id = config.id;
    this.platform = config.platform;
    this.credentials = config.credentials;
    this.metadata = config.metadata!;
    this.status = AccountStatus.LOADING;
  }

  /**
   * 验证账户配置
   */
  private validateAccountConfig(config: {
    id: string;
    platform: Platform;
    credentials: Credentials;
  }): void {
    // 验证账户ID
    if (!config.id || typeof config.id !== 'string' || config.id.trim().length === 0) {
      throw new CredentialManagerError(
        'Account ID must be a non-empty string',
        ErrorType.VALIDATION_ERROR,
        { field: 'id', value: config.id }
      );
    }

    // 验证平台
    if (!Object.values(Platform).includes(config.platform)) {
      throw new CredentialManagerError(
        `Invalid platform: ${config.platform}`,
        ErrorType.VALIDATION_ERROR,
        { field: 'platform', value: config.platform }
      );
    }

    // 验证凭证
    this.validateCredentials(config.credentials, config.platform);
  }

  /**
   * 验证凭证信息
   */
  private validateCredentials(credentials: Credentials, platform: Platform): void {
    if (!credentials || typeof credentials !== 'object') {
      throw new CredentialManagerError(
        'Credentials must be a valid object',
        ErrorType.VALIDATION_ERROR,
        { credentials }
      );
    }

    // 验证凭证类型与平台匹配
    const expectedType = platform.toLowerCase();
    if (credentials.type !== expectedType) {
      throw new CredentialManagerError(
        `Credential type '${credentials.type}' does not match platform '${platform}'`,
        ErrorType.VALIDATION_ERROR,
        { credentialType: credentials.type, platform }
      );
    }

    // 平台特定验证
    switch (platform) {
      case Platform.PACIFICA:
        this.validatePacificaCredentials(credentials as any);
        break;
      case Platform.ASTER:
        this.validateAsterCredentials(credentials as any);
        break;
      case Platform.BINANCE:
        this.validateBinanceCredentials(credentials as any);
        break;
      default:
        throw new CredentialManagerError(
          `Unsupported platform: ${platform}`,
          ErrorType.VALIDATION_ERROR,
          { platform }
        );
    }
  }

  /**
   * 验证Pacifica凭证
   */
  private validatePacificaCredentials(credentials: { privateKey: string }): void {
    if (!credentials.privateKey || typeof credentials.privateKey !== 'string') {
      throw new CredentialManagerError(
        'Pacifica credentials must include a valid privateKey',
        ErrorType.VALIDATION_ERROR,
        { field: 'privateKey' }
      );
    }

    // 验证Ed25519私钥格式（64字符十六进制）
    const privateKeyRegex = /^[0-9a-fA-F]{64}$/;
    if (!privateKeyRegex.test(credentials.privateKey)) {
      throw new CredentialManagerError(
        'Pacifica privateKey must be a 64-character hexadecimal string',
        ErrorType.VALIDATION_ERROR,
        { privateKey: credentials.privateKey.substring(0, 10) + '...' }
      );
    }
  }

  /**
   * 验证Aster凭证
   */
  private validateAsterCredentials(credentials: { privateKey: string }): void {
    if (!credentials.privateKey || typeof credentials.privateKey !== 'string') {
      throw new CredentialManagerError(
        'Aster credentials must include a valid privateKey',
        ErrorType.VALIDATION_ERROR,
        { field: 'privateKey' }
      );
    }

    // 验证以太坊私钥格式（0x前缀 + 64字符十六进制）
    const ethPrivateKeyRegex = /^0x[0-9a-fA-F]{64}$/i;
    if (!ethPrivateKeyRegex.test(credentials.privateKey)) {
      throw new CredentialManagerError(
        'Aster privateKey must be a valid Ethereum private key (0x + 64 hex characters)',
        ErrorType.VALIDATION_ERROR,
        { privateKey: credentials.privateKey.substring(0, 10) + '...' }
      );
    }
  }

  /**
   * 验证Binance凭证
   */
  private validateBinanceCredentials(credentials: { apiKey: string; secretKey: string }): void {
    if (!credentials.apiKey || typeof credentials.apiKey !== 'string') {
      throw new CredentialManagerError(
        'Binance credentials must include a valid apiKey',
        ErrorType.VALIDATION_ERROR,
        { field: 'apiKey' }
      );
    }

    if (!credentials.secretKey || typeof credentials.secretKey !== 'string') {
      throw new CredentialManagerError(
        'Binance credentials must include a valid secretKey',
        ErrorType.VALIDATION_ERROR,
        { field: 'secretKey' }
      );
    }

    // 基本长度验证
    if (credentials.apiKey.trim().length === 0) {
      throw new CredentialManagerError(
        'Binance apiKey cannot be empty',
        ErrorType.VALIDATION_ERROR,
        { field: 'apiKey' }
      );
    }

    if (credentials.secretKey.trim().length === 0) {
      throw new CredentialManagerError(
        'Binance secretKey cannot be empty',
        ErrorType.VALIDATION_ERROR,
        { field: 'secretKey' }
      );
    }
  }

  /**
   * 设置账户状态
   */
  public setStatus(status: AccountStatus): void {
    this.status = status;
  }

  /**
   * 检查账户是否处于活跃状态
   */
  public isActive(): boolean {
    return this.status === AccountStatus.ACTIVE;
  }

  /**
   * 获取账户的安全信息（隐藏敏感数据）
   */
  public toSafeObject(): Omit<Account, 'credentials'> & { credentialsType: string } {
    return {
      id: this.id,
      platform: this.platform,
      status: this.status,
      metadata: this.metadata,
      credentialsType: this.credentials.type,
    };
  }

  /**
   * 克隆账户（深拷贝）
   */
  public clone(): AccountEntity {
    return new AccountEntity({
      id: this.id,
      platform: this.platform,
      credentials: JSON.parse(JSON.stringify(this.credentials)),
      metadata: this.metadata ? JSON.parse(JSON.stringify(this.metadata)) : undefined,
    });
  }

  /**
   * 比较两个账户是否相等
   */
  public equals(other: Account): boolean {
    return (
      this.id === other.id &&
      this.platform === other.platform &&
      JSON.stringify(this.credentials) === JSON.stringify(other.credentials)
    );
  }

  /**
   * 获取账户的字符串表示
   */
  public toString(): string {
    return `Account(id=${this.id}, platform=${this.platform}, status=${this.status})`;
  }
}

/**
 * 账户工厂函数
 */
export function createAccount(config: {
  id: string;
  platform: Platform;
  credentials: Credentials;
  metadata?: Record<string, any>;
}): AccountEntity {
  return new AccountEntity(config);
}

/**
 * 从配置创建账户
 */
export function createAccountFromConfig(config: any): AccountEntity {
  if (!config || typeof config !== 'object') {
    throw new CredentialManagerError(
      'Account config must be a valid object',
      ErrorType.VALIDATION_ERROR,
      { config }
    );
  }

  // 转换平台字符串为枚举
  let platform: Platform;
  if (typeof config.platform === 'string') {
    const platformValue = config.platform.toLowerCase();
    switch (platformValue) {
      case 'pacifica':
        platform = Platform.PACIFICA;
        break;
      case 'aster':
        platform = Platform.ASTER;
        break;
      case 'binance':
        platform = Platform.BINANCE;
        break;
      default:
        throw new CredentialManagerError(
          `Unsupported platform: ${config.platform}`,
          ErrorType.VALIDATION_ERROR,
          { platform: config.platform }
        );
    }
  } else {
    throw new CredentialManagerError(
      'Platform must be a valid string',
      ErrorType.VALIDATION_ERROR,
      { platform: config.platform }
    );
  }

  return new AccountEntity({
    id: config.id,
    platform,
    credentials: config.credentials,
    metadata: config.metadata,
  });
}
