import { Injectable } from '@nestjs/common';
import Decimal from 'decimal.js';
import { ContributionAccountRepository } from '../../infrastructure/persistence/repositories/contribution-account.repository';
import { ContributionRecordRepository } from '../../infrastructure/persistence/repositories/contribution-record.repository';
import { UnallocatedContributionRepository } from '../../infrastructure/persistence/repositories/unallocated-contribution.repository';
import { SystemAccountRepository } from '../../infrastructure/persistence/repositories/system-account.repository';
import { SyncedDataRepository } from '../../infrastructure/persistence/repositories/synced-data.repository';
import { ContributionSourceType } from '../../domain/aggregates/contribution-account.aggregate';

// 基准算力常量
const BASE_CONTRIBUTION_PER_TREE = new Decimal('22617');
const RATE_PERSONAL = new Decimal('0.70');
const RATE_OPERATION = new Decimal('0.12');
const RATE_PROVINCE = new Decimal('0.01');
const RATE_CITY = new Decimal('0.02');
const RATE_LEVEL_TOTAL = new Decimal('0.075');
const RATE_BONUS_TOTAL = new Decimal('0.075');

export interface ContributionStatsDto {
  // 用户统计
  totalUsers: number;
  totalAccounts: number;
  accountsWithContribution: number;

  // 认种统计
  totalAdoptions: number;
  processedAdoptions: number;
  unprocessedAdoptions: number;
  totalTrees: number;

  // 算力统计
  totalContribution: string;

  // 算力分布（基础）
  contributionByType: {
    personal: string;
    teamLevel: string;
    teamBonus: string;
  };

  // ========== 详细算力分解（按用户需求） ==========
  // 全网算力 = 总认种树 * 22617
  networkTotalContribution: string;
  // 个人用户总算力 = 总认种树 * (22617 * 70%)
  personalTotalContribution: string;
  // 运营账户总算力 = 总认种树 * (22617 * 12%)
  operationTotalContribution: string;
  // 省公司总算力 = 总认种树 * (22617 * 1%)
  provinceTotalContribution: string;
  // 市公司总算力 = 总认种树 * (22617 * 2%)
  cityTotalContribution: string;

  // 层级算力详情 (7.5%)
  levelContribution: {
    total: string;
    unlocked: string;
    pending: string;
    byTier: {
      // 1档: 1-5级
      tier1: { unlocked: string; pending: string };
      // 2档: 6-10级
      tier2: { unlocked: string; pending: string };
      // 3档: 11-15级
      tier3: { unlocked: string; pending: string };
    };
  };

  // 团队奖励算力详情 (7.5%)
  bonusContribution: {
    total: string;
    unlocked: string;
    pending: string;
    byTier: {
      tier1: { unlocked: string; pending: string };
      tier2: { unlocked: string; pending: string };
      tier3: { unlocked: string; pending: string };
    };
  };

  // 系统账户
  systemAccounts: {
    accountType: string;
    name: string;
    totalContribution: string;
  }[];

  // 未分配算力
  totalUnallocated: string;
  unallocatedByType: Record<string, string>;
}

@Injectable()
export class GetContributionStatsQuery {
  constructor(
    private readonly accountRepository: ContributionAccountRepository,
    private readonly recordRepository: ContributionRecordRepository,
    private readonly unallocatedRepository: UnallocatedContributionRepository,
    private readonly systemAccountRepository: SystemAccountRepository,
    private readonly syncedDataRepository: SyncedDataRepository,
  ) {}

