/**
 * 转让算力调整服务（纯新增）
 * 处理 planting.ownership.removed 和 planting.ownership.added 事件
 * 对受影响的 88% 算力（个人70% + 团队层级7.5% + 个人加成7.5% + 省1% + 市2%）进行对冲/新增
 *
 * 设计说明：
 * - 直接使用 Prisma 操作数据库，不经过聚合根（因为转让涉及负数金额，而 ContributionAmount 不支持负数）
 * - 所有调整通过追加新流水记录实现（对冲式），历史记录零修改、零删除
 * - 运营账户 12% 完全不受影响
 *
 * 回滚方式：删除此文件并从 application.module.ts 中移除引用
 */

import { Injectable, Logger } from '@nestjs/common';
import Decimal from 'decimal.js';
import { PrismaService } from '../../infrastructure/persistence/prisma/prisma.service';
import { ContributionAccountRepository } from '../../infrastructure/persistence/repositories/contribution-account.repository';
import { SyncedDataRepository } from '../../infrastructure/persistence/repositories/synced-data.repository';
import { SystemAccountRepository } from '../../infrastructure/persistence/repositories/system-account.repository';
import { OutboxRepository } from '../../infrastructure/persistence/repositories/outbox.repository';
import { UnitOfWork } from '../../infrastructure/persistence/unit-of-work/unit-of-work';
import { ContributionAmount } from '../../domain/value-objects/contribution-amount.vo';
import { BonusClaimService } from './bonus-claim.service';

/** 转让事件通用字段 */
interface TransferEventBase {
  transferOrderNo: string;
  sourceOrderNo: string;
  sourceOrderId: string; // bigint → string
  treeCount: number;
  contributionPerTree: string;
  selectedProvince: string;
  selectedCity: string;
  originalAdoptionDate: string;
  originalExpireDate: string;
}

/** 卖方减持事件 */
export interface OwnershipRemovedEvent extends TransferEventBase {
  sellerUserId: string;
  sellerAccountSequence: string;
}

/** 买方增持事件 */
export interface OwnershipAddedEvent extends TransferEventBase {
  buyerUserId: string;
  buyerAccountSequence: string;
}

// 分配比例常量
const RATE_PERSONAL = new Decimal('0.70');
const RATE_LEVEL_PER = new Decimal('0.005');
const RATE_BONUS_PER = new Decimal('0.025');
const RATE_PROVINCE = new Decimal('0.01');
const RATE_CITY = new Decimal('0.02');

@Injectable()
export class TransferAdjustmentService {
  private readonly logger = new Logger(TransferAdjustmentService.name);

  constructor(
    private readonly prisma: PrismaService,
    private readonly contributionAccountRepository: ContributionAccountRepository,
    private readonly syncedDataRepository: SyncedDataRepository,
    private readonly systemAccountRepository: SystemAccountRepository,
    private readonly outboxRepository: OutboxRepository,
    private readonly unitOfWork: UnitOfWork,
    private readonly bonusClaimService: BonusClaimService,
  ) {}

