import {
  Controller,
  Get,
  Param,
  Query,
  HttpCode,
  HttpStatus,
  NotFoundException,
  Inject,
  Logger,
} from '@nestjs/common';
import { ReferralTreeQueryDto, LedgerQueryDto, WalletLedgerQueryDto } from '../dto/request/user-detail-query.dto';
import {
  UserFullDetailDto,
  ReferralTreeDto,
  ReferralNodeDto,
  PlantingLedgerResponseDto,
  WalletLedgerResponseDto,
  AuthorizationDetailResponseDto,
} from '../dto/response/user-detail.dto';
import {
  IUserQueryRepository,
  USER_QUERY_REPOSITORY,
} from '../../domain/repositories/user-query.repository';
import {
  IUserDetailQueryRepository,
  USER_DETAIL_QUERY_REPOSITORY,
} from '../../domain/repositories/user-detail-query.repository';
import { ReferralProxyService } from '../../referral/referral-proxy.service';

/**
 * 用户详情控制器
 * 为 admin-web 用户详情页面提供 API
 */
@Controller('admin/users')
export class UserDetailController {
  private readonly logger = new Logger(UserDetailController.name);

  constructor(
    @Inject(USER_QUERY_REPOSITORY)
    private readonly userQueryRepository: IUserQueryRepository,
    @Inject(USER_DETAIL_QUERY_REPOSITORY)
    private readonly userDetailRepository: IUserDetailQueryRepository,
    private readonly referralProxyService: ReferralProxyService,
  ) {}

  /**
   * 获取用户完整详情
   * GET /admin/users/:accountSequence/full-detail
   */
  @Get(':accountSequence/full-detail')
  @HttpCode(HttpStatus.OK)
  async getFullDetail(
    @Param('accountSequence') accountSequence: string,
  ): Promise<UserFullDetailDto> {
    // 获取基本用户信息
    const user = await this.userQueryRepository.findByAccountSequence(accountSequence);
    if (!user) {
      throw new NotFoundException(`用户 ${accountSequence} 不存在`);
    }

    // 并行获取所有相关数据
    const [referralInfo, personalAdoptions, teamStats, directReferralCount, prePlantingStats] = await Promise.all([
      this.userDetailRepository.getReferralInfo(accountSequence),
      this.userDetailRepository.getPersonalAdoptionCount(accountSequence),
      this.userDetailRepository.getTeamStats(accountSequence),
      this.userDetailRepository.getDirectReferralCount(accountSequence),
      this.referralProxyService.getPrePlantingStats(accountSequence),
    ]);

    // 获取推荐人昵称
    let referrerNickname: string | null = null;
    let referrerSequence: string | null = null;
    if (referralInfo?.referrerId) {
      referrerNickname = await this.userDetailRepository.getReferrerNickname(referralInfo.referrerId);
      // 获取推荐人的 accountSequence
      const referrerUser = await this.userQueryRepository.findById(referralInfo.referrerId);
      referrerSequence = referrerUser?.accountSequence || null;
    }

    return {
      accountId: user.userId.toString(),
      accountSequence: user.accountSequence,
      avatar: user.avatarUrl,
      nickname: user.nickname,
      phoneNumberMasked: user.phoneNumberMasked,
      status: this.mapStatus(user.status),
      kycStatus: user.kycStatus,
      isOnline: user.isOnline,
      registeredAt: user.registeredAt.toISOString(),
      lastActiveAt: user.lastActiveAt?.toISOString() || null,
      personalAdoptions: personalAdoptions,
      selfPrePlantingPortions: prePlantingStats.selfPrePlantingPortions,
      teamPrePlantingPortions: prePlantingStats.teamPrePlantingPortions,
      teamAddresses: teamStats.teamAddressCount,
      teamAdoptions: teamStats.teamAdoptionCount,
      provincialAdoptions: {
        count: user.provinceAdoptionCount,
        percentage: teamStats.teamAdoptionCount > 0
          ? Math.round((user.provinceAdoptionCount / teamStats.teamAdoptionCount) * 100)
          : 0,
      },
      cityAdoptions: {
        count: user.cityAdoptionCount,
        percentage: teamStats.teamAdoptionCount > 0
          ? Math.round((user.cityAdoptionCount / teamStats.teamAdoptionCount) * 100)
          : 0,
      },
      ranking: user.leaderboardRank,
      referralInfo: {
        myReferralCode: referralInfo?.myReferralCode || '',
        usedReferralCode: referralInfo?.usedReferralCode || null,
        referrerId: referralInfo?.referrerId?.toString() || null,
        referrerSequence,
        referrerNickname,
        ancestorPath: referralInfo?.ancestorPath?.map((id) => id.toString()).join(',') || null,
        depth: referralInfo?.depth || 0,
        directReferralCount: directReferralCount,  // 使用实时查询的值
        activeDirectCount: referralInfo?.activeDirectCount || 0,
      },
    };
  }