  async execute(): Promise<ContributionStatsDto> {
    const [
      totalUsers,
      totalAccounts,
      accountsWithContribution,
      totalAdoptions,
      undistributedAdoptions,
      totalContribution,
      contributionByType,
      systemAccounts,
      totalUnallocated,
      unallocatedByType,
      detailedStats,
      unallocatedByLevelTier,
      unallocatedByBonusTier,
      totalTrees,
    ] = await Promise.all([
      this.syncedDataRepository.countUsers(),
      this.accountRepository.countAccounts(),
      this.accountRepository.countAccountsWithContribution(),
      this.syncedDataRepository.countAdoptions(),
      this.syncedDataRepository.countUndistributedAdoptions(),
      this.accountRepository.getTotalContribution(),
      this.recordRepository.getContributionSummaryBySourceType(),
      this.systemAccountRepository.findAll(),
      this.unallocatedRepository.getTotalUnallocated(),
      this.unallocatedRepository.getTotalUnallocatedByType(),
      this.accountRepository.getDetailedContributionStats(),
      this.unallocatedRepository.getUnallocatedByLevelTier(),
      this.unallocatedRepository.getUnallocatedByBonusTier(),
      this.syncedDataRepository.getTotalTrees(),
    ]);

    // 计算理论算力（基于总认种树 * 基准算力）
    const networkTotal = BASE_CONTRIBUTION_PER_TREE.mul(totalTrees);
    const personalTotal = networkTotal.mul(RATE_PERSONAL);
    const operationTotal = networkTotal.mul(RATE_OPERATION);
    const provinceTotal = networkTotal.mul(RATE_PROVINCE);
    const cityTotal = networkTotal.mul(RATE_CITY);
    const levelTotal = networkTotal.mul(RATE_LEVEL_TOTAL);
    const bonusTotal = networkTotal.mul(RATE_BONUS_TOTAL);

    // 层级算力: 已解锁 + 未解锁
    const levelUnlocked = new Decimal(detailedStats.levelUnlocked);
    const levelPending = new Decimal(unallocatedByLevelTier.tier1)
      .plus(unallocatedByLevelTier.tier2)
      .plus(unallocatedByLevelTier.tier3);

    // 团队奖励算力: 已解锁 + 未解锁
    const bonusUnlocked = new Decimal(detailedStats.bonusUnlocked);
    const bonusPending = new Decimal(unallocatedByBonusTier.tier1)
      .plus(unallocatedByBonusTier.tier2)
      .plus(unallocatedByBonusTier.tier3);

    return {
      totalUsers,
      totalAccounts,
      accountsWithContribution,
      totalAdoptions,
      processedAdoptions: totalAdoptions - undistributedAdoptions,
      unprocessedAdoptions: undistributedAdoptions,
      totalTrees,
      totalContribution: totalContribution.value.toString(),
      contributionByType: {
        personal: (contributionByType.get(ContributionSourceType.PERSONAL)?.value || 0).toString(),
        teamLevel: (contributionByType.get(ContributionSourceType.TEAM_LEVEL)?.value || 0).toString(),
        teamBonus: (contributionByType.get(ContributionSourceType.TEAM_BONUS)?.value || 0).toString(),
      },

      // 详细算力分解
      networkTotalContribution: networkTotal.toString(),
      personalTotalContribution: personalTotal.toString(),
      operationTotalContribution: operationTotal.toString(),
      provinceTotalContribution: provinceTotal.toString(),
      cityTotalContribution: cityTotal.toString(),

      // 层级算力详情
      levelContribution: {
        total: levelTotal.toString(),
        unlocked: levelUnlocked.toString(),
        pending: levelPending.toString(),
        byTier: {
          tier1: {
            unlocked: detailedStats.levelByTier.tier1.unlocked,
            pending: unallocatedByLevelTier.tier1,
          },
          tier2: {
            unlocked: detailedStats.levelByTier.tier2.unlocked,
            pending: unallocatedByLevelTier.tier2,
          },
          tier3: {
            unlocked: detailedStats.levelByTier.tier3.unlocked,
            pending: unallocatedByLevelTier.tier3,
          },
        },
      },

      // 团队奖励算力详情
      bonusContribution: {
        total: bonusTotal.toString(),
        unlocked: bonusUnlocked.toString(),
        pending: bonusPending.toString(),
        byTier: {
          tier1: {
            unlocked: detailedStats.bonusByTier.tier1.unlocked,
            pending: unallocatedByBonusTier.tier1,
          },
          tier2: {
            unlocked: detailedStats.bonusByTier.tier2.unlocked,
            pending: unallocatedByBonusTier.tier2,
          },
          tier3: {
            unlocked: detailedStats.bonusByTier.tier3.unlocked,
            pending: unallocatedByBonusTier.tier3,
          },
        },
      },

      systemAccounts: systemAccounts.map((a) => ({
        accountType: a.accountType,
        name: a.name,
        totalContribution: a.contributionBalance.value.toString(),
      })),
      totalUnallocated: totalUnallocated.value.toString(),
      unallocatedByType: Object.fromEntries(
        Array.from(unallocatedByType.entries()).map(([k, v]) => [k, v.value.toString()]),
      ),
    };
  }

}
