import { Injectable, Logger, OnModuleInit } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { Prisma } from '@prisma/client';
import { PrismaService } from '../persistence/prisma/prisma.service';
import {
  CdcConsumerService,
  CdcEvent,
  ServiceEvent,
  ServiceEventHandler,
  TransactionalServiceEventHandler,
} from './cdc-consumer.service';
import { WalletSyncHandlers } from './wallet-sync.handlers';

/** Prisma 事务客户端类型 */
type TransactionClient = Prisma.TransactionClient;

/**
 * CDC 同步服务
 * 负责从各个 2.0 服务同步数据到 mining-admin-service
 *
 * 实现100%可靠的事务性幂等消费模式：
 * 1. 使用数据库事务保证原子性
 * 2. 在同一事务中：检查幂等键 → 记录幂等键 → 执行业务逻辑
 * 3. 任何步骤失败都会回滚，保证数据一致性
 */
@Injectable()
export class CdcSyncService implements OnModuleInit {
  private readonly logger = new Logger(CdcSyncService.name);

  constructor(
    private readonly configService: ConfigService,
    private readonly prisma: PrismaService,
    private readonly cdcConsumer: CdcConsumerService,
    private readonly walletHandlers: WalletSyncHandlers,
  ) {}

  async onModuleInit() {
    await this.registerHandlers();
    await this.cdcConsumer.start();
  }

  /**
   * 事务性幂等包装器 - 100%保证 exactly-once 语义
   *
   * 在同一个数据库事务中完成：
   * 1. 检查事件是否已处理（使用 SELECT FOR UPDATE 防止并发）
   * 2. 先插入幂等记录（如果已存在则事务失败回滚）
   * 3. 执行业务逻辑
   *
   * 任何步骤失败都会回滚整个事务，保证数据一致性
   */
  private withIdempotency(handler: TransactionalServiceEventHandler): ServiceEventHandler {
    return async (event: ServiceEvent) => {
      const idempotencyKey = `${event.sourceTopic}:${event.id}`;

      try {
        await this.prisma.$transaction(async (tx) => {
          // 1. 尝试插入幂等记录（使用唯一约束防止重复）
          // 如果记录已存在，会抛出唯一约束冲突异常
          try {
            await tx.processedEvent.create({
              data: {
                eventId: event.id,
                eventType: event.eventType,
                sourceService: event.sourceTopic,
              },
            });
          } catch (error: any) {
            // 唯一约束冲突 = 事件已处理，直接返回（不执行业务逻辑）
            if (error.code === 'P2002') {
              this.logger.debug(`Skipping duplicate event: ${idempotencyKey} (${event.eventType})`);
              return;
            }
            throw error;
          }

          // 2. 执行业务逻辑（传入事务客户端）
          await handler(event, tx);

          this.logger.debug(`Processed event in transaction: ${idempotencyKey} (${event.eventType})`);
        }, {
          // 设置事务隔离级别为 Serializable，防止并发问题
          isolationLevel: Prisma.TransactionIsolationLevel.Serializable,
          timeout: 30000, // 30秒超时
        });
      } catch (error: any) {
        // 唯一约束冲突在事务外也可能发生（并发场景）
        if (error.code === 'P2002') {
          this.logger.debug(`Skipping duplicate event (concurrent): ${idempotencyKey}`);
          return;
        }
        this.logger.error(`Failed to process event: ${idempotencyKey}`, error);
        throw error;
      }
    };
  }