  /**
   * 处理卖方减持（planting.ownership.removed）
   * 创建负数对冲流水，扣减卖方及其上线链路的算力
   */
  async processOwnershipRemoved(event: OwnershipRemovedEvent): Promise<void> {
    const sourceAdoptionId = BigInt(event.sourceOrderId);
    const baseContribution = new Decimal(event.contributionPerTree);
    const totalContribution = baseContribution.times(event.treeCount);
    const transferDate = new Date();
    const expireDate = new Date(event.originalExpireDate);

    this.logger.log(
      `[TRANSFER-OUT] Starting: ${event.transferOrderNo}, seller=${event.sellerAccountSequence}, ` +
        `trees=${event.treeCount}, contribution/tree=${event.contributionPerTree}`,
    );

    await this.unitOfWork.executeInTransaction(async () => {
      // 1. 卖方个人算力扣减（70%）
      const personalAmount = totalContribution.times(RATE_PERSONAL);
      await this.createTransferRecord({
        accountSequence: event.sellerAccountSequence,
        sourceType: 'TRANSFER_OUT_PERSONAL',
        sourceAdoptionId,
        sourceAccountSequence: event.sellerAccountSequence,
        treeCount: event.treeCount,
        baseContribution,
        distributionRate: RATE_PERSONAL,
        amount: personalAmount.negated(), // 负数
        transferOrderNo: event.transferOrderNo,
        effectiveDate: transferDate,
        expireDate,
        remark: `转让转出个人算力`,
      });
      await this.decrementAccountEffective(event.sellerAccountSequence, personalAmount);
      await this.decrementPersonalContribution(event.sellerAccountSequence, personalAmount);

      // 2. 卖方上线团队层级扣减（每级0.5%，最多15级）
      const sellerReferral = await this.syncedDataRepository.findSyncedReferralByAccountSequence(
        event.sellerAccountSequence,
      );
      if (sellerReferral?.referrerAccountSequence) {
        const ancestorChain = await this.syncedDataRepository.findAncestorChain(
          sellerReferral.referrerAccountSequence,
          15,
        );

        for (let level = 1; level <= 15; level++) {
          const ancestor = ancestorChain[level - 1];
          if (!ancestor) break;

          const levelAmount = totalContribution.times(RATE_LEVEL_PER);

          // 查询该级别是否有已分配的记录
          const originalRecord = await this.prisma.contributionRecord.findFirst({
            where: {
              accountSequence: ancestor.accountSequence,
              sourceAdoptionId,
              sourceType: 'TEAM_LEVEL',
              levelDepth: level,
            },
          });

          if (originalRecord) {
            // 有已分配记录 → 创建负数对冲流水
            await this.createTransferRecord({
              accountSequence: ancestor.accountSequence,
              sourceType: 'TRANSFER_OUT_TEAM_LEVEL',
              sourceAdoptionId,
              sourceAccountSequence: event.sellerAccountSequence,
              treeCount: event.treeCount,
              baseContribution,
              distributionRate: RATE_LEVEL_PER,
              levelDepth: level,
              amount: levelAmount.negated(),
              transferOrderNo: event.transferOrderNo,
              effectiveDate: transferDate,
              expireDate,
              remark: `转让转出L${level}团队算力`,
            });
            await this.decrementAccountEffective(ancestor.accountSequence, levelAmount);
            await this.decrementLevelPending(ancestor.accountSequence, level, levelAmount);
          }
          // 如果在 UnallocatedContribution 中（上线未解锁），标记失效
          await this.invalidateUnallocatedForTransfer(
            sourceAdoptionId,
            event.sellerAccountSequence,
            level,
            event.transferOrderNo,
          );
        }
      }

      // 3. 卖方加成扣减（每档2.5%，最多3档）
      for (let tier = 1; tier <= 3; tier++) {
        const originalBonus = await this.prisma.contributionRecord.findFirst({
          where: {
            accountSequence: event.sellerAccountSequence,
            sourceAdoptionId,
            sourceType: 'TEAM_BONUS',
            bonusTier: tier,
          },
        });

        if (originalBonus) {
          const bonusAmount = totalContribution.times(RATE_BONUS_PER);
          await this.createTransferRecord({
            accountSequence: event.sellerAccountSequence,
            sourceType: 'TRANSFER_OUT_BONUS',
            sourceAdoptionId,
            sourceAccountSequence: event.sellerAccountSequence,
            treeCount: event.treeCount,
            baseContribution,
            distributionRate: RATE_BONUS_PER,
            bonusTier: tier,
            amount: bonusAmount.negated(),
            transferOrderNo: event.transferOrderNo,
            effectiveDate: transferDate,
            expireDate,
            remark: `转让转出加成T${tier}`,
          });
          await this.decrementAccountEffective(event.sellerAccountSequence, bonusAmount);
          await this.decrementBonusPending(event.sellerAccountSequence, tier, bonusAmount);
        }

        // 标记未分配的加成算力失效
        await this.invalidateUnallocatedBonusForTransfer(
          sourceAdoptionId,
          event.sellerAccountSequence,
          tier,
          event.transferOrderNo,
        );
      }

      // 4. 卖方省公司系统账户扣减（1%）
      const provinceAmount = totalContribution.times(RATE_PROVINCE);
      await this.adjustSystemAccount(
        'PROVINCE',
        event.selectedProvince,
        sourceAdoptionId,
        event.sellerAccountSequence,
        'TRANSFER_OUT_SYSTEM_PROVINCE',
        RATE_PROVINCE,
        provinceAmount.negated(),
        transferDate,
        expireDate,
        event.transferOrderNo,
      );

      // 5. 卖方市公司系统账户扣减（2%）
      const cityAmount = totalContribution.times(RATE_CITY);
      await this.adjustSystemAccount(
        'CITY',
        event.selectedCity,
        sourceAdoptionId,
        event.sellerAccountSequence,
        'TRANSFER_OUT_SYSTEM_CITY',
        RATE_CITY,
        cityAmount.negated(),
        transferDate,
        expireDate,
        event.transferOrderNo,
      );

      // 6. 更新卖方解锁状态（如果卖方不再持有任何树）
      await this.updateSellerUnlockStatus(event.sellerAccountSequence);
    });

    this.logger.log(
      `[TRANSFER-OUT] ✓ Completed: ${event.transferOrderNo}, seller=${event.sellerAccountSequence}`,
    );
  }

