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

export interface ContributionAccountDto {
  status: ContributionAccountStatus;
  message: string;
  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,
    private readonly syncedDataRepository: SyncedDataRepository,
  ) {}

  /**
   * 获取账户算力信息
   * 区分三种状态：
   * 1. ACTIVE - 账户存在且有算力数据
   * 2. NOT_ADOPTED - 用户存在但尚未认种，返回零算力
   * 3. USER_NOT_FOUND - 用户不存在
   */
  async execute(accountSequence: string): Promise<ContributionAccountDto> {
    // 1. 先查询 contribution_accounts 表
    const account = await this.accountRepository.findByAccountSequence(accountSequence);
    if (account) {
      return this.toDto(account);
    }

    // 2. 账户不存在，检查用户是否存在（通过 synced_referrals 或 synced_users 表）
    const referral = await this.syncedDataRepository.findSyncedReferralByAccountSequence(accountSequence);
    const user = await this.syncedDataRepository.findSyncedUserByAccountSequence(accountSequence);

    if (referral || user) {
      // 用户存在但自己和团队均未认种，返回零算力的默认数据
      return this.createInactiveResponse(accountSequence);
    }

    // 3. 用户完全不存在
    return this.createUserNotFoundResponse(accountSequence);
  }

  /**
   * 创建"未激活"状态的响应
   * 用户存在但自己和团队均未认种，暂无任何算力
   */
  private createInactiveResponse(accountSequence: string): ContributionAccountDto {
    return {
      status: ContributionAccountStatus.INACTIVE,
      message: '您和团队暂无认种记录，完成认种后即可获得算力。邀请好友认种可获得最高15级层级算力和3档团队加成算力。',
      accountSequence,
      personalContribution: '0',
      teamLevelContribution: '0',
      teamBonusContribution: '0',
      totalContribution: '0',
      hasAdopted: false,
      directReferralAdoptedCount: 0,
      unlockedLevelDepth: 0,
      unlockedBonusTiers: 0,
      isCalculated: false,
      lastCalculatedAt: null,
    };
  }

  /**
   * 创建"用户不存在"状态的响应
   */
  private createUserNotFoundResponse(accountSequence: string): ContributionAccountDto {
    return {
      status: ContributionAccountStatus.USER_NOT_FOUND,
      message: '账户不存在，请确认账户序号是否正确',
      accountSequence,
      personalContribution: '0',
      teamLevelContribution: '0',
      teamBonusContribution: '0',
      totalContribution: '0',
      hasAdopted: false,
      directReferralAdoptedCount: 0,
      unlockedLevelDepth: 0,
      unlockedBonusTiers: 0,
      isCalculated: false,
      lastCalculatedAt: null,
    };
  }

  /**
   * 获取账户的算力明细记录
   */
  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 {
      status: ContributionAccountStatus.ACTIVE,
      message: '账户正常',
      accountSequence: account.accountSequence,
      personalContribution: account.personalContribution.value.toString(),
      teamLevelContribution: account.totalLevelPending.value.toString(),
      teamBonusContribution: account.totalBonusPending.value.toString(),
      totalContribution: account.effectiveContribution.value.toString(),
      hasAdopted: account.hasAdopted,
      directReferralAdoptedCount: account.directReferralAdoptedCount,
      unlockedLevelDepth: account.unlockedLevelDepth,
      unlockedBonusTiers: account.unlockedBonusTiers,
      isCalculated: true,
      lastCalculatedAt: account.updatedAt,
    };
  }

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