  private async registerHandlers(): Promise<void> {
    // ===========================================================================
    // 从 auth-service 同步用户数据 (通过 Debezium CDC 监听 outbox_events 表)
    // ===========================================================================
    const usersTopic = this.configService.get<string>(
      'CDC_TOPIC_AUTH_OUTBOX',
      'cdc.auth.outbox',
    );
    this.cdcConsumer.addTopic(usersTopic);
    this.cdcConsumer.registerServiceHandler(
      'UserCreated',
      this.withIdempotency(this.handleUserCreated.bind(this)),
    );
    // auth-service 发布的 user.registered 事件
    this.cdcConsumer.registerServiceHandler(
      'user.registered',
      this.withIdempotency(this.handleUserRegistered.bind(this)),
    );
    this.cdcConsumer.registerServiceHandler(
      'UserUpdated',
      this.withIdempotency(this.handleUserUpdated.bind(this)),
    );
    this.cdcConsumer.registerServiceHandler(
      'KycStatusChanged',
      this.withIdempotency(this.handleKycStatusChanged.bind(this)),
    );
    // auth-service 发布的 user.kyc_verified 事件
    this.cdcConsumer.registerServiceHandler(
      'user.kyc_verified',
      this.withIdempotency(this.handleKycStatusChanged.bind(this)),
    );
    // auth-service 发布的 user.legacy.migrated 事件 (1.0用户首次登录2.0时)
    this.cdcConsumer.registerServiceHandler(
      'user.legacy.migrated',
      this.withIdempotency(this.handleLegacyUserMigrated.bind(this)),
    );

    // ===========================================================================
    // 从 contribution-service 同步算力数据 (通过 Debezium CDC 监听 outbox_events 表)
    // ===========================================================================
    const contributionTopic = this.configService.get<string>(
      'CDC_TOPIC_CONTRIBUTION_OUTBOX',
      'cdc.contribution.outbox',
    );
    this.cdcConsumer.addTopic(contributionTopic);
    this.cdcConsumer.registerServiceHandler(
      'ContributionAccountUpdated',
      this.withIdempotency(this.handleContributionAccountUpdated.bind(this)),
    );
    // ContributionAccountSynced 用于初始全量同步
    this.cdcConsumer.registerServiceHandler(
      'ContributionAccountSynced',
      this.withIdempotency(this.handleContributionAccountUpdated.bind(this)),
    );
    // ContributionCalculated 事件在算力计算完成时发布
    this.cdcConsumer.registerServiceHandler(
      'ContributionCalculated',
      this.withIdempotency(this.handleContributionCalculated.bind(this)),
    );
    this.cdcConsumer.registerServiceHandler(
      'SystemContributionUpdated',
      this.withIdempotency(this.handleSystemContributionUpdated.bind(this)),
    );
    // SystemAccountSynced 事件 - 同步系统账户算力（来自 contribution-service）
    this.cdcConsumer.registerServiceHandler(
      'SystemAccountSynced',
      this.withIdempotency(this.handleSystemAccountSynced.bind(this)),
    );
    // SystemContributionRecordCreated 事件 - 同步系统账户算力明细（来自 contribution-service）
    this.cdcConsumer.registerServiceHandler(
      'SystemContributionRecordCreated',
      this.withIdempotency(this.handleSystemContributionRecordCreated.bind(this)),
    );
    // ReferralSynced 事件 - 同步推荐关系
    this.cdcConsumer.registerServiceHandler(
      'ReferralSynced',
      this.withIdempotency(this.handleReferralSynced.bind(this)),
    );
    // AdoptionSynced 事件 - 同步认种记录
    this.cdcConsumer.registerServiceHandler(
      'AdoptionSynced',
      this.withIdempotency(this.handleAdoptionSynced.bind(this)),
    );
    // ContributionRecordSynced 事件 - 同步算力明细记录
    this.cdcConsumer.registerServiceHandler(
      'ContributionRecordSynced',
      this.withIdempotency(this.handleContributionRecordSynced.bind(this)),
    );
    // NetworkProgressUpdated 事件 - 同步全网算力进度
    this.cdcConsumer.registerServiceHandler(
      'NetworkProgressUpdated',
      this.withIdempotency(this.handleNetworkProgressUpdated.bind(this)),
    );

    // ===========================================================================
    // 从 mining-service 同步挖矿数据 (通过 Debezium CDC 监听 outbox_events 表)
    // ===========================================================================
    const miningTopic = this.configService.get<string>(
      'CDC_TOPIC_MINING_OUTBOX',
      'cdc.mining.outbox',
    );
    this.cdcConsumer.addTopic(miningTopic);
    this.cdcConsumer.registerServiceHandler(
      'MiningAccountUpdated',
      this.withIdempotency(this.handleMiningAccountUpdated.bind(this)),
    );
    this.cdcConsumer.registerServiceHandler(
      'MiningConfigUpdated',
      this.withIdempotency(this.handleMiningConfigUpdated.bind(this)),
    );
    this.cdcConsumer.registerServiceHandler(
      'DailyMiningStatCreated',
      this.withIdempotency(this.handleDailyMiningStatCreated.bind(this)),
    );

    // ===========================================================================
    // 从 trading-service 同步交易数据 (通过 Debezium CDC 监听 outbox_events 表)
    // ===========================================================================
    const tradingTopic = this.configService.get<string>(
      'CDC_TOPIC_TRADING_OUTBOX',
      'cdc.trading.outbox',
    );
    this.cdcConsumer.addTopic(tradingTopic);
    this.cdcConsumer.registerServiceHandler(
      'TradingAccountUpdated',
      this.withIdempotency(this.handleTradingAccountUpdated.bind(this)),
    );
    this.cdcConsumer.registerServiceHandler(
      'DayKLineCreated',
      this.withIdempotency(this.handleDayKLineCreated.bind(this)),
    );
    this.cdcConsumer.registerServiceHandler(
      'CirculationPoolUpdated',
      this.withIdempotency(this.handleCirculationPoolUpdated.bind(this)),
    );


    // ===========================================================================
    // 从 mining-wallet-service 同步钱包数据 (通过 Debezium CDC 监听 outbox_events 表)
    // ===========================================================================
    const walletTopic = this.configService.get<string>(
      'CDC_TOPIC_WALLET_OUTBOX',
      'cdc.mining-wallet.outbox',
    );
    this.cdcConsumer.addTopic(walletTopic);

    // 区域数据
    this.cdcConsumer.registerServiceHandler(
      'ProvinceCreated',
      this.withIdempotency(this.walletHandlers.handleProvinceCreated.bind(this.walletHandlers)),
    );
    this.cdcConsumer.registerServiceHandler(
      'ProvinceUpdated',
      this.withIdempotency(this.walletHandlers.handleProvinceUpdated.bind(this.walletHandlers)),
    );
    this.cdcConsumer.registerServiceHandler(
      'CityCreated',
      this.withIdempotency(this.walletHandlers.handleCityCreated.bind(this.walletHandlers)),
    );
    this.cdcConsumer.registerServiceHandler(
      'CityUpdated',
      this.withIdempotency(this.walletHandlers.handleCityUpdated.bind(this.walletHandlers)),
    );
    this.cdcConsumer.registerServiceHandler(
      'UserRegionMappingCreated',
      this.withIdempotency(this.walletHandlers.handleUserRegionMappingCreated.bind(this.walletHandlers)),
    );
    this.cdcConsumer.registerServiceHandler(
      'UserRegionMappingUpdated',
      this.withIdempotency(this.walletHandlers.handleUserRegionMappingUpdated.bind(this.walletHandlers)),
    );

    // 系统账户
    this.cdcConsumer.registerServiceHandler(
      'WalletSystemAccountCreated',
      this.withIdempotency(this.walletHandlers.handleWalletSystemAccountCreated.bind(this.walletHandlers)),
    );
    this.cdcConsumer.registerServiceHandler(
      'WalletSystemAccountUpdated',
      this.withIdempotency(this.walletHandlers.handleWalletSystemAccountUpdated.bind(this.walletHandlers)),
    );

    // 池账户
    this.cdcConsumer.registerServiceHandler(
      'WalletPoolAccountCreated',
      this.withIdempotency(this.walletHandlers.handleWalletPoolAccountCreated.bind(this.walletHandlers)),
    );
    this.cdcConsumer.registerServiceHandler(
      'WalletPoolAccountUpdated',
      this.withIdempotency(this.walletHandlers.handleWalletPoolAccountUpdated.bind(this.walletHandlers)),
    );

    // 用户钱包
    this.cdcConsumer.registerServiceHandler(
      'UserWalletCreated',
      this.withIdempotency(this.walletHandlers.handleUserWalletCreated.bind(this.walletHandlers)),
    );
    this.cdcConsumer.registerServiceHandler(
      'UserWalletUpdated',
      this.withIdempotency(this.walletHandlers.handleUserWalletUpdated.bind(this.walletHandlers)),
    );

    // 提现请求
    this.cdcConsumer.registerServiceHandler(
      'WithdrawRequestCreated',
      this.withIdempotency(this.walletHandlers.handleWithdrawRequestCreated.bind(this.walletHandlers)),
    );
    this.cdcConsumer.registerServiceHandler(
      'WithdrawRequestUpdated',
      this.withIdempotency(this.walletHandlers.handleWithdrawRequestUpdated.bind(this.walletHandlers)),
    );

    // 充值记录
    this.cdcConsumer.registerServiceHandler(
      'DepositRecordCreated',
      this.withIdempotency(this.walletHandlers.handleDepositRecordCreated.bind(this.walletHandlers)),
    );
    this.cdcConsumer.registerServiceHandler(
      'DepositRecordUpdated',
      this.withIdempotency(this.walletHandlers.handleDepositRecordUpdated.bind(this.walletHandlers)),
    );

    // DEX Swap
    this.cdcConsumer.registerServiceHandler(
      'DexSwapRecordCreated',
      this.withIdempotency(this.walletHandlers.handleDexSwapRecordCreated.bind(this.walletHandlers)),
    );
    this.cdcConsumer.registerServiceHandler(
      'DexSwapRecordUpdated',
      this.withIdempotency(this.walletHandlers.handleDexSwapRecordUpdated.bind(this.walletHandlers)),
    );

    // 地址绑定
    this.cdcConsumer.registerServiceHandler(
      'BlockchainAddressBindingCreated',
      this.withIdempotency(this.walletHandlers.handleBlockchainAddressBindingCreated.bind(this.walletHandlers)),
    );
    this.cdcConsumer.registerServiceHandler(
      'BlockchainAddressBindingUpdated',
      this.withIdempotency(this.walletHandlers.handleBlockchainAddressBindingUpdated.bind(this.walletHandlers)),
    );

    // 黑洞合约
    this.cdcConsumer.registerServiceHandler(
      'BlackHoleContractCreated',
      this.withIdempotency(this.walletHandlers.handleBlackHoleContractCreated.bind(this.walletHandlers)),
    );
    this.cdcConsumer.registerServiceHandler(
      'BlackHoleContractUpdated',
      this.withIdempotency(this.walletHandlers.handleBlackHoleContractUpdated.bind(this.walletHandlers)),
    );

    // 销毁记录
    this.cdcConsumer.registerServiceHandler(
      'BurnToBlackHoleRecordCreated',
      this.withIdempotency(this.walletHandlers.handleBurnToBlackHoleRecordCreated.bind(this.walletHandlers)),
    );

    // 费率配置
    this.cdcConsumer.registerServiceHandler(
      'FeeConfigCreated',
      this.withIdempotency(this.walletHandlers.handleFeeConfigCreated.bind(this.walletHandlers)),
    );
    this.cdcConsumer.registerServiceHandler(
      'FeeConfigUpdated',
      this.withIdempotency(this.walletHandlers.handleFeeConfigUpdated.bind(this.walletHandlers)),
    );

    // CONTRIBUTION_CREDITED 事件 - 贡献值入账时更新用户钱包
    this.cdcConsumer.registerServiceHandler(
      'CONTRIBUTION_CREDITED',
      this.withIdempotency(this.handleContributionCredited.bind(this)),
    );

    this.logger.log('CDC sync handlers registered with idempotency protection');
  }