  /**
   * 处理买方增持（planting.ownership.added）
   * 创建正数流水，为买方及其上线链路新增算力
   */
  async processOwnershipAdded(event: OwnershipAddedEvent): Promise<void> {
    const sourceAdoptionId = BigInt(event.sourceOrderId);
    const baseContribution = new Decimal(event.contributionPerTree);
    const totalContribution = baseContribution.times(event.treeCount);
    const transferDate = new Date();
    const expireDate = new Date(event.originalExpireDate);

    this.logger.log(
      `[TRANSFER-IN] Starting: ${event.transferOrderNo}, buyer=${event.buyerAccountSequence}, ` +
        `trees=${event.treeCount}, contribution/tree=${event.contributionPerTree}`,
    );

    await this.unitOfWork.executeInTransaction(async () => {
      // 确保买方有算力账户
      let buyerAccount = await this.contributionAccountRepository.findByAccountSequence(
        event.buyerAccountSequence,
      );
      if (!buyerAccount) {
        const { ContributionAccountAggregate } = await import(
          '../../domain/aggregates/contribution-account.aggregate'
        );
        buyerAccount = ContributionAccountAggregate.create(event.buyerAccountSequence);
        await this.contributionAccountRepository.save(buyerAccount);
      }

      // 1. 买方个人算力新增（70%）
      const personalAmount = totalContribution.times(RATE_PERSONAL);
      await this.createTransferRecord({
        accountSequence: event.buyerAccountSequence,
        sourceType: 'TRANSFER_IN_PERSONAL',
        sourceAdoptionId,
        sourceAccountSequence: event.buyerAccountSequence,
        treeCount: event.treeCount,
        baseContribution,
        distributionRate: RATE_PERSONAL,
        amount: personalAmount, // 正数
        transferOrderNo: event.transferOrderNo,
        effectiveDate: transferDate,
        expireDate,
        remark: `转让转入个人算力`,
      });
      await this.incrementAccountEffective(event.buyerAccountSequence, personalAmount);
      await this.incrementPersonalContribution(event.buyerAccountSequence, personalAmount);

      // 2. 买方上线团队层级分配（每级0.5%，最多15级）
      const buyerReferral = await this.syncedDataRepository.findSyncedReferralByAccountSequence(
        event.buyerAccountSequence,
      );
      if (buyerReferral?.referrerAccountSequence) {
        const ancestorChain = await this.syncedDataRepository.findAncestorChain(
          buyerReferral.referrerAccountSequence,
          15,
        );
        const ancestorAccountSeqs = ancestorChain.map((a) => a.accountSequence);
        const ancestorAccounts = await this.contributionAccountRepository.findByAccountSequences(
          ancestorAccountSeqs,
        );

        for (let level = 1; level <= 15; level++) {
          const ancestor = ancestorChain[level - 1];
          const levelAmount = totalContribution.times(RATE_LEVEL_PER);

          if (!ancestor) {
            // 无上线 → UnallocatedContribution（归总部）
            await this.createUnallocatedContribution({
              sourceAdoptionId,
              sourceAccountSequence: event.buyerAccountSequence,
              unallocType: 'LEVEL_NO_ANCESTOR',
              levelDepth: level,
              amount: levelAmount,
              reason: `转让转入：第${level}级无上线`,
              transferOrderNo: event.transferOrderNo,
              effectiveDate: transferDate,
              expireDate,
            });
            continue;
          }

          const ancestorAccount = ancestorAccounts.get(ancestor.accountSequence);
          const unlockedLevelDepth = ancestorAccount?.unlockedLevelDepth ?? 0;

          if (unlockedLevelDepth >= level) {
            // 上线已解锁 → 分配给上线
            await this.createTransferRecord({
              accountSequence: ancestor.accountSequence,
              sourceType: 'TRANSFER_IN_TEAM_LEVEL',
              sourceAdoptionId,
              sourceAccountSequence: event.buyerAccountSequence,
              treeCount: event.treeCount,
              baseContribution,
              distributionRate: RATE_LEVEL_PER,
              levelDepth: level,
              amount: levelAmount,
              transferOrderNo: event.transferOrderNo,
              effectiveDate: transferDate,
              expireDate,
              remark: `转让转入L${level}团队算力`,
            });
            await this.incrementAccountEffective(ancestor.accountSequence, levelAmount);
            await this.incrementLevelPending(ancestor.accountSequence, level, levelAmount);
          } else {
            // 上线未解锁 → UnallocatedContribution
            await this.createUnallocatedContribution({
              sourceAdoptionId,
              sourceAccountSequence: event.buyerAccountSequence,
              unallocType: 'LEVEL_OVERFLOW',
              wouldBeAccountSequence: ancestor.accountSequence,
              levelDepth: level,
              amount: levelAmount,
              reason: `转让转入：上线${ancestor.accountSequence}未解锁第${level}级`,
              transferOrderNo: event.transferOrderNo,
              effectiveDate: transferDate,
              expireDate,
            });
          }
        }
      } else {
        // 买方无推荐链，15级全部归总部
        for (let level = 1; level <= 15; level++) {
          const levelAmount = totalContribution.times(RATE_LEVEL_PER);
          await this.createUnallocatedContribution({
            sourceAdoptionId,
            sourceAccountSequence: event.buyerAccountSequence,
            unallocType: 'LEVEL_NO_ANCESTOR',
            levelDepth: level,
            amount: levelAmount,
            reason: `转让转入：第${level}级无上线（买方无推荐关系）`,
            transferOrderNo: event.transferOrderNo,
            effectiveDate: transferDate,
            expireDate,
          });
        }
      }

      // 3. 买方加成分配（每档2.5%，最多3档）
      // 买方获得树后 hasAdopted = true
      const effectiveHasAdopted = buyerAccount.hasAdopted || true;
      const directReferralAdoptedCount = buyerAccount.directReferralAdoptedCount;

      // 计算买方解锁的加成档位
      let unlockedBonusTiers = 0;
      if (effectiveHasAdopted) unlockedBonusTiers = 1;
      if (directReferralAdoptedCount >= 2) unlockedBonusTiers = 2;
      if (directReferralAdoptedCount >= 4) unlockedBonusTiers = 3;

      for (let tier = 1; tier <= 3; tier++) {
        const bonusAmount = totalContribution.times(RATE_BONUS_PER);

        if (unlockedBonusTiers >= tier) {
          await this.createTransferRecord({
            accountSequence: event.buyerAccountSequence,
            sourceType: 'TRANSFER_IN_BONUS',
            sourceAdoptionId,
            sourceAccountSequence: event.buyerAccountSequence,
            treeCount: event.treeCount,
            baseContribution,
            distributionRate: RATE_BONUS_PER,
            bonusTier: tier,
            amount: bonusAmount,
            transferOrderNo: event.transferOrderNo,
            effectiveDate: transferDate,
            expireDate,
            remark: `转让转入加成T${tier}`,
          });
          await this.incrementAccountEffective(event.buyerAccountSequence, bonusAmount);
          await this.incrementBonusPending(event.buyerAccountSequence, tier, bonusAmount);
        } else {
          await this.createUnallocatedContribution({
            sourceAdoptionId,
            sourceAccountSequence: event.buyerAccountSequence,
            unallocType: `BONUS_TIER_${tier}`,
            wouldBeAccountSequence: event.buyerAccountSequence,
            amount: bonusAmount,
            reason: `转让转入：买方${event.buyerAccountSequence}未解锁第${tier}档加成`,
            transferOrderNo: event.transferOrderNo,
            effectiveDate: transferDate,
            expireDate,
          });
        }
      }

      // 4. 买方省公司系统账户增加（1%）
      const provinceAmount = totalContribution.times(RATE_PROVINCE);
      await this.adjustSystemAccount(
        'PROVINCE',
        event.selectedProvince,
        sourceAdoptionId,
        event.buyerAccountSequence,
        'TRANSFER_IN_SYSTEM_PROVINCE',
        RATE_PROVINCE,
        provinceAmount, // 正数
        transferDate,
        expireDate,
        event.transferOrderNo,
      );

      // 5. 买方市公司系统账户增加（2%）
      const cityAmount = totalContribution.times(RATE_CITY);
      await this.adjustSystemAccount(
        'CITY',
        event.selectedCity,
        sourceAdoptionId,
        event.buyerAccountSequence,
        'TRANSFER_IN_SYSTEM_CITY',
        RATE_CITY,
        cityAmount, // 正数
        transferDate,
        expireDate,
        event.transferOrderNo,
      );

      // 6. 更新买方解锁状态
      await this.updateBuyerUnlockStatus(event.buyerAccountSequence);

      // 7. 发布算力调整完成确认事件（通知 Saga）
      await this.publishTransferAdjustedEvent(event.transferOrderNo);
    });

    this.logger.log(
      `[TRANSFER-IN] ✓ Completed: ${event.transferOrderNo}, buyer=${event.buyerAccountSequence}`,
    );
  }