  /**
   * 获取推荐关系树
   * GET /admin/users/:accountSequence/referral-tree
   */
  @Get(':accountSequence/referral-tree')
  @HttpCode(HttpStatus.OK)
  async getReferralTree(
    @Param('accountSequence') accountSequence: string,
    @Query() query: ReferralTreeQueryDto,
  ): Promise<ReferralTreeDto> {
    // 获取当前用户信息
    const user = await this.userQueryRepository.findByAccountSequence(accountSequence);
    if (!user) {
      throw new NotFoundException(`用户 ${accountSequence} 不存在`);
    }

    // 获取引荐信息和实时统计
    const [referralInfo, personalAdoptionCount, directReferralCount, teamStats, prePlantingStats] = await Promise.all([
      this.userDetailRepository.getReferralInfo(accountSequence),
      this.userDetailRepository.getPersonalAdoptionCount(accountSequence),
      this.userDetailRepository.getDirectReferralCount(accountSequence),
      this.userDetailRepository.getBatchUserStats([accountSequence]),
      this.referralProxyService.getPrePlantingStats(accountSequence),
    ]);

    const currentUserStats = teamStats.get(accountSequence);
    const currentUser: ReferralNodeDto = {
      accountSequence: user.accountSequence,
      userId: user.userId.toString(),
      nickname: user.nickname,
      avatar: user.avatarUrl,
      personalAdoptions: personalAdoptionCount,
      teamAdoptions: currentUserStats?.teamAdoptionCount || 0,
      selfPrePlantingPortions: prePlantingStats.selfPrePlantingPortions,
      teamPrePlantingPortions: prePlantingStats.teamPrePlantingPortions,
      depth: referralInfo?.depth || 0,
      directReferralCount: directReferralCount,
      isCurrentUser: true,
    };

    let ancestors: ReferralNodeDto[] = [];
    let directReferrals: ReferralNodeDto[] = [];

    // 收集所有需要查预种的 accountSequences
    const allNodeSeqs: string[] = [];

    // 向上查询
    let ancestorNodes: typeof ancestors extends (infer T)[] ? any[] : never = [];
    if (query.direction === 'up' || query.direction === 'both') {
      ancestorNodes = await this.userDetailRepository.getAncestors(
        accountSequence,
        query.depth || 1,
      );
      allNodeSeqs.push(...ancestorNodes.map((n: any) => n.accountSequence));
    }

    // 向下查询
    let referralNodes: typeof directReferrals extends (infer T)[] ? any[] : never = [];
    if (query.direction === 'down' || query.direction === 'both') {
      referralNodes = await this.userDetailRepository.getDirectReferrals(accountSequence);
      allNodeSeqs.push(...referralNodes.map((n: any) => n.accountSequence));
    }

    // 批量获取所有节点的预种统计
    const batchPrePlanting = allNodeSeqs.length > 0
      ? await this.referralProxyService.batchGetPrePlantingStats(allNodeSeqs)
      : {};

    if (ancestorNodes.length > 0) {
      ancestors = ancestorNodes.map((node: any) => ({
        accountSequence: node.accountSequence,
        userId: node.userId.toString(),
        nickname: node.nickname,
        avatar: node.avatarUrl,
        personalAdoptions: node.personalAdoptionCount,
        teamAdoptions: node.teamAdoptionCount,
        selfPrePlantingPortions: batchPrePlanting[node.accountSequence]?.selfPrePlantingPortions ?? 0,
        teamPrePlantingPortions: batchPrePlanting[node.accountSequence]?.teamPrePlantingPortions ?? 0,
        depth: node.depth,
        directReferralCount: node.directReferralCount,
      }));
    }

    if (referralNodes.length > 0) {
      directReferrals = referralNodes.map((node: any) => ({
        accountSequence: node.accountSequence,
        userId: node.userId.toString(),
        nickname: node.nickname,
        avatar: node.avatarUrl,
        personalAdoptions: node.personalAdoptionCount,
        teamAdoptions: node.teamAdoptionCount,
        selfPrePlantingPortions: batchPrePlanting[node.accountSequence]?.selfPrePlantingPortions ?? 0,
        teamPrePlantingPortions: batchPrePlanting[node.accountSequence]?.teamPrePlantingPortions ?? 0,
        depth: node.depth,
        directReferralCount: node.directReferralCount,
      }));
    }

    return {
      currentUser,
      ancestors,
      directReferrals,
    };
  }