  // ===========================================================================
  // 用户事件处理
  // ===========================================================================

  private async handleUserCreated(event: ServiceEvent, tx: TransactionClient): Promise<void> {
    const { payload } = event;
    await tx.syncedUser.upsert({
      where: { originalUserId: payload.id },
      create: {
        originalUserId: payload.id,
        accountSequence: payload.accountSequence,
        phone: payload.phone,
        status: payload.status || 'ACTIVE',
        kycStatus: payload.kycStatus || 'PENDING',
        realName: payload.realName,
        isLegacyUser: payload.isLegacyUser || false,
        createdAt: new Date(payload.createdAt),
      },
      update: {
        phone: payload.phone,
        status: payload.status || 'ACTIVE',
        kycStatus: payload.kycStatus || 'PENDING',
        realName: payload.realName,
      },
    });
  }

  /**
   * 处理 auth-service 发布的 user.registered 事件
   * payload: { accountSequence, phone, source, registeredAt }
   */
  private async handleUserRegistered(event: ServiceEvent, tx: TransactionClient): Promise<void> {
    const { payload } = event;
    await tx.syncedUser.upsert({
      where: { accountSequence: payload.accountSequence },
      create: {
        originalUserId: payload.accountSequence,
        accountSequence: payload.accountSequence,
        phone: payload.phone,
        status: 'ACTIVE',
        kycStatus: 'PENDING',
        realName: null,
        isLegacyUser: payload.source === 'V1',
        createdAt: new Date(payload.registeredAt),
      },
      update: {
        phone: payload.phone,
        isLegacyUser: payload.source === 'V1',
      },
    });
  }

