import { Injectable, Inject, Logger } from '@nestjs/common';
import { RewardLedgerEntry } from '../aggregates/reward-ledger-entry/reward-ledger-entry.aggregate';
import { RewardSource } from '../value-objects/reward-source.vo';
import { RightType, RIGHT_AMOUNTS } from '../value-objects/right-type.enum';
import { Money } from '../value-objects/money.vo';
import { Hashpower } from '../value-objects/hashpower.vo';

// 外部服务接口 (防腐层)
export interface IReferralServiceClient {
  getReferralChain(accountSequence: string): Promise<{
    ancestors: Array<{ userId: bigint; accountSequence: string; hasPlanted: boolean }>;
  }>;
}

export interface RewardDistribution {
  distributions: Array<{
    accountSequence: string;
    treeCount: number;
    reason: string;
  }>;
}

export interface AreaRewardDistribution {
  distributions: Array<{
    accountSequence: string;
    treeCount: number;
    reason: string;
    isSystemAccount: boolean;
  }>;
}

export interface IAuthorizationServiceClient {
  findNearestAuthorizedProvince(accountSequence: string, provinceCode: string): Promise<string | null>;
  findNearestAuthorizedCity(accountSequence: string, cityCode: string): Promise<string | null>;
  findNearestCommunity(accountSequence: string): Promise<string | null>;
  getCommunityRewardDistribution(accountSequence: string, treeCount: number): Promise<RewardDistribution>;
  getProvinceTeamRewardDistribution(accountSequence: string, provinceCode: string, treeCount: number): Promise<RewardDistribution>;
  getProvinceAreaRewardDistribution(provinceCode: string, treeCount: number): Promise<AreaRewardDistribution>;
  getCityTeamRewardDistribution(accountSequence: string, cityCode: string, treeCount: number): Promise<RewardDistribution>;
  getCityAreaRewardDistribution(cityCode: string, treeCount: number): Promise<AreaRewardDistribution>;
}

export const REFERRAL_SERVICE_CLIENT = Symbol('IReferralServiceClient');
export const AUTHORIZATION_SERVICE_CLIENT = Symbol('IAuthorizationServiceClient');

// ============================================
// 系统账户ID配置
// ============================================

// 总部社区账户ID
const HEADQUARTERS_COMMUNITY_USER_ID = BigInt(1);

// 成本费账户ID (需要在系统初始化时创建)
const COST_FEE_ACCOUNT_ID = BigInt(2);

// 运营费账户ID (需要在系统初始化时创建)
const OPERATION_FEE_ACCOUNT_ID = BigInt(3);

// RWAD 1号底池账户ID (需要在系统初始化时创建)
const RWAD_POOL_ACCOUNT_ID = BigInt(4);