  // ============================
  // 私有辅助方法
  // ============================

  /**
   * 直接通过 Prisma 创建算力流水记录（支持负数金额）
   */
  private async createTransferRecord(params: {
    accountSequence: string;
    sourceType: string;
    sourceAdoptionId: bigint;
    sourceAccountSequence: string;
    treeCount: number;
    baseContribution: Decimal;
    distributionRate: Decimal;
    levelDepth?: number;
    bonusTier?: number;
    amount: Decimal;
    transferOrderNo: string;
    effectiveDate: Date;
    expireDate: Date;
    remark?: string;
  }): Promise<void> {
    await this.unitOfWork.getClient().contributionRecord.create({
      data: {
        accountSequence: params.accountSequence,
        sourceType: params.sourceType,
        sourceAdoptionId: params.sourceAdoptionId,
        sourceAccountSequence: params.sourceAccountSequence,
        treeCount: params.treeCount,
        baseContribution: params.baseContribution,
        distributionRate: params.distributionRate,
        levelDepth: params.levelDepth ?? null,
        bonusTier: params.bonusTier ?? null,
        amount: params.amount,
        transferOrderNo: params.transferOrderNo,
        status: 'EFFECTIVE',
        effectiveDate: params.effectiveDate,
        expireDate: params.expireDate,
        remark: params.remark ?? null,
      },
    });
  }