  /**
   * 处理 auth-service 发布的 user.legacy.migrated 事件
   * payload: { accountSequence, phone, nickname, migratedAt }
   */
  private async handleLegacyUserMigrated(event: ServiceEvent, tx: TransactionClient): Promise<void> {
    const { payload } = event;
    await tx.syncedUser.upsert({
      where: { accountSequence: payload.accountSequence },
      create: {
        originalUserId: payload.accountSequence,
        accountSequence: payload.accountSequence,
        phone: payload.phone,
        nickname: payload.nickname || null,
        status: 'ACTIVE',
        kycStatus: 'PENDING',
        realName: null,
        isLegacyUser: true,
        createdAt: new Date(payload.migratedAt),
      },
      update: {
        phone: payload.phone,
        nickname: payload.nickname || null,
        isLegacyUser: true,
      },
    });
  }

  private async handleUserUpdated(event: ServiceEvent, tx: TransactionClient): Promise<void> {
    const { payload } = event;
    await tx.syncedUser.updateMany({
      where: { originalUserId: payload.id },
      data: {
        phone: payload.phone,
        status: payload.status,
        kycStatus: payload.kycStatus,
        realName: payload.realName,
      },
    });
  }

  private async handleKycStatusChanged(event: ServiceEvent, tx: TransactionClient): Promise<void> {
    const { payload } = event;
    await tx.syncedUser.updateMany({
      where: { accountSequence: payload.accountSequence },
      data: {
        kycStatus: payload.kycStatus,
        realName: payload.realName,
      },
    });
  }

  // ===========================================================================
  // 算力账户事件处理
  // ===========================================================================

