export abstract class DomainEvent {
  public readonly occurredAt: Date;
  public readonly eventId: string;

  constructor() {
    this.occurredAt = new Date();
    this.eventId = crypto.randomUUID();
  }

  abstract get eventType(): string;
}

export class UserAccountAutoCreatedEvent extends DomainEvent {
  constructor(
    public readonly payload: {
      userId: string;
      accountSequence: string; // 格式: D + YYMMDD + 5位序号
      referralCode: string; // 用户的推荐码（由 identity-service 生成）
      initialDeviceId: string;
      inviterSequence: string | null; // 格式: D + YYMMDD + 5位序号
      registeredAt: Date;
    },
  ) {
    super();
  }

  get eventType(): string {
    return 'UserAccountAutoCreated';
  }
}

export class UserAccountCreatedEvent extends DomainEvent {
  constructor(
    public readonly payload: {
      userId: string;
      accountSequence: string; // 格式: D + YYMMDD + 5位序号
      referralCode: string; // 用户的推荐码（由 identity-service 生成）
      phoneNumber: string | null; // 手机号可能为空（如钱包重试场景）
      initialDeviceId: string;
      inviterSequence: string | null; // 格式: D + YYMMDD + 5位序号
      registeredAt: Date;
    },
  ) {
    super();
  }

  get eventType(): string {
    return 'UserAccountCreated';
  }
}

export class DeviceAddedEvent extends DomainEvent {
  constructor(
    public readonly payload: {
      userId: string;
      accountSequence: string; // 格式: D + YYMMDD + 5位序号
      deviceId: string;
      deviceName: string;
    },
  ) {
    super();
  }

  get eventType(): string {
    return 'DeviceAdded';
  }
}

export class DeviceRemovedEvent extends DomainEvent {
  constructor(public readonly payload: { userId: string; deviceId: string }) {
    super();
  }

  get eventType(): string {
    return 'DeviceRemoved';
  }
}

export class PhoneNumberBoundEvent extends DomainEvent {
  constructor(
    public readonly payload: { userId: string; phoneNumber: string },
  ) {
    super();
  }

  get eventType(): string {
    return 'PhoneNumberBound';
  }
}

export class WalletAddressBoundEvent extends DomainEvent {
  constructor(
    public readonly payload: {
      userId: string;
      chainType: string;
      address: string;
    },
  ) {
    super();
  }

  get eventType(): string {
    return 'WalletAddressBound';
  }
}

export class MultipleWalletAddressesBoundEvent extends DomainEvent {
  constructor(
    public readonly payload: {
      userId: string;
      addresses: Array<{ chainType: string; address: string }>;
    },
  ) {
    super();
  }

  get eventType(): string {
    return 'MultipleWalletAddressesBound';
  }
}

export class KYCSubmittedEvent extends DomainEvent {
  constructor(
    public readonly payload: {
      userId: string;
      realName: string;
      idCardNumber: string;
    },
  ) {
    super();
  }

  get eventType(): string {
    return 'KYCSubmitted';
  }
}

export class KYCVerifiedEvent extends DomainEvent {
  constructor(public readonly payload: { userId: string; accountSequence: string; verifiedAt: Date }) {
    super();
  }

  get eventType(): string {
    return 'KYCVerified';
  }
}

export class KYCRejectedEvent extends DomainEvent {
  constructor(public readonly payload: { userId: string; reason: string }) {
    super();
  }

  get eventType(): string {
    return 'KYCRejected';
  }
}

export class UserAccountFrozenEvent extends DomainEvent {
  constructor(public readonly payload: { userId: string; reason: string }) {
    super();
  }

  get eventType(): string {
    return 'UserAccountFrozen';
  }
}

export class UserAccountDeactivatedEvent extends DomainEvent {
  constructor(
    public readonly payload: { userId: string; deactivatedAt: Date },
  ) {
    super();
  }

  get eventType(): string {
    return 'UserAccountDeactivated';
  }
}

/**
 * 用户资料更新事件
 * 当用户更新昵称或头像时发布
 */
export class UserProfileUpdatedEvent extends DomainEvent {
  constructor(
    public readonly payload: {
      userId: string;
      accountSequence: string;
      nickname: string | null;
      avatarUrl: string | null;
      updatedAt: Date;
    },
  ) {
    super();
  }

  get eventType(): string {
    return 'UserProfileUpdated';
  }
}

/**
 * MPC 密钥生成请求事件
 * 用户创建账户后发布此事件，触发 MPC 服务生成钱包地址
 *
 * payload 格式需要与 mpc-service 的 KeygenRequestedPayload 匹配:
 * - sessionId: 唯一会话ID
 * - userId: 用户ID
 * - accountSequence: 8位账户序列号 (用于关联恢复助记词)
 * - username: 用户名 (用于 mpc-system 标识)
 * - threshold: 签名阈值 (默认 2)
 * - totalParties: 总参与方数 (默认 3)
 * - requireDelegate: 是否需要委托分片 (默认 true)
 */
export class MpcKeygenRequestedEvent extends DomainEvent {
  constructor(
    public readonly payload: {
      sessionId: string;
      userId: string;
      accountSequence: string; // 格式: D + YYMMDD + 5位序号
      username: string;
      threshold: number;
      totalParties: number;
      requireDelegate: boolean;
    },
  ) {
    super();
  }

  get eventType(): string {
    return 'MpcKeygenRequested';
  }
}

// ============ 账户恢复相关事件 ============

/**
 * 账户恢复成功事件 (审计日志)
 */
export class AccountRecoveredEvent extends DomainEvent {
  constructor(
    public readonly payload: {
      userId: string;
      accountSequence: string;
      recoveryMethod: 'mnemonic' | 'phone';
      deviceId: string;
      deviceName?: string;
      ipAddress?: string;
      userAgent?: string;
      recoveredAt: Date;
    },
  ) {
    super();
  }

  get eventType(): string {
    return 'AccountRecovered';
  }
}

/**
 * 账户恢复失败事件 (审计日志)
 */
export class AccountRecoveryFailedEvent extends DomainEvent {
  constructor(
    public readonly payload: {
      accountSequence: string;
      recoveryMethod: 'mnemonic' | 'phone';
      failureReason: string;
      deviceId?: string;
      ipAddress?: string;
      userAgent?: string;
      attemptedAt: Date;
    },
  ) {
    super();
  }

  get eventType(): string {
    return 'AccountRecoveryFailed';
  }
}

/**
 * 助记词挂失事件 (审计日志)
 */
export class MnemonicRevokedEvent extends DomainEvent {
  constructor(
    public readonly payload: {
      userId: string;
      accountSequence: string;
      reason: string;
      revokedAt: Date;
    },
  ) {
    super();
  }

  get eventType(): string {
    return 'MnemonicRevoked';
  }
}

/**
 * 账户解冻事件 (审计日志)
 */
export class AccountUnfrozenEvent extends DomainEvent {
  constructor(
    public readonly payload: {
      userId: string;
      accountSequence: string;
      verifyMethod: 'mnemonic' | 'phone';
      unfrozenAt: Date;
    },
  ) {
    super();
  }

  get eventType(): string {
    return 'AccountUnfrozen';
  }
}

/**
 * 密钥轮换请求事件
 * 触发 MPC 系统进行密钥轮换
 */
export class KeyRotationRequestedEvent extends DomainEvent {
  constructor(
    public readonly payload: {
      sessionId: string;
      userId: string;
      accountSequence: string;
      reason: string;
      requestedAt: Date;
    },
  ) {
    super();
  }

  get eventType(): string {
    return 'KeyRotationRequested';
  }
}