  /**
   * 获取认种分类账
   * GET /admin/users/:accountSequence/planting-ledger
   */
  @Get(':accountSequence/planting-ledger')
  @HttpCode(HttpStatus.OK)
  async getPlantingLedger(
    @Param('accountSequence') accountSequence: string,
    @Query() query: LedgerQueryDto,
  ): Promise<PlantingLedgerResponseDto> {
    this.logger.log(`[getPlantingLedger] 查询认种分类账, accountSequence=${accountSequence}`);

    const user = await this.userQueryRepository.findByAccountSequence(accountSequence);
    this.logger.log(`[getPlantingLedger] 用户查询结果: ${user ? `userId=${user.userId}` : 'null'}`);
    if (!user) {
      throw new NotFoundException(`用户 ${accountSequence} 不存在`);
    }

    const [summary, ledger] = await Promise.all([
      this.userDetailRepository.getPlantingSummary(accountSequence),
      this.userDetailRepository.getPlantingLedger(
        accountSequence,
        query.page || 1,
        query.pageSize || 20,
        query.startDate ? new Date(query.startDate) : undefined,
        query.endDate ? new Date(query.endDate) : undefined,
      ),
    ]);

    this.logger.log(`[getPlantingLedger] 认种汇总: totalOrders=${summary?.totalOrders}, totalTreeCount=${summary?.totalTreeCount}, effectiveTreeCount=${summary?.effectiveTreeCount}`);
    this.logger.log(`[getPlantingLedger] 认种流水条数: ${ledger.items.length}, total=${ledger.total}`);

    return {
      summary: {
        totalOrders: summary?.totalOrders || 0,
        totalTreeCount: summary?.totalTreeCount || 0,
        totalAmount: summary?.totalAmount || '0',
        effectiveTreeCount: summary?.effectiveTreeCount || 0,
        pendingTreeCount: summary?.pendingTreeCount || 0,
        firstPlantingAt: summary?.firstPlantingAt?.toISOString() || null,
        lastPlantingAt: summary?.lastPlantingAt?.toISOString() || null,
      },
      items: ledger.items.map((item) => ({
        orderId: item.orderId.toString(),
        orderNo: item.orderNo,
        treeCount: item.treeCount,
        totalAmount: item.totalAmount,
        status: item.status,
        selectedProvince: item.selectedProvince,
        selectedCity: item.selectedCity,
        createdAt: item.createdAt.toISOString(),
        paidAt: item.paidAt?.toISOString() || null,
        fundAllocatedAt: item.fundAllocatedAt?.toISOString() || null,
        miningEnabledAt: item.miningEnabledAt?.toISOString() || null,
      })),
      total: ledger.total,
      page: ledger.page,
      pageSize: ledger.pageSize,
      totalPages: ledger.totalPages,
    };
  }