  private async handleContributionAccountUpdated(event: ServiceEvent, tx: TransactionClient): Promise<void> {
    const { payload } = event;
    await tx.syncedContributionAccount.upsert({
      where: { accountSequence: payload.accountSequence },
      create: {
        accountSequence: payload.accountSequence,
        personalContribution: payload.personalContribution || 0,
        teamLevelContribution: payload.teamLevelContribution || 0,
        teamBonusContribution: payload.teamBonusContribution || 0,
        totalContribution: payload.totalContribution || 0,
        effectiveContribution: payload.effectiveContribution || 0,
        hasAdopted: payload.hasAdopted || false,
        directReferralCount: payload.directReferralAdoptedCount || 0,
        unlockedLevelDepth: payload.unlockedLevelDepth || 0,
        unlockedBonusTiers: payload.unlockedBonusTiers || 0,
      },
      update: {
        personalContribution: payload.personalContribution,
        teamLevelContribution: payload.teamLevelContribution,
        teamBonusContribution: payload.teamBonusContribution,
        totalContribution: payload.totalContribution,
        effectiveContribution: payload.effectiveContribution,
        hasAdopted: payload.hasAdopted,
        directReferralCount: payload.directReferralAdoptedCount,
        unlockedLevelDepth: payload.unlockedLevelDepth,
        unlockedBonusTiers: payload.unlockedBonusTiers,
      },
    });
  }

  /**
   * 处理 ContributionCalculated 事件
   * contribution-service 在计算算力时发布，触发增量更新
   */
  private async handleContributionCalculated(event: ServiceEvent, tx: TransactionClient): Promise<void> {
    const { payload } = event;
    await tx.syncedContributionAccount.upsert({
      where: { accountSequence: payload.accountSequence },
      create: {
        accountSequence: payload.accountSequence,
        personalContribution: payload.personalContribution || 0,
        teamLevelContribution: 0,
        teamBonusContribution: 0,
        totalContribution: 0,
        effectiveContribution: 0,
        hasAdopted: true,
        directReferralCount: 0,
        unlockedLevelDepth: 0,
        unlockedBonusTiers: 0,
      },
      update: {
        personalContribution: {
          increment: parseFloat(payload.personalContribution) || 0,
        },
        hasAdopted: true,
      },
    });
  }

  private async handleSystemContributionUpdated(event: ServiceEvent, tx: TransactionClient): Promise<void> {
    const { payload } = event;
    const accountType = payload.accountType;
    const regionCode = payload.regionCode || null;

    // 查找所有匹配的记录（处理可能存在的重复记录情况）
    // 注意：由于 PostgreSQL 中 NULL != NULL，唯一约束在 regionCode 为 NULL 时不生效
    const existingRecords = await tx.syncedSystemContribution.findMany({
      where: {
        accountType,
        regionCode: regionCode === null ? { equals: null } : regionCode,
      },
      orderBy: { syncedAt: 'asc' },
    });

    if (existingRecords.length > 0) {
      await tx.syncedSystemContribution.update({
        where: { id: existingRecords[0].id },
        data: {
          name: payload.name,
          contributionBalance: payload.contributionBalance,
          contributionNeverExpires: payload.contributionNeverExpires,
        },
      });

      // 删除重复记录
      if (existingRecords.length > 1) {
        const duplicateIds = existingRecords.slice(1).map(r => r.id);
        await tx.syncedSystemContribution.deleteMany({
          where: { id: { in: duplicateIds } },
        });
        this.logger.warn(
          `Deleted ${duplicateIds.length} duplicate system contribution records for ${accountType}:${regionCode}`,
        );
      }
    } else {
      await tx.syncedSystemContribution.create({
        data: {
          accountType,
          regionCode,
          name: payload.name,
          contributionBalance: payload.contributionBalance || 0,
          contributionNeverExpires: payload.contributionNeverExpires || false,
        },
      });
    }
  }

  /**
   * 处理 SystemAccountSynced 事件 - 同步系统账户算力
   * 来自 contribution-service 的系统账户（运营、省、市、总部）算力同步
   * accountType: OPERATION / PROVINCE / CITY / HEADQUARTERS
   * regionCode: 省/市代码，如 440000, 440100
   *
   * 注意：由于 PostgreSQL 中 NULL != NULL，@@unique([accountType, regionCode]) 约束
   * 在 regionCode 为 NULL 时不会阻止重复插入。因此需要在代码层面确保唯一性。
   */
  private async handleSystemAccountSynced(event: ServiceEvent, tx: TransactionClient): Promise<void> {
    const { payload } = event;
    const accountType = payload.accountType; // OPERATION / PROVINCE / CITY / HEADQUARTERS
    const regionCode = payload.regionCode || null;

    // 查找所有匹配的记录（处理可能存在的重复记录情况）
    const existingRecords = await tx.syncedSystemContribution.findMany({
      where: {
        accountType,
        regionCode: regionCode === null ? { equals: null } : regionCode,
      },
      orderBy: { syncedAt: 'asc' }, // 保留最早创建的记录
    });

    if (existingRecords.length > 0) {
      // 更新第一条记录
      await tx.syncedSystemContribution.update({
        where: { id: existingRecords[0].id },
        data: {
          name: payload.name,
          contributionBalance: payload.contributionBalance,
        },
      });

      // 如果存在重复记录，删除多余的（只保留第一条）
      if (existingRecords.length > 1) {
        const duplicateIds = existingRecords.slice(1).map(r => r.id);
        await tx.syncedSystemContribution.deleteMany({
          where: { id: { in: duplicateIds } },
        });
        this.logger.warn(
          `Deleted ${duplicateIds.length} duplicate system contribution records for ${accountType}:${regionCode}`,
        );
      }
    } else {
      await tx.syncedSystemContribution.create({
        data: {
          accountType,
          regionCode,
          name: payload.name,
          contributionBalance: payload.contributionBalance || 0,
          contributionNeverExpires: true, // 系统账户算力永不过期
        },
      });
    }
  }