  /**
   * 创建未分配算力记录（归总部）
   */
  private async createUnallocatedContribution(params: {
    sourceAdoptionId: bigint;
    sourceAccountSequence: string;
    unallocType: string;
    wouldBeAccountSequence?: string;
    levelDepth?: number;
    amount: Decimal;
    reason: string;
    transferOrderNo: string;
    effectiveDate: Date;
    expireDate: Date;
  }): Promise<void> {
    await this.unitOfWork.getClient().unallocatedContribution.create({
      data: {
        sourceAdoptionId: params.sourceAdoptionId,
        sourceAccountSequence: params.sourceAccountSequence,
        unallocType: params.unallocType,
        wouldBeAccountSequence: params.wouldBeAccountSequence ?? null,
        levelDepth: params.levelDepth ?? null,
        amount: params.amount,
        reason: params.reason,
        transferOrderNo: params.transferOrderNo,
        status: 'PENDING',
        effectiveDate: params.effectiveDate,
        expireDate: params.expireDate,
      },
    });

    // 汇总到总部系统账户
    await this.systemAccountRepository.addContribution(
      'HEADQUARTERS',
      null,
      new ContributionAmount(params.amount),
    );
  }

  /**
   * 标记未分配的层级算力失效（转让场景）
   */
  private async invalidateUnallocatedForTransfer(
    sourceAdoptionId: bigint,
    sourceAccountSequence: string,
    levelDepth: number,
    transferOrderNo: string,
  ): Promise<void> {
    await this.unitOfWork.getClient().unallocatedContribution.updateMany({
      where: {
        sourceAdoptionId,
        sourceAccountSequence,
        levelDepth,
        status: 'PENDING',
        unallocType: { in: ['LEVEL_OVERFLOW', 'LEVEL_NO_ANCESTOR'] },
      },
      data: {
        status: 'ALLOCATED_TO_HQ',
        allocatedAt: new Date(),
      },
    });
  }

