import { Injectable } from '@nestjs/common';
import { FundAllocation } from '../value-objects/fund-allocation.vo';
import {
  FundAllocationTargetType,
  FUND_ALLOCATION_AMOUNTS,
} from '../value-objects/fund-allocation-target-type.enum';
import { PlantingOrder } from '../aggregates/planting-order.aggregate';

export interface ReferralContext {
  referralChain: string[];
  nearestProvinceAuth: string | null;
  nearestCityAuth: string | null;
  nearestCommunity: string | null;
}

// 增强的授权上下文，用于支持更精确的分配
export interface EnhancedAllocationContext extends ReferralContext {
  // 直接推荐人ID
  directReferrerId: string | null;
  // 省区域权益接收方（正式省公司或系统省账户）
  provinceAreaRecipient: {
    type: 'USER' | 'SYSTEM';
    id: string;
    hashpowerPercent: number; // 1% for 正式省公司
  };
  // 省团队权益接收方（授权省公司或系统省账户）
  provinceTeamRecipient: {
    type: 'USER' | 'SYSTEM';
    id: string;
  };
  // 市区域权益接收方（正式市公司或系统市账户）
  cityAreaRecipient: {
    type: 'USER' | 'SYSTEM';
    id: string;
    hashpowerPercent: number; // 2% for 正式市公司
  };
  // 市团队权益接收方（授权市公司或系统市账户）
  cityTeamRecipient: {
    type: 'USER' | 'SYSTEM';
    id: string;
  };
  // 社区权益接收方（社区授权或运营账户）
  communityRecipient: {
    type: 'USER' | 'SYSTEM';
    id: string;
  } | null;
}

@Injectable()
export class FundAllocationDomainService {
  /**
   * 计算认种订单的资金分配
   * 核心业务规则: 2199 USDT 的 10 个去向
   */
  calculateAllocations(
    order: PlantingOrder,
    context: ReferralContext,
  ): FundAllocation[] {
    const treeCount = order.treeCount.value;
    const allocations: FundAllocation[] = [];
    const selection = order.provinceCitySelection;

    if (!selection) {
      throw new Error('订单未选择省市，无法计算资金分配');
    }

    // 1. 成本账户: 2800 USDT/棵
    allocations.push(
      new FundAllocation(
        FundAllocationTargetType.COST_ACCOUNT,
        FUND_ALLOCATION_AMOUNTS[FundAllocationTargetType.COST_ACCOUNT] *
          treeCount,
        'SYSTEM_COST_ACCOUNT',
      ),
    );

    // 2. 运营账户: 2100 USDT/棵
    allocations.push(
      new FundAllocation(
        FundAllocationTargetType.OPERATION_ACCOUNT,
        FUND_ALLOCATION_AMOUNTS[FundAllocationTargetType.OPERATION_ACCOUNT] *
          treeCount,
        'SYSTEM_OPERATION_ACCOUNT',
      ),
    );

    // 3. 总部社区: 203 USDT/棵
    allocations.push(
      new FundAllocation(
        FundAllocationTargetType.HEADQUARTERS_COMMUNITY,
        FUND_ALLOCATION_AMOUNTS[
          FundAllocationTargetType.HEADQUARTERS_COMMUNITY
        ] * treeCount,
        'SYSTEM_HEADQUARTERS_COMMUNITY',
      ),
    );

    // 4. 分享权益: 3600 USDT/棵 (分配给推荐链)
    // 无推荐人时进入分享权益池 SYSTEM_SHARE_RIGHT_POOL
    allocations.push(
      new FundAllocation(
        FundAllocationTargetType.REFERRAL_RIGHTS,
        FUND_ALLOCATION_AMOUNTS[FundAllocationTargetType.REFERRAL_RIGHTS] *
          treeCount,
        context.referralChain.length > 0
          ? context.referralChain[0]
          : 'SYSTEM_SHARE_RIGHT_POOL',
        { referralChain: context.referralChain },
      ),
    );

    // 5. 省区域权益: 108 USDT/棵
    allocations.push(
      new FundAllocation(
        FundAllocationTargetType.PROVINCE_AREA_RIGHTS,
        FUND_ALLOCATION_AMOUNTS[FundAllocationTargetType.PROVINCE_AREA_RIGHTS] *
          treeCount,
        `SYSTEM_PROVINCE_${selection.provinceCode}`,
      ),
    );

    // 6. 省团队权益: 144 USDT/棵
    allocations.push(
      new FundAllocation(
        FundAllocationTargetType.PROVINCE_TEAM_RIGHTS,
        FUND_ALLOCATION_AMOUNTS[FundAllocationTargetType.PROVINCE_TEAM_RIGHTS] *
          treeCount,
        context.nearestProvinceAuth || 'SYSTEM_HEADQUARTERS_COMMUNITY',
      ),
    );

    // 7. 市区域权益: 252 USDT/棵
    allocations.push(
      new FundAllocation(
        FundAllocationTargetType.CITY_AREA_RIGHTS,
        FUND_ALLOCATION_AMOUNTS[FundAllocationTargetType.CITY_AREA_RIGHTS] *
          treeCount,
        `SYSTEM_CITY_${selection.cityCode}`,
      ),
    );

    // 8. 市团队权益: 288 USDT/棵
    allocations.push(
      new FundAllocation(
        FundAllocationTargetType.CITY_TEAM_RIGHTS,
        FUND_ALLOCATION_AMOUNTS[FundAllocationTargetType.CITY_TEAM_RIGHTS] *
          treeCount,
        context.nearestCityAuth || 'SYSTEM_HEADQUARTERS_COMMUNITY',
      ),
    );

    // 9. 社区权益: 576 USDT/棵
    allocations.push(
      new FundAllocation(
        FundAllocationTargetType.COMMUNITY_RIGHTS,
        FUND_ALLOCATION_AMOUNTS[FundAllocationTargetType.COMMUNITY_RIGHTS] *
          treeCount,
        context.nearestCommunity || 'SYSTEM_HEADQUARTERS_COMMUNITY',
      ),
    );

    // 10. RWAD底池: 5760 USDT/棵
    allocations.push(
      new FundAllocation(
        FundAllocationTargetType.RWAD_POOL,
        FUND_ALLOCATION_AMOUNTS[FundAllocationTargetType.RWAD_POOL] * treeCount,
        'SYSTEM_RWAD_POOL',
      ),
    );

    // [2026-02-26] 总部运营成本压力涨价：加价部分全额归总部 (S0000000001)
    if (order.priceSupplement > 0) {
      allocations.push(
        new FundAllocation(
          FundAllocationTargetType.HQ_PRICE_SUPPLEMENT,
          order.priceSupplement * treeCount,
          'SYSTEM_HEADQUARTERS', // 总部 S0000000001
          { reason: '总部运营成本压力涨价' },
        ),
      );
    }

    // 验证总额（基础 15831 + 涨价补充）
    const total = allocations.reduce((sum, a) => sum + a.amount, 0);
    const expected = order.totalAmount;
    if (Math.abs(total - expected) > 0.01) {
      throw new Error(`资金分配计算错误: 总额 ${total} != ${expected}`);
    }

    return allocations;
  }