  /**
   * 处理 SystemContributionRecordCreated 事件 - 同步系统账户算力明细
   * 来自 contribution-service，记录每笔算力的来源信息
   */
  private async handleSystemContributionRecordCreated(event: ServiceEvent, tx: TransactionClient): Promise<void> {
    const { payload } = event;

    // contribution-service 使用 systemAccountType 字段，需要兼容处理
    const systemAccountType = payload.systemAccountType || payload.accountType;

    // 解析 systemAccountType：可能是 "PROVINCE_440000" 或 "PROVINCE"
    let accountType: string;
    let regionCode: string | null = null;

    if (systemAccountType?.includes('_')) {
      const parts = systemAccountType.split('_');
      accountType = parts[0];
      regionCode = parts.slice(1).join('_');
    } else {
      accountType = systemAccountType;
      regionCode = payload.regionCode || null;
    }

    await tx.syncedSystemContributionRecord.upsert({
      where: { originalRecordId: BigInt(payload.recordId) },
      create: {
        originalRecordId: BigInt(payload.recordId),
        accountType,
        regionCode,
        sourceAdoptionId: BigInt(payload.sourceAdoptionId),
        sourceAccountSequence: payload.sourceAccountSequence,
        sourceType: payload.sourceType || 'FIXED_RATE',  // 来源类型
        levelDepth: payload.levelDepth ?? null,          // 层级深度
        distributionRate: payload.distributionRate,
        amount: payload.amount,
        effectiveDate: new Date(payload.effectiveDate),
        expireDate: payload.expireDate ? new Date(payload.expireDate) : null,
        isExpired: false,
        createdAt: new Date(payload.createdAt),
      },
      update: {
        accountType,
        regionCode,
        sourceAdoptionId: BigInt(payload.sourceAdoptionId),
        sourceAccountSequence: payload.sourceAccountSequence,
        sourceType: payload.sourceType || 'FIXED_RATE',
        levelDepth: payload.levelDepth ?? null,
        distributionRate: payload.distributionRate,
        amount: payload.amount,
        effectiveDate: new Date(payload.effectiveDate),
        expireDate: payload.expireDate ? new Date(payload.expireDate) : null,
      },
    });

    this.logger.debug(
      `Synced system contribution record: recordId=${payload.recordId}, account=${accountType}:${regionCode}, amount=${payload.amount}`,
    );
  }

  /**
   * 处理 ReferralSynced 事件 - 同步推荐关系
   */
  private async handleReferralSynced(event: ServiceEvent, tx: TransactionClient): Promise<void> {
    const { payload } = event;
    await tx.syncedReferral.upsert({
      where: { accountSequence: payload.accountSequence },
      create: {
        accountSequence: payload.accountSequence,
        referrerAccountSequence: payload.referrerAccountSequence,
        referrerUserId: payload.referrerUserId ? BigInt(payload.referrerUserId) : null,
        originalUserId: payload.originalUserId ? BigInt(payload.originalUserId) : null,
        ancestorPath: payload.ancestorPath,
        depth: payload.depth || 0,
      },
      update: {
        referrerAccountSequence: payload.referrerAccountSequence,
        referrerUserId: payload.referrerUserId ? BigInt(payload.referrerUserId) : null,
        originalUserId: payload.originalUserId ? BigInt(payload.originalUserId) : null,
        ancestorPath: payload.ancestorPath,
        depth: payload.depth || 0,
      },
    });
  }

  /**
   * 处理 AdoptionSynced 事件 - 同步认种记录
   */
  private async handleAdoptionSynced(event: ServiceEvent, tx: TransactionClient): Promise<void> {
    const { payload } = event;
    await tx.syncedAdoption.upsert({
      where: { originalAdoptionId: BigInt(payload.originalAdoptionId) },
      create: {
        originalAdoptionId: BigInt(payload.originalAdoptionId),
        accountSequence: payload.accountSequence,
        treeCount: payload.treeCount,
        adoptionDate: new Date(payload.adoptionDate),
        status: payload.status,
        contributionPerTree: payload.contributionPerTree,
      },
      update: {
        accountSequence: payload.accountSequence,
        treeCount: payload.treeCount,
        adoptionDate: new Date(payload.adoptionDate),
        status: payload.status,
        contributionPerTree: payload.contributionPerTree,
      },
    });
  }