  /**
   * 标记未分配的加成算力失效（转让场景）
   */
  private async invalidateUnallocatedBonusForTransfer(
    sourceAdoptionId: bigint,
    sourceAccountSequence: string,
    bonusTier: number,
    transferOrderNo: string,
  ): Promise<void> {
    await this.unitOfWork.getClient().unallocatedContribution.updateMany({
      where: {
        sourceAdoptionId,
        sourceAccountSequence,
        unallocType: `BONUS_TIER_${bonusTier}`,
        status: 'PENDING',
      },
      data: {
        status: 'ALLOCATED_TO_HQ',
        allocatedAt: new Date(),
      },
    });
  }

  /**
   * 调整系统账户（省/市）
   */
  private async adjustSystemAccount(
    accountType: 'PROVINCE' | 'CITY',
    regionCode: string,
    sourceAdoptionId: bigint,
    sourceAccountSequence: string,
    sourceType: string,
    distributionRate: Decimal,
    amount: Decimal, // 可正可负
    effectiveDate: Date,
    expireDate: Date,
    transferOrderNo: string,
  ): Promise<void> {
    // 确保系统账户存在
    await this.systemAccountRepository.ensureSystemAccountsExist();

    const systemAccount = await this.systemAccountRepository.findByTypeAndRegion(
      accountType,
      regionCode,
    );

    if (!systemAccount) {
      // 动态创建省市系统账户
      await this.systemAccountRepository.addContribution(
        accountType,
        regionCode,
        new ContributionAmount(0),
      );
    }

    // 使用 Prisma 直接更新（支持负数 increment）
    const sa = await this.unitOfWork.getClient().systemAccount.findFirst({
      where: { accountType, regionCode },
    });

    if (sa) {
      await this.unitOfWork.getClient().systemAccount.update({
        where: { id: sa.id },
        data: {
          contributionBalance: { increment: amount },
        },
      });

      // 创建系统账户明细记录
      await this.unitOfWork.getClient().systemContributionRecord.create({
        data: {
          systemAccountId: sa.id,
          sourceAdoptionId,
          sourceAccountSequence,
          sourceType,
          distributionRate: distributionRate.toNumber(),
          amount,
          transferOrderNo,
          effectiveDate,
          expireDate,
        },
      });
    }
  }

