import { Injectable } from '@nestjs/common';
import { ContributionAccountRepository } from '../../infrastructure/persistence/repositories/contribution-account.repository';
import { ContributionRecordRepository } from '../../infrastructure/persistence/repositories/contribution-record.repository';
import { ContributionAmount } from '../../domain/value-objects/contribution-amount.vo';

export interface ContributionAccountDto {
  accountSequence: string;
  personalContribution: string;
  teamLevelContribution: string;
  teamBonusContribution: string;
  totalContribution: string;
  hasAdopted: boolean;
  directReferralAdoptedCount: number;
  unlockedLevelDepth: number;
  unlockedBonusTiers: number;
  isCalculated: boolean;
  lastCalculatedAt: Date | null;
}

export interface ContributionRecordDto {
  id: string;
  sourceType: string;
  sourceAdoptionId: string;
  sourceAccountSequence: string | null;
  treeCount: number;
  baseContribution: string;
  distributionRate: string;
  levelDepth: number | null;
  bonusTier: number | null;
  finalContribution: string;
  effectiveDate: Date;
  expireDate: Date;
  isExpired: boolean;
  createdAt: Date;
}

@Injectable()
export class GetContributionAccountQuery {
  constructor(
    private readonly accountRepository: ContributionAccountRepository,
    private readonly recordRepository: ContributionRecordRepository,
  ) {}

  /**
   * 获取账户算力信息
   */
  async execute(accountSequence: string): Promise<ContributionAccountDto | null> {
    const account = await this.accountRepository.findByAccountSequence(accountSequence);
    if (!account) {
      return null;
    }

    return this.toDto(account);
  }

  /**
   * 获取账户的算力明细记录
   */
  async getRecords(
    accountSequence: string,
    options?: {
      sourceType?: string;
      includeExpired?: boolean;
      page?: number;
      pageSize?: number;
    },
  ): Promise<{ data: ContributionRecordDto[]; total: number }> {
    const result = await this.recordRepository.findByAccountSequence(accountSequence, {
      sourceType: options?.sourceType as any,
      includeExpired: options?.includeExpired ?? false,
      page: options?.page ?? 1,
      limit: options?.pageSize ?? 50,
    });

    return {
      data: result.items.map((r: any) => this.toRecordDto(r)),
      total: result.total,
    };
  }

  /**
   * 获取账户的活跃算力统计
   */
  async getActiveContribution(accountSequence: string): Promise<{
    personal: string;
    teamLevel: string;
    teamBonus: string;
    total: string;
  } | null> {
    const result = await this.recordRepository.getActiveContributionByAccount(accountSequence);
    if (!result) {
      return null;
    }

    return {
      personal: result.personal.value.toString(),
      teamLevel: result.teamLevel.value.toString(),
      teamBonus: result.teamBonus.value.toString(),
      total: result.total.value.toString(),
    };
  }

  private toDto(account: any): ContributionAccountDto {
    return {
      accountSequence: account.accountSequence,
      personalContribution: account.personalContribution.value.toString(),
      teamLevelContribution: account.teamLevelContribution.value.toString(),
      teamBonusContribution: account.teamBonusContribution.value.toString(),
      totalContribution: account.totalContribution.value.toString(),
      hasAdopted: account.hasAdopted,
      directReferralAdoptedCount: account.directReferralAdoptedCount,
      unlockedLevelDepth: account.unlockedLevelDepth,
      unlockedBonusTiers: account.unlockedBonusTiers,
      isCalculated: account.isCalculated,
      lastCalculatedAt: account.lastCalculatedAt,
    };
  }

  private toRecordDto(record: any): ContributionRecordDto {
    return {
      id: record.id,
      sourceType: record.sourceType,
      sourceAdoptionId: record.sourceAdoptionId,
      sourceAccountSequence: record.sourceAccountSequence,
      treeCount: record.treeCount,
      baseContribution: record.baseContribution.value.toString(),
      distributionRate: record.distributionRate.value.toString(),
      levelDepth: record.levelDepth,
      bonusTier: record.bonusTier,
      finalContribution: record.finalContribution.value.toString(),
      effectiveDate: record.effectiveDate,
      expireDate: record.expireDate,
      isExpired: record.isExpired,
      createdAt: record.createdAt,
    };
  }
}