  /**
   * 处理 ContributionRecordSynced 事件 - 同步算力明细记录
   */
  private async handleContributionRecordSynced(event: ServiceEvent, tx: TransactionClient): Promise<void> {
    const { payload } = event;
    await tx.syncedContributionRecord.upsert({
      where: { originalRecordId: BigInt(payload.originalRecordId) },
      create: {
        originalRecordId: BigInt(payload.originalRecordId),
        accountSequence: payload.accountSequence,
        sourceType: payload.sourceType,
        sourceAdoptionId: BigInt(payload.sourceAdoptionId),
        sourceAccountSequence: payload.sourceAccountSequence,
        treeCount: payload.treeCount,
        baseContribution: payload.baseContribution,
        distributionRate: payload.distributionRate,
        levelDepth: payload.levelDepth,
        bonusTier: payload.bonusTier,
        amount: payload.amount,
        effectiveDate: new Date(payload.effectiveDate),
        expireDate: new Date(payload.expireDate),
        isExpired: payload.isExpired || false,
        createdAt: new Date(payload.createdAt),
      },
      update: {
        accountSequence: payload.accountSequence,
        sourceType: payload.sourceType,
        sourceAdoptionId: BigInt(payload.sourceAdoptionId),
        sourceAccountSequence: payload.sourceAccountSequence,
        treeCount: payload.treeCount,
        baseContribution: payload.baseContribution,
        distributionRate: payload.distributionRate,
        levelDepth: payload.levelDepth,
        bonusTier: payload.bonusTier,
        amount: payload.amount,
        effectiveDate: new Date(payload.effectiveDate),
        expireDate: new Date(payload.expireDate),
        isExpired: payload.isExpired || false,
      },
    });
  }

  /**
   * 处理 NetworkProgressUpdated 事件 - 同步全网算力进度
   */
  private async handleNetworkProgressUpdated(event: ServiceEvent, tx: TransactionClient): Promise<void> {
    const { payload } = event;
    // 全网进度只保留一条记录
    const existing = await tx.syncedNetworkProgress.findFirst();

    if (existing) {
      await tx.syncedNetworkProgress.update({
        where: { id: existing.id },
        data: {
          totalTreeCount: payload.totalTreeCount,
          totalAdoptionOrders: payload.totalAdoptionOrders,
          totalAdoptedUsers: payload.totalAdoptedUsers,
          currentUnit: payload.currentUnit,
          currentMultiplier: payload.currentMultiplier,
          currentContributionPerTree: payload.currentContributionPerTree,
          nextUnitTreeCount: payload.nextUnitTreeCount,
        },
      });
    } else {
      await tx.syncedNetworkProgress.create({
        data: {
          totalTreeCount: payload.totalTreeCount,
          totalAdoptionOrders: payload.totalAdoptionOrders,
          totalAdoptedUsers: payload.totalAdoptedUsers,
          currentUnit: payload.currentUnit,
          currentMultiplier: payload.currentMultiplier,
          currentContributionPerTree: payload.currentContributionPerTree,
          nextUnitTreeCount: payload.nextUnitTreeCount,
        },
      });
    }
  }

  // ===========================================================================
  // 挖矿账户事件处理
  // ===========================================================================

  private async handleMiningAccountUpdated(event: ServiceEvent, tx: TransactionClient): Promise<void> {
    const { payload } = event;
    await tx.syncedMiningAccount.upsert({
      where: { accountSequence: payload.accountSequence },
      create: {
        accountSequence: payload.accountSequence,
        totalMined: payload.totalMined || 0,
        availableBalance: payload.availableBalance || 0,
        frozenBalance: payload.frozenBalance || 0,
        totalContribution: payload.totalContribution || 0,
      },
      update: {
        totalMined: payload.totalMined,
        availableBalance: payload.availableBalance,
        frozenBalance: payload.frozenBalance,
        totalContribution: payload.totalContribution,
      },
    });
  }

  private async handleMiningConfigUpdated(event: ServiceEvent, tx: TransactionClient): Promise<void> {
    const { payload } = event;
    // 只保留一条挖矿配置记录
    await tx.syncedMiningConfig.deleteMany({});
    // mining-service 发布 secondDistribution，计算 minuteDistribution = secondDistribution * 60
    const secondDistribution = parseFloat(payload.secondDistribution || '0');
    const minuteDistribution = payload.minuteDistribution || (secondDistribution * 60).toString();
    await tx.syncedMiningConfig.create({
      data: {
        totalShares: payload.totalShares,
        distributionPool: payload.distributionPool,
        remainingDistribution: payload.remainingDistribution,
        halvingPeriodYears: payload.halvingPeriodYears,
        currentEra: payload.currentEra || 1,
        minuteDistribution: minuteDistribution,
        isActive: payload.isActive || false,
        activatedAt: payload.activatedAt ? new Date(payload.activatedAt) : null,
      },
    });
  }