// 分享权益池账户ID (无推荐人时分享权益进入此账户)
const SHARE_RIGHT_POOL_USER_ID = BigInt(-5);

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

  /**
   * 将 accountSequence 转换为 userId
   * accountSequence 格式: D25121400002 (用户) / S0000000001 (系统) / 9440000 (省系统)
   * 如果以字母开头，去掉第一个字符后转为 BigInt
   */
  private parseAccountSequenceToUserId(accountSequence: string): bigint {
    const numericPart = /^[a-zA-Z]/i.test(accountSequence) ? accountSequence.slice(1) : accountSequence;
    return BigInt(numericPart);
  }

  constructor(
    @Inject(REFERRAL_SERVICE_CLIENT)
    private readonly referralService: IReferralServiceClient,
    @Inject(AUTHORIZATION_SERVICE_CLIENT)
    private readonly authorizationService: IAuthorizationServiceClient,
  ) {}

  /**
   * 计算认种订单产生的所有奖励
   * 总计 15831 USDT = 2800 + 2100 + 203 + 5760 + 3600 + 108 + 144 + 252 + 288 + 576
   */
  async calculateRewards(params: {
    sourceOrderNo: string;  // 订单号是字符串格式
    sourceUserId: bigint;
    sourceAccountSequence?: string;  // 跨服务关联标识
    treeCount: number;
    provinceCode: string;
    cityCode: string;
    priceSupplement?: number; // [2026-02-26] 总部运营成本压力涨价（每棵树加价金额），归总部 (S0000000001)
  }): Promise<RewardLedgerEntry[]> {
    this.logger.log(
      `[calculateRewards] START orderNo=${params.sourceOrderNo}, userId=${params.sourceUserId}, ` +
      `treeCount=${params.treeCount}, province=${params.provinceCode}, city=${params.cityCode}`,
    );

    const rewards: RewardLedgerEntry[] = [];

    // ============================================
    // 系统费用类 (10863 USDT)
    // ============================================

    // 1. 成本费 (2800 USDT)
    const costFeeReward = this.calculateCostFee(
      params.sourceOrderNo,
      params.sourceUserId,
      params.sourceAccountSequence,
      params.treeCount,
    );
    rewards.push(costFeeReward);

    // 2. 运营费 (2100 USDT)
    const operationFeeReward = this.calculateOperationFee(
      params.sourceOrderNo,
      params.sourceUserId,
      params.sourceAccountSequence,
      params.treeCount,
    );
    rewards.push(operationFeeReward);

    // 3. 总部社区基础费 (203 USDT)
    const headquartersBaseFeeReward = this.calculateHeadquartersBaseFee(
      params.sourceOrderNo,
      params.sourceUserId,
      params.sourceAccountSequence,
      params.treeCount,
    );
    rewards.push(headquartersBaseFeeReward);

    // 4. RWAD底池注入 (5760 USDT)
    const rwadPoolReward = this.calculateRwadPoolInjection(
      params.sourceOrderNo,
      params.sourceUserId,
      params.sourceAccountSequence,
      params.treeCount,
    );
    rewards.push(rwadPoolReward);

    // ============================================
    // 用户权益类 (4968 USDT + 算力)
    // ============================================

    // 5. 分享权益 (3600 USDT)
    const shareRewards = await this.calculateShareRights(
      params.sourceOrderNo,
      params.sourceUserId,
      params.sourceAccountSequence,
      params.treeCount,
    );
    rewards.push(...shareRewards);

    // 6. 省团队权益 (144 USDT) - 可能返回多条记录（考核分配）
    const provinceTeamRewards = await this.calculateProvinceTeamRight(
      params.sourceOrderNo,
      params.sourceUserId,
      params.sourceAccountSequence!,
      params.provinceCode,
      params.treeCount,
    );
    rewards.push(...provinceTeamRewards);

    // 7. 省区域权益 (108 USDT + 1%算力) - 可能返回多条记录（考核分配）
    const provinceAreaRewards = await this.calculateProvinceAreaRight(
      params.sourceOrderNo,
      params.sourceUserId,
      params.sourceAccountSequence!,
      params.provinceCode,
      params.treeCount,
    );
    rewards.push(...provinceAreaRewards);

    // 8. 市团队权益 (288 USDT) - 可能返回多条记录（考核分配）
    const cityTeamRewards = await this.calculateCityTeamRight(
      params.sourceOrderNo,
      params.sourceUserId,
      params.sourceAccountSequence!,
      params.cityCode,
      params.treeCount,
    );
    rewards.push(...cityTeamRewards);

    // 9. 市区域权益 (252 USDT + 2%算力) - 可能返回多条记录（考核分配）
    const cityAreaRewards = await this.calculateCityAreaRight(
      params.sourceOrderNo,
      params.sourceUserId,
      params.sourceAccountSequence!,
      params.cityCode,
      params.treeCount,
    );
    rewards.push(...cityAreaRewards);

    // 10. 社区权益 (576 USDT) - 可能返回多条记录（考核分配）
    const communityRewards = await this.calculateCommunityRight(
      params.sourceOrderNo,
      params.sourceUserId,
      params.sourceAccountSequence!,
      params.treeCount,
    );
    rewards.push(...communityRewards);

    // [2026-02-26] 11. 总部运营成本压力涨价（动态金额，归总部 S0000000001）
    if (params.priceSupplement && params.priceSupplement > 0) {
      const supplementReward = this.calculateHqPriceSupplement(
        params.sourceOrderNo,
        params.sourceUserId,
        params.sourceAccountSequence,
        params.treeCount,
        params.priceSupplement,
      );
      rewards.push(supplementReward);
    }

    this.logger.log(
      `[calculateRewards] DONE orderNo=${params.sourceOrderNo}, totalRewards=${rewards.length}`,
    );

    return rewards;
  }

  // ============================================
  // 系统费用计算方法
  // ============================================

  /**
   * 计算成本费 (2800 USDT)
   * 分配至指定成本账户
   */
  private calculateCostFee(
    sourceOrderNo: string,
    sourceUserId: bigint,
    sourceAccountSequence: string | undefined,
    treeCount: number,
  ): RewardLedgerEntry {
    const { usdt, hashpowerPercent } = RIGHT_AMOUNTS[RightType.COST_FEE];
    const usdtAmount = Money.USDT(usdt * treeCount);
    const hashpower = Hashpower.fromTreeCount(treeCount, hashpowerPercent);

    const rewardSource = RewardSource.create(
      RightType.COST_FEE,
      sourceOrderNo,
      sourceUserId,
      sourceAccountSequence,
    );

    return RewardLedgerEntry.createSettleable({
      userId: COST_FEE_ACCOUNT_ID,
      accountSequence: 'S0000000002',
      rewardSource,
      usdtAmount,
      hashpowerAmount: hashpower,
      memo: `成本费：来自用户${sourceAccountSequence || sourceUserId}的认种，${treeCount}棵树`,
    });
  }

  /**
   * 计算运营费 (2100 USDT)
   * 分配至指定运营账户
   */
  private calculateOperationFee(
    sourceOrderNo: string,
    sourceUserId: bigint,
    sourceAccountSequence: string | undefined,
    treeCount: number,
  ): RewardLedgerEntry {
    const { usdt, hashpowerPercent } = RIGHT_AMOUNTS[RightType.OPERATION_FEE];
    const usdtAmount = Money.USDT(usdt * treeCount);
    const hashpower = Hashpower.fromTreeCount(treeCount, hashpowerPercent);

    const rewardSource = RewardSource.create(
      RightType.OPERATION_FEE,
      sourceOrderNo,
      sourceUserId,
      sourceAccountSequence,
    );

    return RewardLedgerEntry.createSettleable({
      userId: OPERATION_FEE_ACCOUNT_ID,
      accountSequence: 'S0000000003',
      rewardSource,
      usdtAmount,
      hashpowerAmount: hashpower,
      memo: `运营费：来自用户${sourceAccountSequence || sourceUserId}的认种，${treeCount}棵树`,
    });
  }

  /**
   * 计算总部社区基础费 (203 USDT)
   * 分配至总部社区账户
   */
  private calculateHeadquartersBaseFee(
    sourceOrderNo: string,
    sourceUserId: bigint,
    sourceAccountSequence: string | undefined,
    treeCount: number,
  ): RewardLedgerEntry {
    const { usdt, hashpowerPercent } = RIGHT_AMOUNTS[RightType.HEADQUARTERS_BASE_FEE];
    const usdtAmount = Money.USDT(usdt * treeCount);
    const hashpower = Hashpower.fromTreeCount(treeCount, hashpowerPercent);

    const rewardSource = RewardSource.create(
      RightType.HEADQUARTERS_BASE_FEE,
      sourceOrderNo,
      sourceUserId,
      sourceAccountSequence,
    );

    return RewardLedgerEntry.createSettleable({
      userId: HEADQUARTERS_COMMUNITY_USER_ID,
      accountSequence: 'S0000000001',
      rewardSource,
      usdtAmount,
      hashpowerAmount: hashpower,
      memo: `总部社区基础费：来自用户${sourceAccountSequence || sourceUserId}的认种，${treeCount}棵树`,
    });
  }

  /**
   * 计算RWAD底池注入 (5760 USDT)
   * 注入RWAD 1号底池
   */
  private calculateRwadPoolInjection(
    sourceOrderNo: string,
    sourceUserId: bigint,
    sourceAccountSequence: string | undefined,
    treeCount: number,
  ): RewardLedgerEntry {
    const { usdt, hashpowerPercent } = RIGHT_AMOUNTS[RightType.RWAD_POOL_INJECTION];
    const usdtAmount = Money.USDT(usdt * treeCount);
    const hashpower = Hashpower.fromTreeCount(treeCount, hashpowerPercent);

    const rewardSource = RewardSource.create(
      RightType.RWAD_POOL_INJECTION,
      sourceOrderNo,
      sourceUserId,
      sourceAccountSequence,
    );

    return RewardLedgerEntry.createSettleable({
      userId: RWAD_POOL_ACCOUNT_ID,
      accountSequence: 'S0000000004',
      rewardSource,
      usdtAmount,
      hashpowerAmount: hashpower,
      memo: `RWAD底池注入：来自用户${sourceAccountSequence || sourceUserId}的认种，${treeCount}棵树，5760U注入1号底池`,
    });
  }

  /**
   * [2026-02-26] 计算总部运营成本压力涨价
   * 动态金额，全额归总部 (S0000000001)
   * 不影响基础 10 类分配，纯增量
   */
  private calculateHqPriceSupplement(
    sourceOrderNo: string,
    sourceUserId: bigint,
    sourceAccountSequence: string | undefined,
    treeCount: number,
    priceSupplement: number,
  ): RewardLedgerEntry {
    const usdtAmount = Money.USDT(priceSupplement * treeCount);
    const hashpower = Hashpower.fromTreeCount(treeCount, 0); // 涨价部分无算力

    const rewardSource = RewardSource.create(
      RightType.HQ_PRICE_SUPPLEMENT,
      sourceOrderNo,
      sourceUserId,
      sourceAccountSequence,
    );

    return RewardLedgerEntry.createSettleable({
      userId: HEADQUARTERS_COMMUNITY_USER_ID,
      accountSequence: 'S0000000001',
      rewardSource,
      usdtAmount,
      hashpowerAmount: hashpower,
      memo: `总部运营成本压力涨价：来自用户${sourceAccountSequence || sourceUserId}的认种，${treeCount}棵树，每棵加价${priceSupplement}U`,
    });
  }

  // ============================================
  // 用户权益计算方法
  // ============================================

  /**
   * 计算分享权益 (3600 USDT)
   */
  private async calculateShareRights(
    sourceOrderNo: string,
    sourceUserId: bigint,
    sourceAccountSequence: string | undefined,
    treeCount: number,
  ): Promise<RewardLedgerEntry[]> {
    this.logger.debug(`[calculateShareRights] userId=${sourceUserId}, accountSequence=${sourceAccountSequence}, treeCount=${treeCount}`);

    const { usdt, hashpowerPercent } = RIGHT_AMOUNTS[RightType.SHARE_RIGHT];
    const usdtAmount = Money.USDT(usdt * treeCount);
    const hashpower = Hashpower.fromTreeCount(treeCount, hashpowerPercent);

    const rewardSource = RewardSource.create(
      RightType.SHARE_RIGHT,
      sourceOrderNo,
      sourceUserId,
      sourceAccountSequence,
    );

    // 使用 accountSequence 获取推荐链（优先），否则用 userId
    const queryId = sourceAccountSequence || sourceUserId.toString();
    this.logger.debug(`[calculateShareRights] querying referral chain with: ${queryId}`);
    const referralChain = await this.referralService.getReferralChain(queryId);

    if (referralChain.ancestors.length > 0) {
      const directReferrer = referralChain.ancestors[0];

      if (directReferrer.hasPlanted) {
        // 推荐人已认种，直接可结算
        this.logger.debug(
          `[calculateShareRights] referrer=${directReferrer.userId} (${directReferrer.accountSequence}) hasPlanted=true -> SETTLEABLE`,
        );
        return [RewardLedgerEntry.createSettleable({
          userId: directReferrer.userId,
          accountSequence: directReferrer.accountSequence,
          rewardSource,
          usdtAmount,
          hashpowerAmount: hashpower,
          memo: `分享权益：来自用户${sourceAccountSequence || sourceUserId}的认种`,
        })];
      } else {
        // 推荐人未认种，进入待领取（24h倒计时）
        this.logger.debug(
          `[calculateShareRights] referrer=${directReferrer.userId} (${directReferrer.accountSequence}) hasPlanted=false -> PENDING (24h)`,
        );
        return [RewardLedgerEntry.createPending({
          userId: directReferrer.userId,
          accountSequence: directReferrer.accountSequence,
          rewardSource,
          usdtAmount,
          hashpowerAmount: hashpower,
          memo: `分享权益：来自用户${sourceAccountSequence || sourceUserId}的认种（24h内认种可领取）`,
        })];
      }
    } else {
      // 无推荐人，进分享权益池 (S0000000005)
      this.logger.debug(`[calculateShareRights] no referrer -> SHARE_RIGHT_POOL (S0000000005)`);
      return [RewardLedgerEntry.createSettleable({
        userId: SHARE_RIGHT_POOL_USER_ID,
        accountSequence: 'S0000000005',
        rewardSource,
        usdtAmount,
        hashpowerAmount: hashpower,
        memo: '分享权益：无推荐人，进分享权益池',
      })];
    }
  }

  /**
   * 计算省团队权益 (144 USDT)
   * 根据考核规则（500棵初审），可能返回多条分配记录
   */
  private async calculateProvinceTeamRight(
    sourceOrderNo: string,
    sourceUserId: bigint,
    sourceAccountSequence: string,
    provinceCode: string,
    treeCount: number,
  ): Promise<RewardLedgerEntry[]> {
    this.logger.debug(
      `[calculateProvinceTeamRight] accountSequence=${sourceAccountSequence}, province=${provinceCode}, treeCount=${treeCount}`,
    );

    const { usdt, hashpowerPercent } = RIGHT_AMOUNTS[RightType.PROVINCE_TEAM_RIGHT];

    // 调用 authorization-service 获取省团队权益分配方案
    const distribution = await this.authorizationService.getProvinceTeamRewardDistribution(
      sourceAccountSequence,
      provinceCode,
      treeCount,
    );

    this.logger.debug(
      `[calculateProvinceTeamRight] distribution: ${JSON.stringify(distribution.distributions)}`,
    );

    const rewards: RewardLedgerEntry[] = [];

    // 根据分配方案创建奖励记录
    for (const item of distribution.distributions) {
      const itemUsdtAmount = Money.USDT(usdt * item.treeCount);
      const itemHashpower = Hashpower.fromTreeCount(item.treeCount, hashpowerPercent);

      const rewardSource = RewardSource.create(
        RightType.PROVINCE_TEAM_RIGHT,
        sourceOrderNo,
        sourceUserId,
        sourceAccountSequence,
      );

      rewards.push(
        RewardLedgerEntry.createSettleable({
          userId: this.parseAccountSequenceToUserId(item.accountSequence),
          accountSequence: item.accountSequence,
          rewardSource,
          usdtAmount: itemUsdtAmount,
          hashpowerAmount: itemHashpower,
          memo: `省团队权益(${provinceCode})：来自用户${sourceAccountSequence}的认种`,
        }),
      );
    }

    return rewards;
  }

  /**
   * 计算省区域权益 (108 USDT + 1%算力)
   * 根据考核规则（50000棵），可能返回多条分配记录
   * - 未达标：进系统省账户
   * - 已达标：进正式省公司账户
   */
  private async calculateProvinceAreaRight(
    sourceOrderNo: string,
    sourceUserId: bigint,
    sourceAccountSequence: string,
    provinceCode: string,
    treeCount: number,
  ): Promise<RewardLedgerEntry[]> {
    this.logger.debug(
      `[calculateProvinceAreaRight] province=${provinceCode}, treeCount=${treeCount}`,
    );

    const { usdt, hashpowerPercent } = RIGHT_AMOUNTS[RightType.PROVINCE_AREA_RIGHT];

    // 调用 authorization-service 获取省区域权益分配方案
    const distribution = await this.authorizationService.getProvinceAreaRewardDistribution(
      provinceCode,
      treeCount,
    );

    this.logger.debug(
      `[calculateProvinceAreaRight] distribution: ${JSON.stringify(distribution.distributions)}`,
    );

    const rewards: RewardLedgerEntry[] = [];

    // 根据分配方案创建奖励记录
    for (const item of distribution.distributions) {
      const itemUsdtAmount = Money.USDT(usdt * item.treeCount);
      const itemHashpower = Hashpower.fromTreeCount(item.treeCount, hashpowerPercent);

      const rewardSource = RewardSource.create(
        RightType.PROVINCE_AREA_RIGHT,
        sourceOrderNo,
        sourceUserId,
        sourceAccountSequence,
      );

      rewards.push(
        RewardLedgerEntry.createSettleable({
          userId: this.parseAccountSequenceToUserId(item.accountSequence),
          accountSequence: item.accountSequence,
          rewardSource,
          usdtAmount: itemUsdtAmount,
          hashpowerAmount: itemHashpower,
          memo: `省区域权益(${provinceCode})：来自用户${sourceAccountSequence}的认种`,
        }),
      );
    }

    return rewards;
  }

  /**
   * 计算市团队权益 (288 USDT)
   * 根据考核规则（100棵初审），可能返回多条分配记录
   */
  private async calculateCityTeamRight(
    sourceOrderNo: string,
    sourceUserId: bigint,
    sourceAccountSequence: string,
    cityCode: string,
    treeCount: number,
  ): Promise<RewardLedgerEntry[]> {
    this.logger.debug(
      `[calculateCityTeamRight] accountSequence=${sourceAccountSequence}, city=${cityCode}, treeCount=${treeCount}`,
    );

    const { usdt, hashpowerPercent } = RIGHT_AMOUNTS[RightType.CITY_TEAM_RIGHT];

    // 调用 authorization-service 获取市团队权益分配方案
    const distribution = await this.authorizationService.getCityTeamRewardDistribution(
      sourceAccountSequence,
      cityCode,
      treeCount,
    );

    this.logger.debug(
      `[calculateCityTeamRight] distribution: ${JSON.stringify(distribution.distributions)}`,
    );

    const rewards: RewardLedgerEntry[] = [];

    // 根据分配方案创建奖励记录
    for (const item of distribution.distributions) {
      const itemUsdtAmount = Money.USDT(usdt * item.treeCount);
      const itemHashpower = Hashpower.fromTreeCount(item.treeCount, hashpowerPercent);

      const rewardSource = RewardSource.create(
        RightType.CITY_TEAM_RIGHT,
        sourceOrderNo,
        sourceUserId,
        sourceAccountSequence,
      );

      rewards.push(
        RewardLedgerEntry.createSettleable({
          userId: this.parseAccountSequenceToUserId(item.accountSequence),
          accountSequence: item.accountSequence,
          rewardSource,
          usdtAmount: itemUsdtAmount,
          hashpowerAmount: itemHashpower,
          memo: `市团队权益(${cityCode})：来自用户${sourceAccountSequence}的认种`,
        }),
      );
    }

    return rewards;
  }

  /**
   * 计算市区域权益 (252 USDT + 2%算力)
   * 根据考核规则（10000棵），可能返回多条分配记录
   * - 未达标：进系统市账户
   * - 已达标：进正式市公司账户
   */
  private async calculateCityAreaRight(
    sourceOrderNo: string,
    sourceUserId: bigint,
    sourceAccountSequence: string,
    cityCode: string,
    treeCount: number,
  ): Promise<RewardLedgerEntry[]> {
    this.logger.debug(
      `[calculateCityAreaRight] city=${cityCode}, treeCount=${treeCount}`,
    );

    const { usdt, hashpowerPercent } = RIGHT_AMOUNTS[RightType.CITY_AREA_RIGHT];

    // 调用 authorization-service 获取市区域权益分配方案
    const distribution = await this.authorizationService.getCityAreaRewardDistribution(
      cityCode,
      treeCount,
    );

    this.logger.debug(
      `[calculateCityAreaRight] distribution: ${JSON.stringify(distribution.distributions)}`,
    );

    const rewards: RewardLedgerEntry[] = [];

    // 根据分配方案创建奖励记录
    for (const item of distribution.distributions) {
      const itemUsdtAmount = Money.USDT(usdt * item.treeCount);
      const itemHashpower = Hashpower.fromTreeCount(item.treeCount, hashpowerPercent);

      const rewardSource = RewardSource.create(
        RightType.CITY_AREA_RIGHT,
        sourceOrderNo,
        sourceUserId,
        sourceAccountSequence,
      );

      rewards.push(
        RewardLedgerEntry.createSettleable({
          userId: this.parseAccountSequenceToUserId(item.accountSequence),
          accountSequence: item.accountSequence,
          rewardSource,
          usdtAmount: itemUsdtAmount,
          hashpowerAmount: itemHashpower,
          memo: `市区域权益(${cityCode})：来自用户${sourceAccountSequence}的认种`,
        }),
      );
    }

    return rewards;
  }

  /**
   * 计算社区权益 (576 USDT)
   * 根据考核规则，可能返回多条分配记录：
   * - 权益已激活：全部给该社区
   * - 权益未激活：考核前的部分给上级社区/总部，考核后的部分给该社区
   */
  private async calculateCommunityRight(
    sourceOrderNo: string,
    sourceUserId: bigint,
    sourceAccountSequence: string,
    treeCount: number,
  ): Promise<RewardLedgerEntry[]> {
    this.logger.debug(
      `[calculateCommunityRight] accountSequence=${sourceAccountSequence}, treeCount=${treeCount}`,
    );

    const { usdt, hashpowerPercent } = RIGHT_AMOUNTS[RightType.COMMUNITY_RIGHT];

    // 调用 authorization-service 获取社区权益分配方案
    const distribution = await this.authorizationService.getCommunityRewardDistribution(
      sourceAccountSequence,
      treeCount,
    );

    this.logger.debug(
      `[calculateCommunityRight] distribution: ${JSON.stringify(distribution.distributions)}`,
    );

    const rewards: RewardLedgerEntry[] = [];

    // 根据分配方案创建奖励记录
    for (const item of distribution.distributions) {
      const itemUsdtAmount = Money.USDT(usdt * item.treeCount);
      const itemHashpower = Hashpower.fromTreeCount(item.treeCount, hashpowerPercent);

      const rewardSource = RewardSource.create(
        RightType.COMMUNITY_RIGHT,
        sourceOrderNo,
        sourceUserId,
        sourceAccountSequence,
      );

      rewards.push(
        RewardLedgerEntry.createSettleable({
          userId: this.parseAccountSequenceToUserId(item.accountSequence),
          accountSequence: item.accountSequence,
          rewardSource,
          usdtAmount: itemUsdtAmount,
          hashpowerAmount: itemHashpower,
          memo: `社区权益：来自用户${sourceAccountSequence}的认种`,
        }),
      );
    }

    return rewards;
  }

  // ============================================
  // 合同超时场景的奖励计算
  // ============================================

  /**
   * 计算合同超时未签署时的奖励分配
   *
   * 与正常流程的区别：
   * - 系统费用（成本费、运营费、底池、总部基础费）：正常分配到系统账户
   * - 用户权益：全部分配到系统默认账户，不分给真正的推荐人/团队
   *
   * 系统默认账户规则：
   * - 分享权益 3600 → S0000000005（分享权益池）
   * - 省团队权益 144 → 7+省代码（省团队默认账户）
   * - 市团队权益 288 → 6+市代码（市团队默认账户）
   * - 社区权益 576 → S0000000001（总部社区）
   * - 省区域权益 108 → 9+省代码（省区域账户）
   * - 市区域权益 252 → 8+市代码（市区域账户）
   */
  async calculateRewardsForExpiredContract(params: {
    sourceOrderNo: string;
    sourceUserId: bigint;
    sourceAccountSequence?: string;
    treeCount: number;
    provinceCode: string;
    cityCode: string;
    priceSupplement?: number; // [2026-02-26] 总部运营成本压力涨价
  }): Promise<RewardLedgerEntry[]> {
    this.logger.log(
      `[calculateRewardsForExpiredContract] START orderNo=${params.sourceOrderNo}, userId=${params.sourceUserId}, ` +
      `treeCount=${params.treeCount}, province=${params.provinceCode}, city=${params.cityCode}`,
    );

    const rewards: RewardLedgerEntry[] = [];

    // ============================================
    // 系统费用类 (10863 USDT) - 正常分配
    // ============================================

    // 1. 成本费 (2800 USDT) → S0000000002
    rewards.push(this.calculateCostFee(
      params.sourceOrderNo,
      params.sourceUserId,
      params.sourceAccountSequence,
      params.treeCount,
    ));

    // 2. 运营费 (2100 USDT) → S0000000003
    rewards.push(this.calculateOperationFee(
      params.sourceOrderNo,
      params.sourceUserId,
      params.sourceAccountSequence,
      params.treeCount,
    ));

    // 3. 总部社区基础费 (203 USDT) → S0000000001
    rewards.push(this.calculateHeadquartersBaseFee(
      params.sourceOrderNo,
      params.sourceUserId,
      params.sourceAccountSequence,
      params.treeCount,
    ));

    // 4. RWAD底池注入 (5760 USDT) → S0000000004
    rewards.push(this.calculateRwadPoolInjection(
      params.sourceOrderNo,
      params.sourceUserId,
      params.sourceAccountSequence,
      params.treeCount,
    ));

    // ============================================
    // 用户权益类 (4968 USDT) - 全部进入系统默认账户
    // ============================================

    // 5. 分享权益 (3600 USDT) → S0000000005（分享权益池）
    rewards.push(this.calculateShareRightToSystemAccount(
      params.sourceOrderNo,
      params.sourceUserId,
      params.sourceAccountSequence,
      params.treeCount,
    ));

    // 6. 省团队权益 (144 USDT) → 7+省代码
    rewards.push(this.calculateProvinceTeamRightToSystemAccount(
      params.sourceOrderNo,
      params.sourceUserId,
      params.sourceAccountSequence,
      params.provinceCode,
      params.treeCount,
    ));

    // 7. 省区域权益 (108 USDT + 1%算力) → 9+省代码
    rewards.push(this.calculateProvinceAreaRightToSystemAccount(
      params.sourceOrderNo,
      params.sourceUserId,
      params.sourceAccountSequence,
      params.provinceCode,
      params.treeCount,
    ));

    // 8. 市团队权益 (288 USDT) → 6+市代码
    rewards.push(this.calculateCityTeamRightToSystemAccount(
      params.sourceOrderNo,
      params.sourceUserId,
      params.sourceAccountSequence,
      params.cityCode,
      params.treeCount,
    ));

    // 9. 市区域权益 (252 USDT + 2%算力) → 8+市代码
    rewards.push(this.calculateCityAreaRightToSystemAccount(
      params.sourceOrderNo,
      params.sourceUserId,
      params.sourceAccountSequence,
      params.cityCode,
      params.treeCount,
    ));

    // 10. 社区权益 (576 USDT) → S0000000001（总部社区）
    rewards.push(this.calculateCommunityRightToSystemAccount(
      params.sourceOrderNo,
      params.sourceUserId,
      params.sourceAccountSequence,
      params.treeCount,
    ));

    // [2026-02-26] 11. 总部运营成本压力涨价（动态金额，归总部 S0000000001）
    if (params.priceSupplement && params.priceSupplement > 0) {
      rewards.push(this.calculateHqPriceSupplement(
        params.sourceOrderNo,
        params.sourceUserId,
        params.sourceAccountSequence,
        params.treeCount,
        params.priceSupplement,
      ));
    }

    this.logger.log(
      `[calculateRewardsForExpiredContract] DONE orderNo=${params.sourceOrderNo}, totalRewards=${rewards.length}`,
    );

    return rewards;
  }

  // ============================================
  // 合同超时场景的用户权益计算（进入系统账户）
  // ============================================

  /**
   * 分享权益进入分享权益池
   */
  private calculateShareRightToSystemAccount(
    sourceOrderNo: string,
    sourceUserId: bigint,
    sourceAccountSequence: string | undefined,
    treeCount: number,
  ): RewardLedgerEntry {
    const { usdt, hashpowerPercent } = RIGHT_AMOUNTS[RightType.SHARE_RIGHT];
    const usdtAmount = Money.USDT(usdt * treeCount);
    const hashpower = Hashpower.fromTreeCount(treeCount, hashpowerPercent);

    const rewardSource = RewardSource.create(
      RightType.SHARE_RIGHT,
      sourceOrderNo,
      sourceUserId,
      sourceAccountSequence,
    );

    return RewardLedgerEntry.createSettleable({
      userId: SHARE_RIGHT_POOL_USER_ID,
      accountSequence: 'S0000000005',
      rewardSource,
      usdtAmount,
      hashpowerAmount: hashpower,
      memo: `分享权益：合同超时未签署，进分享权益池`,
    });
  }

  /**
   * 省团队权益进入省团队默认账户 (7+省代码)
   */
  private calculateProvinceTeamRightToSystemAccount(
    sourceOrderNo: string,
    sourceUserId: bigint,
    sourceAccountSequence: string | undefined,
    provinceCode: string,
    treeCount: number,
  ): RewardLedgerEntry {
    const { usdt, hashpowerPercent } = RIGHT_AMOUNTS[RightType.PROVINCE_TEAM_RIGHT];
    const usdtAmount = Money.USDT(usdt * treeCount);
    const hashpower = Hashpower.fromTreeCount(treeCount, hashpowerPercent);

    const rewardSource = RewardSource.create(
      RightType.PROVINCE_TEAM_RIGHT,
      sourceOrderNo,
      sourceUserId,
      sourceAccountSequence,
    );

    // 省团队默认账户: 7 + 省代码
    const accountSequence = `7${provinceCode}`;

    return RewardLedgerEntry.createSettleable({
      userId: BigInt(accountSequence),
      accountSequence,
      rewardSource,
      usdtAmount,
      hashpowerAmount: hashpower,
      memo: `省团队权益(${provinceCode})：合同超时未签署，进省团队默认账户`,
    });
  }

  /**
   * 省区域权益进入省区域账户 (9+省代码)
   */
  private calculateProvinceAreaRightToSystemAccount(
    sourceOrderNo: string,
    sourceUserId: bigint,
    sourceAccountSequence: string | undefined,
    provinceCode: string,
    treeCount: number,
  ): RewardLedgerEntry {
    const { usdt, hashpowerPercent } = RIGHT_AMOUNTS[RightType.PROVINCE_AREA_RIGHT];
    const usdtAmount = Money.USDT(usdt * treeCount);
    const hashpower = Hashpower.fromTreeCount(treeCount, hashpowerPercent);

    const rewardSource = RewardSource.create(
      RightType.PROVINCE_AREA_RIGHT,
      sourceOrderNo,
      sourceUserId,
      sourceAccountSequence,
    );

    // 省区域账户: 9 + 省代码
    const accountSequence = `9${provinceCode}`;

    return RewardLedgerEntry.createSettleable({
      userId: BigInt(accountSequence),
      accountSequence,
      rewardSource,
      usdtAmount,
      hashpowerAmount: hashpower,
      memo: `省区域权益(${provinceCode})：合同超时未签署，进省区域账户`,
    });
  }

  /**
   * 市团队权益进入市团队默认账户 (6+市代码)
   */
  private calculateCityTeamRightToSystemAccount(
    sourceOrderNo: string,
    sourceUserId: bigint,
    sourceAccountSequence: string | undefined,
    cityCode: string,
    treeCount: number,
  ): RewardLedgerEntry {
    const { usdt, hashpowerPercent } = RIGHT_AMOUNTS[RightType.CITY_TEAM_RIGHT];
    const usdtAmount = Money.USDT(usdt * treeCount);
    const hashpower = Hashpower.fromTreeCount(treeCount, hashpowerPercent);

    const rewardSource = RewardSource.create(
      RightType.CITY_TEAM_RIGHT,
      sourceOrderNo,
      sourceUserId,
      sourceAccountSequence,
    );

    // 市团队默认账户: 6 + 市代码
    const accountSequence = `6${cityCode}`;

    return RewardLedgerEntry.createSettleable({
      userId: BigInt(accountSequence),
      accountSequence,
      rewardSource,
      usdtAmount,
      hashpowerAmount: hashpower,
      memo: `市团队权益(${cityCode})：合同超时未签署，进市团队默认账户`,
    });
  }

  /**
   * 市区域权益进入市区域账户 (8+市代码)
   */
  private calculateCityAreaRightToSystemAccount(
    sourceOrderNo: string,
    sourceUserId: bigint,
    sourceAccountSequence: string | undefined,
    cityCode: string,
    treeCount: number,
  ): RewardLedgerEntry {
    const { usdt, hashpowerPercent } = RIGHT_AMOUNTS[RightType.CITY_AREA_RIGHT];
    const usdtAmount = Money.USDT(usdt * treeCount);
    const hashpower = Hashpower.fromTreeCount(treeCount, hashpowerPercent);

    const rewardSource = RewardSource.create(
      RightType.CITY_AREA_RIGHT,
      sourceOrderNo,
      sourceUserId,
      sourceAccountSequence,
    );

    // 市区域账户: 8 + 市代码
    const accountSequence = `8${cityCode}`;

    return RewardLedgerEntry.createSettleable({
      userId: BigInt(accountSequence),
      accountSequence,
      rewardSource,
      usdtAmount,
      hashpowerAmount: hashpower,
      memo: `市区域权益(${cityCode})：合同超时未签署，进市区域账户`,
    });
  }

  /**
   * 社区权益进入总部社区 (S0000000001)
   */
  private calculateCommunityRightToSystemAccount(
    sourceOrderNo: string,
    sourceUserId: bigint,
    sourceAccountSequence: string | undefined,
    treeCount: number,
  ): RewardLedgerEntry {
    const { usdt, hashpowerPercent } = RIGHT_AMOUNTS[RightType.COMMUNITY_RIGHT];
    const usdtAmount = Money.USDT(usdt * treeCount);
    const hashpower = Hashpower.fromTreeCount(treeCount, hashpowerPercent);

    const rewardSource = RewardSource.create(
      RightType.COMMUNITY_RIGHT,
      sourceOrderNo,
      sourceUserId,
      sourceAccountSequence,
    );

    return RewardLedgerEntry.createSettleable({
      userId: HEADQUARTERS_COMMUNITY_USER_ID,
      accountSequence: 'S0000000001',
      rewardSource,
      usdtAmount,
      hashpowerAmount: hashpower,
      memo: `社区权益：合同超时未签署，进总部社区`,
    });
  }
}