  // ============================
  // ContributionAccount 原子更新方法
  // ============================

  private async incrementAccountEffective(accountSequence: string, amount: Decimal): Promise<void> {
    await this.unitOfWork.getClient().contributionAccount.update({
      where: { accountSequence },
      data: {
        effectiveContribution: { increment: amount },
        updatedAt: new Date(),
      },
    });
  }

  private async decrementAccountEffective(accountSequence: string, amount: Decimal): Promise<void> {
    await this.unitOfWork.getClient().contributionAccount.update({
      where: { accountSequence },
      data: {
        effectiveContribution: { decrement: amount },
        updatedAt: new Date(),
      },
    });
  }

  private async incrementPersonalContribution(accountSequence: string, amount: Decimal): Promise<void> {
    await this.unitOfWork.getClient().contributionAccount.update({
      where: { accountSequence },
      data: {
        personalContribution: { increment: amount },
        updatedAt: new Date(),
      },
    });
  }

  private async decrementPersonalContribution(accountSequence: string, amount: Decimal): Promise<void> {
    await this.unitOfWork.getClient().contributionAccount.update({
      where: { accountSequence },
      data: {
        personalContribution: { decrement: amount },
        updatedAt: new Date(),
      },
    });
  }

  private async incrementLevelPending(accountSequence: string, level: number, amount: Decimal): Promise<void> {
    const levelField = `level${level}Pending`;
    await this.unitOfWork.getClient().contributionAccount.update({
      where: { accountSequence },
      data: {
        [levelField]: { increment: amount },
        totalLevelPending: { increment: amount },
        totalPending: { increment: amount },
        updatedAt: new Date(),
      },
    });
  }

  private async decrementLevelPending(accountSequence: string, level: number, amount: Decimal): Promise<void> {
    const levelField = `level${level}Pending`;
    await this.unitOfWork.getClient().contributionAccount.update({
      where: { accountSequence },
      data: {
        [levelField]: { decrement: amount },
        totalLevelPending: { decrement: amount },
        totalPending: { decrement: amount },
        updatedAt: new Date(),
      },
    });
  }

  private async incrementBonusPending(accountSequence: string, tier: number, amount: Decimal): Promise<void> {
    const tierField = `bonusTier${tier}Pending`;
    await this.unitOfWork.getClient().contributionAccount.update({
      where: { accountSequence },
      data: {
        [tierField]: { increment: amount },
        totalBonusPending: { increment: amount },
        totalPending: { increment: amount },
        updatedAt: new Date(),
      },
    });
  }

  private async decrementBonusPending(accountSequence: string, tier: number, amount: Decimal): Promise<void> {
    const tierField = `bonusTier${tier}Pending`;
    await this.unitOfWork.getClient().contributionAccount.update({
      where: { accountSequence },
      data: {
        [tierField]: { decrement: amount },
        totalBonusPending: { decrement: amount },
        totalPending: { decrement: amount },
        updatedAt: new Date(),
      },
    });
  }

  // ============================
  // 解锁状态更新
  // ============================