  private async handleDailyMiningStatCreated(event: ServiceEvent, tx: TransactionClient): Promise<void> {
    const { payload } = event;
    await tx.syncedDailyMiningStat.upsert({
      where: { statDate: new Date(payload.date) },
      create: {
        statDate: new Date(payload.date),
        totalContribution: payload.totalContribution || 0,
        totalDistributed: payload.totalDistributed || 0,
        totalBurned: payload.totalBurned || 0,
        participantCount: payload.participantCount || 0,
        avgContributionRate: payload.avgContributionRate || 0,
      },
      update: {
        totalContribution: payload.totalContribution,
        totalDistributed: payload.totalDistributed,
        totalBurned: payload.totalBurned,
        participantCount: payload.participantCount,
        avgContributionRate: payload.avgContributionRate,
      },
    });
  }

  // ===========================================================================
  // 交易账户事件处理
  // ===========================================================================

  private async handleTradingAccountUpdated(
    event: ServiceEvent,
    tx: TransactionClient,
  ): Promise<void> {
    const { payload } = event;

    await tx.syncedTradingAccount.upsert({
      where: { accountSequence: payload.accountSequence },
      create: {
        accountSequence: payload.accountSequence,
        shareBalance: payload.shareBalance || 0,
        cashBalance: payload.cashBalance || 0,
        frozenShares: payload.frozenShares || 0,
        frozenCash: payload.frozenCash || 0,
        totalBought: payload.totalBought || 0,
        totalSold: payload.totalSold || 0,
      },
      update: {
        shareBalance: payload.shareBalance,
        cashBalance: payload.cashBalance,
        frozenShares: payload.frozenShares,
        frozenCash: payload.frozenCash,
        totalBought: payload.totalBought,
        totalSold: payload.totalSold,
      },
    });

    this.logger.debug(`Synced trading account: ${payload.accountSequence}`);
  }

  private async handleDayKLineCreated(event: ServiceEvent, tx: TransactionClient): Promise<void> {
    const { payload } = event;

    await tx.syncedDayKLine.upsert({
      where: { klineDate: new Date(payload.date) },
      create: {
        klineDate: new Date(payload.date),
        open: payload.open,
        high: payload.high,
        low: payload.low,
        close: payload.close,
        volume: payload.volume || 0,
        amount: payload.amount || 0,
        tradeCount: payload.tradeCount || 0,
      },
      update: {
        open: payload.open,
        high: payload.high,
        low: payload.low,
        close: payload.close,
        volume: payload.volume,
        amount: payload.amount,
        tradeCount: payload.tradeCount,
      },
    });

    this.logger.debug(`Synced day K-line: ${payload.date}`);
  }

  private async handleCirculationPoolUpdated(
    event: ServiceEvent,
    tx: TransactionClient,
  ): Promise<void> {
    const { payload } = event;

    // 只保留一条流通池记录
    await tx.syncedCirculationPool.deleteMany({});
    await tx.syncedCirculationPool.create({
      data: {
        totalShares: payload.totalShares || 0,
        totalCash: payload.totalCash || 0,
      },
    });

    this.logger.debug('Synced circulation pool');
  }

  // ===========================================================================
  // 钱包事件处理 (mining-wallet-service)
  // ===========================================================================

  /**
   * 处理 CONTRIBUTION_CREDITED 事件
   * mining-wallet-service 在为用户入账贡献值时发布
   * payload: { accountSequence, walletType, amount, balanceAfter, transactionId, ... }
   */
  private async handleContributionCredited(event: ServiceEvent, tx: TransactionClient): Promise<void> {
    const { payload } = event;
    const walletType = payload.walletType || 'CONTRIBUTION';

    // 先查找是否已存在
    const existing = await tx.syncedUserWallet.findUnique({
      where: {
        accountSequence_walletType: {
          accountSequence: payload.accountSequence,
          walletType,
        },
      },
    });

    if (existing) {
      // 更新余额（使用最新的 balanceAfter）
      await tx.syncedUserWallet.update({
        where: { id: existing.id },
        data: {
          balance: payload.balanceAfter,
          totalInflow: {
            increment: parseFloat(payload.amount) || 0,
          },
        },
      });
    } else {
      // 创建新钱包记录
      // originalId 使用 accountSequence + walletType 的组合生成一个稳定的 ID
      const originalId = `wallet-${payload.accountSequence}-${walletType}`;

      await tx.syncedUserWallet.create({
        data: {
          originalId,
          accountSequence: payload.accountSequence,
          walletType,
          balance: payload.balanceAfter || 0,
          frozenBalance: 0,
          totalInflow: parseFloat(payload.amount) || 0,
          totalOutflow: 0,
          isActive: true,
        },
      });
    }

    this.logger.debug(`Synced user wallet from CONTRIBUTION_CREDITED: ${payload.accountSequence}, balance: ${payload.balanceAfter}`);
  }

}