  /**
   * 获取钱包分类账
   * GET /admin/users/:accountSequence/wallet-ledger
   */
  @Get(':accountSequence/wallet-ledger')
  @HttpCode(HttpStatus.OK)
  async getWalletLedger(
    @Param('accountSequence') accountSequence: string,
    @Query() query: WalletLedgerQueryDto,
  ): Promise<WalletLedgerResponseDto> {
    this.logger.log(`[getWalletLedger] 查询钱包分类账, accountSequence=${accountSequence}`);

    const user = await this.userQueryRepository.findByAccountSequence(accountSequence);
    this.logger.log(`[getWalletLedger] 用户查询结果: ${user ? `userId=${user.userId}` : 'null'}`);
    if (!user) {
      throw new NotFoundException(`用户 ${accountSequence} 不存在`);
    }

    const [summary, ledger] = await Promise.all([
      this.userDetailRepository.getWalletSummary(accountSequence),
      this.userDetailRepository.getWalletLedger(
        accountSequence,
        query.page || 1,
        query.pageSize || 20,
        {
          assetType: query.assetType,
          entryType: query.entryType,
          startDate: query.startDate ? new Date(query.startDate) : undefined,
          endDate: query.endDate ? new Date(query.endDate) : undefined,
        },
      ),
    ]);

    this.logger.log(`[getWalletLedger] 钱包汇总: usdtAvailable=${summary?.usdtAvailable}, dstAvailable=${summary?.dstAvailable}, hashpower=${summary?.hashpower}`);
    this.logger.log(`[getWalletLedger] 钱包流水条数: ${ledger.items.length}, total=${ledger.total}`);

    return {
      summary: {
        usdtAvailable: summary?.usdtAvailable || '0',
        usdtFrozen: summary?.usdtFrozen || '0',
        dstAvailable: summary?.dstAvailable || '0',
        dstFrozen: summary?.dstFrozen || '0',
        bnbAvailable: summary?.bnbAvailable || '0',
        bnbFrozen: summary?.bnbFrozen || '0',
        ogAvailable: summary?.ogAvailable || '0',
        ogFrozen: summary?.ogFrozen || '0',
        rwadAvailable: summary?.rwadAvailable || '0',
        rwadFrozen: summary?.rwadFrozen || '0',
        hashpower: summary?.hashpower || '0',
        pendingUsdt: summary?.pendingUsdt || '0',
        pendingHashpower: summary?.pendingHashpower || '0',
        settleableUsdt: summary?.settleableUsdt || '0',
        settleableHashpower: summary?.settleableHashpower || '0',
        settledTotalUsdt: summary?.settledTotalUsdt || '0',
        settledTotalHashpower: summary?.settledTotalHashpower || '0',
        expiredTotalUsdt: summary?.expiredTotalUsdt || '0',
        expiredTotalHashpower: summary?.expiredTotalHashpower || '0',
      },
      items: ledger.items.map((item) => ({
        entryId: item.entryId.toString(),
        entryType: item.entryType,
        assetType: item.assetType,
        amount: item.amount,
        balanceAfter: item.balanceAfter,
        refOrderId: item.refOrderId,
        refTxHash: item.refTxHash,
        memo: item.memo,
        createdAt: item.createdAt.toISOString(),
      })),
      total: ledger.total,
      page: ledger.page,
      pageSize: ledger.pageSize,
      totalPages: ledger.totalPages,
    };
  }