  /**
   * 获取底池注入金额
   */
  getPoolInjectionAmount(treeCount: number): number {
    return FUND_ALLOCATION_AMOUNTS[FundAllocationTargetType.RWAD_POOL] * treeCount;
  }

  /**
   * 使用增强的授权上下文计算资金分配
   * 支持更精确的省市社区权益分配
   */
  calculateAllocationsWithEnhancedContext(
    order: PlantingOrder,
    context: EnhancedAllocationContext,
  ): FundAllocation[] {
    const treeCount = order.treeCount.value;
    const allocations: FundAllocation[] = [];
    const selection = order.provinceCitySelection;

    if (!selection) {
      throw new Error('订单未选择省市，无法计算资金分配');
    }

    // 1. 成本账户: 2800 USDT/棵
    allocations.push(
      new FundAllocation(
        FundAllocationTargetType.COST_ACCOUNT,
        FUND_ALLOCATION_AMOUNTS[FundAllocationTargetType.COST_ACCOUNT] * treeCount,
        'SYSTEM:COST_ACCOUNT',
      ),
    );

    // 2. 运营账户: 2100 USDT/棵
    allocations.push(
      new FundAllocation(
        FundAllocationTargetType.OPERATION_ACCOUNT,
        FUND_ALLOCATION_AMOUNTS[FundAllocationTargetType.OPERATION_ACCOUNT] * treeCount,
        'SYSTEM:OPERATION_ACCOUNT',
      ),
    );

    // 3. 总部社区: 203 USDT/棵
    allocations.push(
      new FundAllocation(
        FundAllocationTargetType.HEADQUARTERS_COMMUNITY,
        FUND_ALLOCATION_AMOUNTS[FundAllocationTargetType.HEADQUARTERS_COMMUNITY] * treeCount,
        'SYSTEM:HQ_COMMUNITY',
      ),
    );

    // 4. 分享权益 (直推奖励): 3600 USDT/棵
    // 仅直推，无多级；无推荐人归入分享权益池
    const referralTarget = context.directReferrerId
      ? `USER:${context.directReferrerId}`
      : 'SYSTEM:SHARE_RIGHT_POOL';
    allocations.push(
      new FundAllocation(
        FundAllocationTargetType.REFERRAL_RIGHTS,
        FUND_ALLOCATION_AMOUNTS[FundAllocationTargetType.REFERRAL_RIGHTS] * treeCount,
        referralTarget,
        {
          isDirectReferral: !!context.directReferrerId,
          referrerId: context.directReferrerId,
        },
      ),
    );

    // 5. 省区域权益: 108 USDT/棵 + 1%算力（正式省公司才有算力）
    const provinceAreaTarget = context.provinceAreaRecipient.type === 'USER'
      ? `USER:${context.provinceAreaRecipient.id}`
      : `SYSTEM:SYSTEM_PROVINCE:${selection.provinceCode}`;
    allocations.push(
      new FundAllocation(
        FundAllocationTargetType.PROVINCE_AREA_RIGHTS,
        FUND_ALLOCATION_AMOUNTS[FundAllocationTargetType.PROVINCE_AREA_RIGHTS] * treeCount,
        provinceAreaTarget,
        {
          hashpowerPercent: context.provinceAreaRecipient.hashpowerPercent,
          provinceCode: selection.provinceCode,
        },
      ),
    );

    // 6. 省团队权益: 144 USDT/棵（授权省公司）
    const provinceTeamTarget = context.provinceTeamRecipient.type === 'USER'
      ? `USER:${context.provinceTeamRecipient.id}`
      : `SYSTEM:SYSTEM_PROVINCE:${selection.provinceCode}`;
    allocations.push(
      new FundAllocation(
        FundAllocationTargetType.PROVINCE_TEAM_RIGHTS,
        FUND_ALLOCATION_AMOUNTS[FundAllocationTargetType.PROVINCE_TEAM_RIGHTS] * treeCount,
        provinceTeamTarget,
        { provinceCode: selection.provinceCode },
      ),
    );

    // 7. 市区域权益: 252 USDT/棵 + 2%算力（正式市公司才有算力）
    const cityAreaTarget = context.cityAreaRecipient.type === 'USER'
      ? `USER:${context.cityAreaRecipient.id}`
      : `SYSTEM:SYSTEM_CITY:${selection.cityCode}`;
    allocations.push(
      new FundAllocation(
        FundAllocationTargetType.CITY_AREA_RIGHTS,
        FUND_ALLOCATION_AMOUNTS[FundAllocationTargetType.CITY_AREA_RIGHTS] * treeCount,
        cityAreaTarget,
        {
          hashpowerPercent: context.cityAreaRecipient.hashpowerPercent,
          cityCode: selection.cityCode,
        },
      ),
    );

    // 8. 市团队权益: 288 USDT/棵（授权市公司）
    const cityTeamTarget = context.cityTeamRecipient.type === 'USER'
      ? `USER:${context.cityTeamRecipient.id}`
      : `SYSTEM:SYSTEM_CITY:${selection.cityCode}`;
    allocations.push(
      new FundAllocation(
        FundAllocationTargetType.CITY_TEAM_RIGHTS,
        FUND_ALLOCATION_AMOUNTS[FundAllocationTargetType.CITY_TEAM_RIGHTS] * treeCount,
        cityTeamTarget,
        { cityCode: selection.cityCode },
      ),
    );

    // 9. 社区权益: 576 USDT/棵
    const communityTarget = context.communityRecipient && context.communityRecipient.type === 'USER'
      ? `USER:${context.communityRecipient.id}`
      : 'SYSTEM:OPERATION_ACCOUNT';
    allocations.push(
      new FundAllocation(
        FundAllocationTargetType.COMMUNITY_RIGHTS,
        FUND_ALLOCATION_AMOUNTS[FundAllocationTargetType.COMMUNITY_RIGHTS] * treeCount,
        communityTarget,
      ),
    );

    // 10. RWAD底池: 5760 USDT/棵
    allocations.push(
      new FundAllocation(
        FundAllocationTargetType.RWAD_POOL,
        FUND_ALLOCATION_AMOUNTS[FundAllocationTargetType.RWAD_POOL] * treeCount,
        'SYSTEM:RWAD_POOL_PENDING',
        { miningStartDelayDays: 30 },
      ),
    );

    // [2026-02-26] 总部运营成本压力涨价：加价部分全额归总部 (S0000000001)
    if (order.priceSupplement > 0) {
      allocations.push(
        new FundAllocation(
          FundAllocationTargetType.HQ_PRICE_SUPPLEMENT,
          order.priceSupplement * treeCount,
          'SYSTEM:HEADQUARTERS', // 总部 S0000000001
          { reason: '总部运营成本压力涨价' },
        ),
      );
    }

    // 验证总额（基础 15831 + 涨价补充）
    const total = allocations.reduce((sum, a) => sum + a.amount, 0);
    const expected = order.totalAmount;
    if (Math.abs(total - expected) > 0.01) {
      throw new Error(`资金分配计算错误: 总额 ${total} != ${expected}`);
    }

    return allocations;
  }
}