  /**
   * 更新卖方解锁状态
   * 如果卖方不再持有任何树，需要更新 hasAdopted 和相关解锁深度
   */
  private async updateSellerUnlockStatus(sellerAccountSequence: string): Promise<void> {
    // 检查卖方是否还有其他已同步的认种记录
    const adoptions = await this.syncedDataRepository.findAdoptionsByAccountSequence(
      sellerAccountSequence,
    );

    // 过滤掉 status 不是 MINING_ENABLED 的
    const activeAdoptions = adoptions.filter((a) => a.status === 'MINING_ENABLED');

    if (activeAdoptions.length === 0) {
      // 卖方不再持有任何活跃树 → 重置解锁状态
      const account = await this.contributionAccountRepository.findByAccountSequence(
        sellerAccountSequence,
      );
      if (account && account.hasAdopted) {
        // 注意：不追回历史分配，只更新状态影响未来分配
        await this.unitOfWork.getClient().contributionAccount.update({
          where: { accountSequence: sellerAccountSequence },
          data: {
            hasAdopted: false,
            unlockedLevelDepth: 0,
            // unlockedBonusTiers 的重新计算：T1 取决于 hasAdopted
            unlockedBonusTiers: account.directReferralAdoptedCount >= 4 ? 3 :
              account.directReferralAdoptedCount >= 2 ? 2 : 0,
            updatedAt: new Date(),
          },
        });

        this.logger.log(
          `[TRANSFER-OUT] Seller ${sellerAccountSequence} no longer holds trees, reset unlock status`,
        );
      }
    }
  }

  /**
   * 更新买方解锁状态
   * 买方获得树后标记 hasAdopted，触发解锁和可能的奖励补发
   */
  private async updateBuyerUnlockStatus(buyerAccountSequence: string): Promise<void> {
    const account = await this.contributionAccountRepository.findByAccountSequence(
      buyerAccountSequence,
    );
    if (!account) return;

    if (!account.hasAdopted) {
      // 首次获得树 → 解锁 L1-5 + T1
      account.markAsAdopted();
      await this.contributionAccountRepository.save(account);

      this.logger.log(
        `[TRANSFER-IN] Buyer ${buyerAccountSequence} marked as adopted, unlocked L1-5 + T1`,
      );
    }

    // 检查买方的推荐人的 directReferralAdoptedCount 是否需要更新
    const buyerReferral = await this.syncedDataRepository.findSyncedReferralByAccountSequence(
      buyerAccountSequence,
    );
    if (buyerReferral?.referrerAccountSequence) {
      const newCount = await this.syncedDataRepository.getDirectReferralAdoptedCount(
        buyerReferral.referrerAccountSequence,
      );

      const referrerAccount = await this.contributionAccountRepository.findByAccountSequence(
        buyerReferral.referrerAccountSequence,
      );
      if (referrerAccount && newCount > referrerAccount.directReferralAdoptedCount) {
        const previousCount = referrerAccount.directReferralAdoptedCount;

        // 更新直推认种计数
        for (let i = previousCount; i < newCount; i++) {
          referrerAccount.incrementDirectReferralAdoptedCount();
        }
        await this.contributionAccountRepository.save(referrerAccount);

        // 触发奖励补发检查
        await this.bonusClaimService.checkAndClaimBonus(
          buyerReferral.referrerAccountSequence,
          previousCount,
          newCount,
        );

        this.logger.log(
          `[TRANSFER-IN] Updated referrer ${buyerReferral.referrerAccountSequence} ` +
            `directReferralAdoptedCount: ${previousCount} → ${newCount}`,
        );
      }
    }
  }

  /**
   * 发布算力调整完成确认事件（通知 Saga）
   */
  private async publishTransferAdjustedEvent(transferOrderNo: string): Promise<void> {
    await this.outboxRepository.save({
      aggregateType: 'TransferAdjustment',
      aggregateId: transferOrderNo,
      eventType: 'ContributionTransferAdjusted',
      topic: 'contribution.transfer.adjusted', // 显式指定 topic
      key: transferOrderNo,
      payload: {
        transferOrderNo,
        consumerService: 'contribution-service',
        success: true,
        confirmedAt: new Date().toISOString(),
      },
    });

    this.logger.log(
      `[TRANSFER] Published contribution.transfer.adjusted for ${transferOrderNo}`,
    );
  }
}