  /**
   * 获取授权详情
   * GET /admin/users/:accountSequence/authorization-detail
   */
  @Get(':accountSequence/authorization-detail')
  @HttpCode(HttpStatus.OK)
  async getAuthorizationDetail(
    @Param('accountSequence') accountSequence: string,
  ): Promise<AuthorizationDetailResponseDto> {
    const user = await this.userQueryRepository.findByAccountSequence(accountSequence);
    if (!user) {
      throw new NotFoundException(`用户 ${accountSequence} 不存在`);
    }

    const [roles, assessments, benefitAssessments, systemLedger] = await Promise.all([
      this.userDetailRepository.getAuthorizationRoles(accountSequence),
      this.userDetailRepository.getMonthlyAssessments(accountSequence),
      this.userDetailRepository.getBenefitAssessments(accountSequence),
      this.userDetailRepository.getSystemAccountLedger(accountSequence),
    ]);

    return {
      roles: roles.map((role) => ({
        id: role.id,
        roleType: role.roleType,
        regionCode: role.regionCode,
        regionName: role.regionName,
        displayTitle: role.displayTitle,
        status: role.status,
        benefitActive: role.benefitActive,
        benefitActivatedAt: role.benefitActivatedAt?.toISOString() || null,
        authorizedAt: role.authorizedAt?.toISOString() || null,
        authorizedBy: role.authorizedBy,
        initialTargetTreeCount: role.initialTargetTreeCount,
        monthlyTargetType: role.monthlyTargetType,
        lastAssessmentMonth: role.lastAssessmentMonth,
        monthlyTreesAdded: role.monthlyTreesAdded,
        officePhotoUrls: role.officePhotoUrls,
        createdAt: role.createdAt.toISOString(),
      })),
      assessments: assessments.map((assessment) => ({
        id: assessment.id,
        authorizationId: assessment.authorizationId,
        roleType: assessment.roleType,
        regionCode: assessment.regionCode,
        assessmentMonth: assessment.assessmentMonth,
        monthIndex: assessment.monthIndex,
        monthlyTarget: assessment.monthlyTarget,
        monthlyCompleted: assessment.monthlyCompleted,
        cumulativeTarget: assessment.cumulativeTarget,
        cumulativeCompleted: assessment.cumulativeCompleted,
        result: assessment.result,
        rankingInRegion: assessment.rankingInRegion,
        isFirstPlace: assessment.isFirstPlace,
        isBypassed: assessment.isBypassed,
        completedAt: assessment.completedAt?.toISOString() || null,
        assessedAt: assessment.assessedAt?.toISOString() || null,
      })),
      // [2026-01-08] 新增：权益考核记录
      benefitAssessments: benefitAssessments.map((ba) => ({
        id: ba.id,
        authorizationId: ba.authorizationId,
        roleType: ba.roleType,
        regionCode: ba.regionCode,
        regionName: ba.regionName,
        assessmentMonth: ba.assessmentMonth,
        monthIndex: ba.monthIndex,
        monthlyTarget: ba.monthlyTarget,
        cumulativeTarget: ba.cumulativeTarget,
        treesCompleted: ba.treesCompleted,
        treesRequired: ba.treesRequired,
        benefitActionTaken: ba.benefitActionTaken,
        previousBenefitStatus: ba.previousBenefitStatus,
        newBenefitStatus: ba.newBenefitStatus,
        newValidUntil: ba.newValidUntil?.toISOString() || null,
        result: ba.result,
        remarks: ba.remarks,
        assessedAt: ba.assessedAt.toISOString(),
        createdAt: ba.createdAt.toISOString(),
      })),
      systemAccountLedger: systemLedger.map((ledger) => ({
        ledgerId: ledger.ledgerId.toString(),
        accountId: ledger.accountId.toString(),
        accountType: ledger.accountType,
        entryType: ledger.entryType,
        amount: ledger.amount,
        balanceAfter: ledger.balanceAfter,
        sourceOrderId: ledger.sourceOrderId?.toString() || null,
        sourceRewardId: ledger.sourceRewardId?.toString() || null,
        txHash: ledger.txHash,
        memo: ledger.memo,
        createdAt: ledger.createdAt.toISOString(),
      })),
    };
  }

  // ============================================================================
  // 辅助方法
  // ============================================================================

  private mapStatus(status: string): 'active' | 'frozen' | 'deactivated' {
    switch (status.toUpperCase()) {
      case 'ACTIVE':
        return 'active';
      case 'FROZEN':
        return 'frozen';
      case 'DEACTIVATED':
        return 'deactivated';
      default:
        return 'active';
    }
  }

}
