import { Injectable, NotFoundException, Logger } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { PrismaService } from '../../infrastructure/persistence/prisma/prisma.service';
import { Prisma } from '@prisma/client';

export interface GetUsersQuery {
  page: number;
  pageSize: number;
  search?: string;
  status?: string;
  kycStatus?: string;
  hasAdopted?: boolean;
}

export interface GetOrdersQuery {
  page: number;
  pageSize: number;
  type?: string;
  status?: string;
}

@Injectable()
export class UsersService {
  private readonly logger = new Logger(UsersService.name);
  private readonly miningServiceUrl: string;
  private readonly tradingServiceUrl: string;

  constructor(
    private readonly prisma: PrismaService,
    private readonly configService: ConfigService,
  ) {
    this.miningServiceUrl = this.configService.get<string>('MINING_SERVICE_URL', 'http://localhost:3021');
    this.tradingServiceUrl = this.configService.get<string>('TRADING_SERVICE_URL', 'http://localhost:3022');
  }

  /**
   * 获取用户列表
   */
  async getUsers(query: GetUsersQuery) {
    const { page, pageSize, search, status, kycStatus, hasAdopted } = query;
    const skip = (page - 1) * pageSize;

    const where: Prisma.SyncedUserWhereInput = {};

    if (search) {
      where.OR = [
        { phone: { contains: search } },
        { accountSequence: { contains: search } },
        { realName: { contains: search } },
        { nickname: { contains: search } },
      ];
    }

    if (status) {
      where.status = status;
    }

    if (kycStatus) {
      where.kycStatus = kycStatus;
    }

    if (hasAdopted !== undefined) {
      where.contributionAccount = {
        hasAdopted: hasAdopted,
      };
    }

    const [users, total] = await Promise.all([
      this.prisma.syncedUser.findMany({
        where,
        skip,
        take: pageSize,
        orderBy: { createdAt: 'desc' },
        include: {
          contributionAccount: true,
          miningAccount: true,
          tradingAccount: true,
          referral: true,
        },
      }),
      this.prisma.syncedUser.count({ where }),
    ]);

    // 批量获取认种统计
    const accountSequences = users.map((u) => u.accountSequence);
    const adoptionStats = await this.getAdoptionStatsForUsers(accountSequences);

    // 批量获取推荐人信息
    const referrerAccountSequences = users
      .map((u) => u.referral?.referrerAccountSequence)
      .filter((s): s is string => !!s);
    const referrers = await this.getReferrersInfo(referrerAccountSequences);

    return {
      data: users.map((user) =>
        this.formatUserListItem(user, {
          adoptionStats: adoptionStats.get(user.accountSequence),
          referrerInfo: user.referral?.referrerAccountSequence
            ? referrers.get(user.referral.referrerAccountSequence)
            : null,
        }),
      ),
      pagination: {
        page,
        pageSize,
        total,
        totalPages: Math.ceil(total / pageSize),
      },
    };
  }

  /**
   * 批量获取用户认种统计
   */
  private async getAdoptionStatsForUsers(
    accountSequences: string[],
  ): Promise<Map<string, { personalCount: number; personalOrders: number; teamCount: number; teamOrders: number }>> {
    const result = new Map<
      string,
      { personalCount: number; personalOrders: number; teamCount: number; teamOrders: number }
    >();

    if (accountSequences.length === 0) return result;

    // 获取每个用户的个人认种数量和订单数（只统计 MINING_ENABLED 状态）
    const personalAdoptions = await this.prisma.syncedAdoption.groupBy({
      by: ['accountSequence'],
      where: {
        accountSequence: { in: accountSequences },
        status: 'MINING_ENABLED',
      },
      _sum: { treeCount: true },
      _count: { id: true },
    });

    for (const stat of personalAdoptions) {
      result.set(stat.accountSequence, {
        personalCount: stat._sum.treeCount || 0,
        personalOrders: stat._count.id || 0,
        teamCount: 0,
        teamOrders: 0,
      });
    }

    // 确保所有用户都有记录
    for (const seq of accountSequences) {
      if (!result.has(seq)) {
        result.set(seq, { personalCount: 0, personalOrders: 0, teamCount: 0, teamOrders: 0 });
      }
    }

    // 获取团队认种数量（通过 referral 的 originalUserId 和 ancestorPath）
    const referrals = await this.prisma.syncedReferral.findMany({
      where: { accountSequence: { in: accountSequences } },
      select: { accountSequence: true, originalUserId: true },
    });

    for (const ref of referrals) {
      if (!ref.originalUserId) continue;

      // 找所有下级
      const teamMembers = await this.prisma.syncedReferral.findMany({
        where: {
          ancestorPath: { contains: ref.originalUserId.toString() },
        },
        select: { accountSequence: true },
      });

      if (teamMembers.length > 0) {
        const teamAdoptionStats = await this.prisma.syncedAdoption.aggregate({
          where: {
            accountSequence: { in: teamMembers.map((m) => m.accountSequence) },
            status: 'MINING_ENABLED',
          },
          _sum: { treeCount: true },
          _count: { id: true },
        });
        const stats = result.get(ref.accountSequence);
        if (stats) {
          stats.teamCount = teamAdoptionStats._sum.treeCount || 0;
          stats.teamOrders = teamAdoptionStats._count.id || 0;
        }
      }
    }

    return result;
  }

  /**
   * 批量获取推荐人信息
   */
  private async getReferrersInfo(
    accountSequences: string[],
  ): Promise<Map<string, { nickname: string | null; phone: string }>> {
    const result = new Map<
      string,
      { nickname: string | null; phone: string }
    >();

    if (accountSequences.length === 0) return result;

    const referrers = await this.prisma.syncedUser.findMany({
      where: { accountSequence: { in: accountSequences } },
      select: { accountSequence: true, nickname: true, phone: true },
    });

    for (const ref of referrers) {
      result.set(ref.accountSequence, {
        nickname: ref.nickname,
        phone: ref.phone,
      });
    }

    return result;
  }

  /**
   * 获取用户详情
   */
  async getUserDetail(accountSequence: string) {
    const user = await this.prisma.syncedUser.findUnique({
      where: { accountSequence },
      include: {
        contributionAccount: true,
        miningAccount: true,
        tradingAccount: true,
        referral: true,
      },
    });

    if (!user) {
      throw new NotFoundException(`用户 ${accountSequence} 不存在`);
    }

    // 获取个人认种数量（从 synced_adoptions 统计，只统计 MINING_ENABLED 状态）
    const personalAdoptionStats = await this.prisma.syncedAdoption.aggregate({
      where: { accountSequence, status: 'MINING_ENABLED' },
      _sum: { treeCount: true },
      _count: { id: true },
    });

    // 获取直推人数和直推认种数量
    const directReferrals = await this.prisma.syncedReferral.findMany({
      where: { referrerAccountSequence: accountSequence },
      select: { accountSequence: true },
    });
    const directReferralCount = directReferrals.length;

    // 获取直推认种数量（只统计 MINING_ENABLED 状态）
    let directReferralAdoptions = 0;
    if (directReferrals.length > 0) {
      const directAdoptionStats = await this.prisma.syncedAdoption.aggregate({
        where: {
          accountSequence: {
            in: directReferrals.map((r) => r.accountSequence),
          },
          status: 'MINING_ENABLED',
        },
        _sum: { treeCount: true },
      });
      directReferralAdoptions = directAdoptionStats._sum.treeCount || 0;
    }

    // 获取团队认种数量（通过 ancestorPath 包含当前用户的所有下级）
    // 先获取当前用户的 originalUserId
    const currentReferral = await this.prisma.syncedReferral.findUnique({
      where: { accountSequence },
      select: { originalUserId: true },
    });

    let teamAdoptions = 0;
    let teamMemberCount = 0;
    if (currentReferral?.originalUserId) {
      // 找出所有 ancestorPath 包含当前用户 originalUserId 的用户（即所有下级）
      const teamMembers = await this.prisma.syncedReferral.findMany({
        where: {
          ancestorPath: {
            contains: currentReferral.originalUserId.toString(),
          },
        },
        select: { accountSequence: true },
      });
      teamMemberCount = teamMembers.length;

      if (teamMembers.length > 0) {
        const teamAdoptionStats = await this.prisma.syncedAdoption.aggregate({
          where: {
            accountSequence: {
              in: teamMembers.map((m) => m.accountSequence),
            },
            status: 'MINING_ENABLED',
          },
          _sum: { treeCount: true },
        });
        teamAdoptions = teamAdoptionStats._sum.treeCount || 0;
      }
    }

    // 获取推荐人昵称
    let referrerNickname = null;
    if (user.referral?.referrerAccountSequence) {
      const referrer = await this.prisma.syncedUser.findUnique({
        where: { accountSequence: user.referral.referrerAccountSequence },
        select: { nickname: true, phone: true },
      });
      referrerNickname = referrer?.nickname || this.maskPhone(referrer?.phone || '');
    }

    return this.formatUserDetail(user, {
      personalAdoptionCount: personalAdoptionStats._sum.treeCount || 0,
      personalAdoptionOrders: personalAdoptionStats._count.id || 0,
      directReferralCount,
      directReferralAdoptions,
      teamAdoptions,
      teamMemberCount,
      referrerNickname,
    });
  }

  /**
   * 获取用户算力记录（包含明细流水）
   */
  async getUserContributions(
    accountSequence: string,
    page: number,
    pageSize: number,
    sortBy?: string,
    sortOrder?: 'asc' | 'desc',
  ) {
    const user = await this.prisma.syncedUser.findUnique({
      where: { accountSequence },
      include: { contributionAccount: true },
    });

    if (!user) {
      throw new NotFoundException(`用户 ${accountSequence} 不存在`);
    }

    // 返回算力账户概要
    const contribution = user.contributionAccount;
    const emptySummary = {
      accountSequence,
      personalContribution: '0',
      teamLevelContribution: '0',
      teamBonusContribution: '0',
      totalContribution: '0',
      effectiveContribution: '0',
      hasAdopted: false,
      directReferralCount: 0,
      unlockedLevelDepth: 0,
      unlockedBonusTiers: 0,
    };

    // 构建排序条件
    const allowedSortFields = ['sourceType', 'levelDepth', 'amount', 'createdAt'];
    const order = sortOrder === 'asc' || sortOrder === 'desc' ? sortOrder : 'desc';
    let orderBy: any;

    if (sortBy && allowedSortFields.includes(sortBy)) {
      // 按指定字段排序，levelDepth 需要特殊处理（null 值排到末尾）
      if (sortBy === 'levelDepth') {
        // 先按 sourceType 分组，再按 levelDepth/bonusTier 排序
        orderBy = [
          { sourceType: order },
          { levelDepth: { sort: order, nulls: 'last' } },
          { bonusTier: { sort: order, nulls: 'last' } },
        ];
      } else {
        orderBy = { [sortBy]: order };
      }
    } else {
      orderBy = { createdAt: 'desc' };
    }

    // 获取算力明细记录
    const [records, total] = await Promise.all([
      this.prisma.syncedContributionRecord.findMany({
        where: { accountSequence },
        orderBy,
        skip: (page - 1) * pageSize,
        take: pageSize,
      }),
      this.prisma.syncedContributionRecord.count({
        where: { accountSequence },
      }),
    ]);

    // 格式化记录
    const formattedRecords = await Promise.all(
      records.map(async (record) => {
        // 获取来源用户信息
        let sourceUserInfo = null;
        if (record.sourceAccountSequence !== accountSequence) {
          const sourceUser = await this.prisma.syncedUser.findUnique({
            where: { accountSequence: record.sourceAccountSequence },
            select: { nickname: true, phone: true },
          });
          sourceUserInfo = sourceUser ? {
            nickname: sourceUser.nickname,
            phone: this.maskPhone(sourceUser.phone),
          } : null;
        }

        return {
          id: record.originalRecordId.toString(),
          sourceType: record.sourceType,
          sourceAccountSequence: record.sourceAccountSequence,
          sourceUserInfo,
          treeCount: record.treeCount,
          baseContribution: record.baseContribution.toString(),
          distributionRate: record.distributionRate.toString(),
          levelDepth: record.levelDepth,
          bonusTier: record.bonusTier,
          amount: record.amount.toString(),
          effectiveDate: record.effectiveDate,
          expireDate: record.expireDate,
          isExpired: record.isExpired,
          createdAt: record.createdAt,
        };
      })
    );

    if (!contribution) {
      return {
        summary: emptySummary,
        records: formattedRecords,
        pagination: {
          page,
          pageSize,
          total,
          totalPages: Math.ceil(total / pageSize),
        },
      };
    }

    return {
      summary: {
        accountSequence,
        personalContribution: contribution.personalContribution.toString(),
        teamLevelContribution: contribution.teamLevelContribution.toString(),
        teamBonusContribution: contribution.teamBonusContribution.toString(),
        totalContribution: contribution.totalContribution.toString(),
        effectiveContribution: contribution.effectiveContribution.toString(),
        hasAdopted: contribution.hasAdopted,
        directReferralCount: contribution.directReferralCount,
        unlockedLevelDepth: contribution.unlockedLevelDepth,
        unlockedBonusTiers: contribution.unlockedBonusTiers,
      },
      records: formattedRecords,
      pagination: {
        page,
        pageSize,
        total,
        totalPages: Math.ceil(total / pageSize),
      },
    };
  }

  /**
   * 获取用户挖矿记录（从 mining-service 获取）
   */
  async getUserMiningRecords(
    accountSequence: string,
    page: number,
    pageSize: number,
  ) {
    const user = await this.prisma.syncedUser.findUnique({
      where: { accountSequence },
      include: { miningAccount: true },
    });

    if (!user) {
      throw new NotFoundException(`用户 ${accountSequence} 不存在`);
    }

    const mining = user.miningAccount;
    const emptySummary = {
      accountSequence,
      totalMined: '0',
      availableBalance: '0',
      frozenBalance: '0',
      totalContribution: '0',
    };

    // 从 mining-service 获取挖矿记录
    try {
      const url = `${this.miningServiceUrl}/api/v2/mining/accounts/${accountSequence}/records?page=${page}&pageSize=${pageSize}`;
      this.logger.log(`Fetching mining records from ${url}`);

      const response = await fetch(url);
      if (!response.ok) {
        this.logger.warn(`Failed to fetch mining records: ${response.status}`);
        return {
          summary: mining ? {
            accountSequence,
            totalMined: mining.totalMined.toString(),
            availableBalance: mining.availableBalance.toString(),
            frozenBalance: mining.frozenBalance.toString(),
            totalContribution: mining.totalContribution.toString(),
          } : emptySummary,
          records: [],
          pagination: { page, pageSize, total: 0, totalPages: 0 },
        };
      }

      const result = await response.json();
      const recordsData = result.data || result;

      // 格式化记录以匹配前端期望的格式
      const records = (recordsData.data || []).map((r: any) => ({
        id: r.id,
        accountSequence,
        distributionMinute: r.miningMinute,
        contributionRatio: r.contributionRatio,
        shareAmount: r.minedAmount,
        priceSnapshot: r.secondDistribution,
        createdAt: r.createdAt,
      }));

      return {
        summary: mining ? {
          accountSequence,
          totalMined: mining.totalMined.toString(),
          availableBalance: mining.availableBalance.toString(),
          frozenBalance: mining.frozenBalance.toString(),
          totalContribution: mining.totalContribution.toString(),
        } : emptySummary,
        records,
        pagination: {
          page,
          pageSize,
          total: recordsData.total || 0,
          totalPages: Math.ceil((recordsData.total || 0) / pageSize),
        },
      };
    } catch (error) {
      this.logger.error('Failed to fetch mining records from mining-service', error);
      return {
        summary: mining ? {
          accountSequence,
          totalMined: mining.totalMined.toString(),
          availableBalance: mining.availableBalance.toString(),
          frozenBalance: mining.frozenBalance.toString(),
          totalContribution: mining.totalContribution.toString(),
        } : emptySummary,
        records: [],
        pagination: { page, pageSize, total: 0, totalPages: 0 },
      };
    }
  }

  /**
   * 获取用户交易订单（从同步表获取概要）
   * 注：详细订单需要调用 trading-service
   */
  async getUserOrders(accountSequence: string, query: GetOrdersQuery) {
    const { page, pageSize } = query;

    const user = await this.prisma.syncedUser.findUnique({
      where: { accountSequence },
      include: { tradingAccount: true },
    });

    if (!user) {
      throw new NotFoundException(`用户 ${accountSequence} 不存在`);
    }

    const trading = user.tradingAccount;
    if (!trading) {
      return {
        summary: {
          accountSequence,
          shareBalance: '0',
          cashBalance: '0',
          frozenShares: '0',
          frozenCash: '0',
          totalBought: '0',
          totalSold: '0',
        },
        orders: [],
        pagination: { page, pageSize, total: 0, totalPages: 0 },
      };
    }

    return {
      summary: {
        accountSequence,
        shareBalance: trading.shareBalance.toString(),
        cashBalance: trading.cashBalance.toString(),
        frozenShares: trading.frozenShares.toString(),
        frozenCash: trading.frozenCash.toString(),
        totalBought: trading.totalBought.toString(),
        totalSold: trading.totalSold.toString(),
      },
      // 详细订单需要从 trading-service 获取
      orders: [],
      pagination: { page, pageSize, total: 0, totalPages: 0 },
      note: '详细交易订单请查看 trading-service',
    };
  }

  /**
   * 获取用户引荐关系树
   */
  async getReferralTree(
    accountSequence: string,
    direction: string,
    depth: number,
  ) {
    const user = await this.prisma.syncedUser.findUnique({
      where: { accountSequence },
      include: {
        contributionAccount: true,
        referral: true,
      },
    });

    if (!user) {
      throw new NotFoundException(`用户 ${accountSequence} 不存在`);
    }

    // 获取当前用户的认种统计
    const currentUserAdoptions = await this.getUserAdoptionStats(accountSequence);

    // 构建当前用户节点
    const currentUser = {
      accountSequence: user.accountSequence,
      nickname: user.nickname || user.realName || null,
      avatar: null,
      personalAdoptions: currentUserAdoptions.personal,
      teamAdoptions: currentUserAdoptions.team,
      directReferralCount: 0,
    };

    // 获取直推下级数量
    const directReferralCount = await this.prisma.syncedReferral.count({
      where: { referrerAccountSequence: accountSequence },
    });
    currentUser.directReferralCount = directReferralCount;

    // 获取向上的引荐人链 (ancestors)
    let ancestors: any[] = [];
    if (direction === 'up' || direction === 'both') {
      ancestors = await this.getAncestors(accountSequence, depth);
    }

    // 获取直推下级 (directReferrals)
    let directReferrals: any[] = [];
    if (direction === 'down' || direction === 'both') {
      directReferrals = await this.getDirectReferrals(accountSequence);
    }

    return {
      currentUser,
      ancestors,
      directReferrals,
    };
  }

  /**
   * 获取用户认种统计（只统计 MINING_ENABLED 状态）
   */
  private async getUserAdoptionStats(
    accountSequence: string,
  ): Promise<{ personal: number; team: number }> {
    // 个人认种（只统计 MINING_ENABLED 状态）
    const personalStats = await this.prisma.syncedAdoption.aggregate({
      where: { accountSequence, status: 'MINING_ENABLED' },
      _sum: { treeCount: true },
    });

    // 获取用户的 originalUserId
    const referral = await this.prisma.syncedReferral.findUnique({
      where: { accountSequence },
      select: { originalUserId: true },
    });

    let teamCount = 0;
    if (referral?.originalUserId) {
      // 团队认种 = 所有下级的认种总和（只统计 MINING_ENABLED 状态）
      const teamMembers = await this.prisma.syncedReferral.findMany({
        where: {
          ancestorPath: { contains: referral.originalUserId.toString() },
        },
        select: { accountSequence: true },
      });

      if (teamMembers.length > 0) {
        const teamStats = await this.prisma.syncedAdoption.aggregate({
          where: {
            accountSequence: { in: teamMembers.map((m) => m.accountSequence) },
            status: 'MINING_ENABLED',
          },
          _sum: { treeCount: true },
        });
        teamCount = teamStats._sum.treeCount || 0;
      }
    }

    return {
      personal: personalStats._sum.treeCount || 0,
      team: teamCount,
    };
  }

  /**
   * 获取向上的引荐人链
   */
  private async getAncestors(
    accountSequence: string,
    maxDepth: number = 10,
  ): Promise<any[]> {
    const ancestors: any[] = [];

    // 获取当前用户的推荐关系
    const referral = await this.prisma.syncedReferral.findUnique({
      where: { accountSequence },
      select: { referrerAccountSequence: true, ancestorPath: true },
    });

    if (!referral?.referrerAccountSequence) {
      return ancestors;
    }

    // 通过 ancestorPath 解析祖先链
    // ancestorPath 格式类似: "123,456,789" 其中 123 是直接上级的 originalUserId
    if (referral.ancestorPath) {
      const ancestorUserIds = referral.ancestorPath
        .split(',')
        .filter((id) => id.trim())
        .slice(0, maxDepth);

      // 获取所有祖先的 referral 记录以获取 accountSequence
      const ancestorReferrals = await this.prisma.syncedReferral.findMany({
        where: {
          originalUserId: { in: ancestorUserIds.map((id) => BigInt(id)) },
        },
        select: { accountSequence: true, originalUserId: true },
      });

      const userIdToSeq = new Map(
        ancestorReferrals
          .filter((r) => r.originalUserId !== null)
          .map((r) => [r.originalUserId!.toString(), r.accountSequence]),
      );

      // 按顺序获取每个祖先的详细信息
      for (const userId of ancestorUserIds) {
        const seq = userIdToSeq.get(userId);
        if (!seq) continue;

        const user = await this.prisma.syncedUser.findUnique({
          where: { accountSequence: seq },
          select: { accountSequence: true, nickname: true, realName: true },
        });

        if (user) {
          const adoptionStats = await this.getUserAdoptionStats(seq);
          const directCount = await this.prisma.syncedReferral.count({
            where: { referrerAccountSequence: seq },
          });

          ancestors.push({
            accountSequence: user.accountSequence,
            nickname: user.nickname || user.realName || null,
            avatar: null,
            personalAdoptions: adoptionStats.personal,
            teamAdoptions: adoptionStats.team,
            directReferralCount: directCount,
          });
        }
      }
    }

    // 反转使得最近的祖先在最后（靠近当前用户）
    return ancestors.reverse();
  }

  /**
   * 获取直推下级
   */
  private async getDirectReferrals(accountSequence: string): Promise<any[]> {
    // 获取所有直推下级
    const directReferrals = await this.prisma.syncedReferral.findMany({
      where: { referrerAccountSequence: accountSequence },
      select: { accountSequence: true },
    });

    const results: any[] = [];

    for (const ref of directReferrals) {
      const user = await this.prisma.syncedUser.findUnique({
        where: { accountSequence: ref.accountSequence },
        select: { accountSequence: true, nickname: true, realName: true },
      });

      if (user) {
        const adoptionStats = await this.getUserAdoptionStats(ref.accountSequence);
        const directCount = await this.prisma.syncedReferral.count({
          where: { referrerAccountSequence: ref.accountSequence },
        });

        results.push({
          accountSequence: user.accountSequence,
          nickname: user.nickname || user.realName || null,
          avatar: null,
          personalAdoptions: adoptionStats.personal,
          teamAdoptions: adoptionStats.team,
          directReferralCount: directCount,
        });
      }
    }

    return results;
  }

  /**
   * 获取用户认种分类账
   */
  async getPlantingLedger(accountSequence: string, page: number, pageSize: number) {
    const user = await this.prisma.syncedUser.findUnique({
      where: { accountSequence },
    });

    if (!user) {
      throw new NotFoundException(`用户 ${accountSequence} 不存在`);
    }

    // 查询认种记录总数
    const total = await this.prisma.syncedAdoption.count({
      where: { accountSequence },
    });

    // 分页查询认种记录
    const adoptions = await this.prisma.syncedAdoption.findMany({
      where: { accountSequence },
      orderBy: { adoptionDate: 'desc' },
      skip: (page - 1) * pageSize,
      take: pageSize,
    });

    // 汇总统计
    const summary = await this.prisma.syncedAdoption.aggregate({
      where: { accountSequence },
      _count: { id: true },
      _sum: { treeCount: true },
      _min: { adoptionDate: true },
      _max: { adoptionDate: true },
    });

    // 计算总金额（每棵树 * 树数量）
    const allAdoptions = await this.prisma.syncedAdoption.findMany({
      where: { accountSequence },
      select: { treeCount: true, contributionPerTree: true },
    });

    let totalAmount = 0;
    for (const a of allAdoptions) {
      totalAmount += a.treeCount * Number(a.contributionPerTree);
    }

    // 获取每笔认种的实际分配明细（从 contribution_records 统计）
    const adoptionMap = new Map(adoptions.map((a) => [
      a.originalAdoptionId.toString(),
      { treeCount: a.treeCount, contributionPerTree: Number(a.contributionPerTree) },
    ]));
    const distributionByAdoption = await this.getDistributionByAdoptions(adoptionMap);

    // 格式化认种记录，包含分配明细
    const items = adoptions.map((a) => {
      const totalContribution = a.treeCount * Number(a.contributionPerTree);
      const distribution = distributionByAdoption.get(a.originalAdoptionId.toString());

      return {
        id: a.id,
        originalAdoptionId: a.originalAdoptionId.toString(),
        treeCount: a.treeCount,
        adoptionDate: a.adoptionDate,
        status: a.status || 'ACTIVE',
        contributionPerTree: a.contributionPerTree.toString(),
        totalContribution: totalContribution.toString(),
        // 分配明细
        distribution: distribution || {
          personal: {
            rate: 0.70,
            amount: (totalContribution * 0.70).toFixed(4),
            label: '认种人账户',
          },
          operation: {
            rate: 0.12,
            amount: (totalContribution * 0.12).toFixed(4),
            label: '运营账户',
          },
          province: {
            rate: 0.01,
            amount: (totalContribution * 0.01).toFixed(4),
            label: '省公司账户',
          },
          city: {
            rate: 0.02,
            amount: (totalContribution * 0.02).toFixed(4),
            label: '市公司账户',
          },
          team: {
            rate: 0.15,
            amount: (totalContribution * 0.15).toFixed(4),
            distributed: '0',
            unallocated: (totalContribution * 0.15).toFixed(4),
            label: '团队分配',
          },
        },
      };
    });

    return {
      summary: {
        totalOrders: summary._count.id || 0,
        totalTreeCount: summary._sum.treeCount || 0,
        totalAmount: totalAmount.toString(),
        effectiveTreeCount: summary._sum.treeCount || 0, // 有效认种数默认等于总数
        firstPlantingAt: summary._min.adoptionDate || null,
        lastPlantingAt: summary._max.adoptionDate || null,
      },
      items,
      total,
      page,
      pageSize,
      totalPages: Math.ceil(total / pageSize),
    };
  }

  /**
   * 获取用户批量补发记录（从 mining-service 获取）
   */
  async getBatchMiningRecords(
    accountSequence: string,
    page: number,
    pageSize: number,
  ) {
    const user = await this.prisma.syncedUser.findUnique({
      where: { accountSequence },
    });

    if (!user) {
      throw new NotFoundException(`用户 ${accountSequence} 不存在`);
    }

    try {
      const url = `${this.miningServiceUrl}/api/v2/mining/admin/batch-mining/records/${accountSequence}?page=${page}&pageSize=${pageSize}`;
      this.logger.log(`Fetching batch mining records from ${url}`);

      const response = await fetch(url);
      if (!response.ok) {
        if (response.status === 404) {
          return {
            records: [],
            total: 0,
            page,
            pageSize,
            totalPages: 0,
            totalAmount: '0',
          };
        }
        this.logger.warn(`Failed to fetch batch mining records: ${response.status}`);
        return {
          records: [],
          total: 0,
          page,
          pageSize,
          totalPages: 0,
          totalAmount: '0',
        };
      }

      const result = await response.json();
      const data = result.data || result;

      return {
        records: data.records || [],
        total: data.total || 0,
        page: data.page || page,
        pageSize: data.pageSize || pageSize,
        totalPages: Math.ceil((data.total || 0) / pageSize),
        totalAmount: data.totalAmount || '0',
      };
    } catch (error) {
      this.logger.error('Failed to fetch batch mining records from mining-service', error);
      return {
        records: [],
        total: 0,
        page,
        pageSize,
        totalPages: 0,
        totalAmount: '0',
      };
    }
  }

  /**
   * 获取用户钱包流水
   * 从 SyncedUserWallet 获取钱包汇总，从 SyncedMiningAccount 获取挖矿余额
   */
  async getWalletLedger(accountSequence: string, page: number, pageSize: number) {
    const user = await this.prisma.syncedUser.findUnique({
      where: { accountSequence },
      include: { miningAccount: true },
    });

    if (!user) {
      throw new NotFoundException(`用户 ${accountSequence} 不存在`);
    }

    // 获取用户的各类钱包数据
    const wallets = await this.prisma.syncedUserWallet.findMany({
      where: { accountSequence },
    });

    // 按钱包类型分类
    const walletByType = new Map(wallets.map(w => [w.walletType, w]));
    const greenPointsWallet = walletByType.get('GREEN_POINTS');
    const contributionWallet = walletByType.get('CONTRIBUTION');
    const tokenWallet = walletByType.get('TOKEN_STORAGE');

    const mining = user.miningAccount;

    // 构建前端期望的钱包汇总格式
    // usdtAvailable = GREEN_POINTS 钱包的可用余额 (绿积分)
    // usdtFrozen = GREEN_POINTS 钱包的冻结余额
    // pendingUsdt = 待领取收益（挖矿余额）
    // settleableUsdt = 可结算收益
    // settledTotalUsdt = 已结算收益
    // expiredTotalUsdt = 过期收益
    const summary = {
      usdtAvailable: greenPointsWallet?.balance?.toString() || '0',
      usdtFrozen: greenPointsWallet?.frozenBalance?.toString() || '0',
      pendingUsdt: mining?.availableBalance?.toString() || '0',  // 挖矿可用余额作为待领取
      settleableUsdt: '0',  // 暂无数据源
      settledTotalUsdt: greenPointsWallet?.totalInflow?.toString() || '0',  // 总流入作为已结算
      expiredTotalUsdt: '0',  // 暂无数据源
    };

    // TODO: 实现钱包流水分页查询
    // 目前从 SyncedUserWallet 只能获取汇总数据，流水明细需要额外的表
    return {
      summary,
      items: [],
      total: 0,
      page,
      pageSize,
      totalPages: 0,
    };
  }

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

  private formatUserListItem(
    user: any,
    extra?: {
      adoptionStats?: { personalCount: number; personalOrders: number; teamCount: number; teamOrders: number };
      referrerInfo?: { nickname: string | null; phone: string } | null;
    },
  ) {
    return {
      accountSequence: user.accountSequence,
      phone: this.maskPhone(user.phone),
      nickname: user.nickname || null,
      status: user.status,
      kycStatus: user.kycStatus,
      realName: user.realName,
      isLegacyUser: user.isLegacyUser,
      createdAt: user.createdAt,
      // 认种统计
      adoption: {
        personalAdoptionCount: extra?.adoptionStats?.personalCount || 0,
        personalAdoptionOrders: extra?.adoptionStats?.personalOrders || 0,
        teamAdoptions: extra?.adoptionStats?.teamCount || 0,
        teamAdoptionOrders: extra?.adoptionStats?.teamOrders || 0,
      },
      // 推荐人信息
      referral: user.referral
        ? {
            referrerAccountSequence: user.referral.referrerAccountSequence,
            referrerNickname:
              extra?.referrerInfo?.nickname ||
              (extra?.referrerInfo?.phone
                ? this.maskPhone(extra.referrerInfo.phone)
                : null),
          }
        : null,
      contribution: user.contributionAccount
        ? {
            totalContribution:
              user.contributionAccount.totalContribution.toString(),
            effectiveContribution:
              user.contributionAccount.effectiveContribution.toString(),
            hasAdopted: user.contributionAccount.hasAdopted,
          }
        : null,
      mining: user.miningAccount
        ? {
            totalMined: user.miningAccount.totalMined.toString(),
            availableBalance: user.miningAccount.availableBalance.toString(),
          }
        : null,
      trading: user.tradingAccount
        ? {
            shareBalance: user.tradingAccount.shareBalance.toString(),
            cashBalance: user.tradingAccount.cashBalance.toString(),
          }
        : null,
    };
  }

  private formatUserDetail(
    user: any,
    extra?: {
      personalAdoptionCount: number;
      personalAdoptionOrders: number;
      directReferralCount: number;
      directReferralAdoptions: number;
      teamAdoptions: number;
      teamMemberCount: number;
      referrerNickname: string | null;
    },
  ) {
    return {
      accountSequence: user.accountSequence,
      phone: user.phone,
      nickname: user.nickname || null,
      status: user.status,
      kycStatus: user.kycStatus,
      realName: user.realName,
      isLegacyUser: user.isLegacyUser,
      createdAt: user.createdAt,
      syncedAt: user.syncedAt,
      // 推荐关系
      referral: user.referral
        ? {
            referrerAccountSequence: user.referral.referrerAccountSequence,
            referrerNickname: extra?.referrerNickname || null,
            depth: user.referral.depth,
          }
        : null,
      // 认种统计
      adoption: {
        personalAdoptionCount: extra?.personalAdoptionCount || 0,
        personalAdoptionOrders: extra?.personalAdoptionOrders || 0,
        directReferralAdoptions: extra?.directReferralAdoptions || 0,
        teamAdoptions: extra?.teamAdoptions || 0,
      },
      // 团队统计
      team: {
        directReferralCount: extra?.directReferralCount || 0,
        teamMemberCount: extra?.teamMemberCount || 0,
      },
      contribution: user.contributionAccount
        ? {
            personalContribution:
              user.contributionAccount.personalContribution.toString(),
            teamLevelContribution:
              user.contributionAccount.teamLevelContribution.toString(),
            teamBonusContribution:
              user.contributionAccount.teamBonusContribution.toString(),
            totalContribution:
              user.contributionAccount.totalContribution.toString(),
            effectiveContribution:
              user.contributionAccount.effectiveContribution.toString(),
            hasAdopted: user.contributionAccount.hasAdopted,
            directReferralCount: user.contributionAccount.directReferralCount,
            unlockedLevelDepth: user.contributionAccount.unlockedLevelDepth,
            unlockedBonusTiers: user.contributionAccount.unlockedBonusTiers,
          }
        : null,
      mining: user.miningAccount
        ? {
            totalMined: user.miningAccount.totalMined.toString(),
            availableBalance: user.miningAccount.availableBalance.toString(),
            frozenBalance: user.miningAccount.frozenBalance.toString(),
            totalContribution: user.miningAccount.totalContribution.toString(),
          }
        : null,
      trading: user.tradingAccount
        ? {
            shareBalance: user.tradingAccount.shareBalance.toString(),
            cashBalance: user.tradingAccount.cashBalance.toString(),
            frozenShares: user.tradingAccount.frozenShares.toString(),
            frozenCash: user.tradingAccount.frozenCash.toString(),
            totalBought: user.tradingAccount.totalBought.toString(),
            totalSold: user.tradingAccount.totalSold.toString(),
          }
        : null,
    };
  }

  private maskPhone(phone: string): string {
    if (!phone || phone.length < 7) return phone;
    return phone.substring(0, 3) + '****' + phone.substring(phone.length - 4);
  }

  /**
   * 获取认种的实际分配明细
   * 基于认种的总算力计算各项分配金额
   */
  private async getDistributionByAdoptions(
    adoptionMap: Map<string, { treeCount: number; contributionPerTree: number }>,
  ): Promise<Map<string, any>> {
    const result = new Map<string, any>();

    if (adoptionMap.size === 0) return result;

    const adoptionIds = Array.from(adoptionMap.keys()).map((id) => BigInt(id));

    // 查询这些认种产生的算力记录（只统计团队分配部分的实际发放）
    const records = await this.prisma.syncedContributionRecord.findMany({
      where: { sourceAdoptionId: { in: adoptionIds } },
      select: {
        sourceAdoptionId: true,
        sourceType: true,
        amount: true,
      },
    });

    // 按认种ID分组统计团队分配的实际发放
    const teamDistributedByAdoption = new Map<string, number>();

    for (const record of records) {
      const adoptionId = record.sourceAdoptionId.toString();
      const amount = Number(record.amount);

      // 只统计团队部分（TEAM_LEVEL 和 TEAM_BONUS）
      if (record.sourceType === 'TEAM_LEVEL' || record.sourceType === 'TEAM_BONUS') {
        teamDistributedByAdoption.set(
          adoptionId,
          (teamDistributedByAdoption.get(adoptionId) || 0) + amount,
        );
      }
    }

    // 为每个认种构建分配明细
    for (const [adoptionId, adoption] of adoptionMap) {
      const totalContribution = adoption.treeCount * adoption.contributionPerTree;
      const teamTotal = totalContribution * 0.15;
      const teamDistributed = teamDistributedByAdoption.get(adoptionId) || 0;
      const teamUnallocated = teamTotal - teamDistributed;

      result.set(adoptionId, {
        personal: {
          rate: 0.70,
          amount: (totalContribution * 0.70).toFixed(4),
          label: '认种人账户',
        },
        operation: {
          rate: 0.12,
          amount: (totalContribution * 0.12).toFixed(4),
          label: '运营账户',
        },
        province: {
          rate: 0.01,
          amount: (totalContribution * 0.01).toFixed(4),
          label: '省公司账户',
        },
        city: {
          rate: 0.02,
          amount: (totalContribution * 0.02).toFixed(4),
          label: '市公司账户',
        },
        team: {
          rate: 0.15,
          amount: teamTotal.toFixed(4),
          distributed: teamDistributed.toFixed(4),
          unallocated: Math.max(0, teamUnallocated).toFixed(4),
          label: '团队分配',
        },
      });
    }

    return result;
  }

  /**
   * 获取全部P2P转账记录（代理 trading-service）
   */
  async getP2pTransfers(page: number, pageSize: number, search?: string) {
    try {
      const params = new URLSearchParams({
        page: page.toString(),
        pageSize: pageSize.toString(),
      });
      if (search) params.set('search', search);

      const url = `${this.tradingServiceUrl}/api/v2/p2p/internal/all-transfers?${params}`;
      const response = await fetch(url);
      if (!response.ok) {
        this.logger.warn(`Failed to fetch P2P transfers: ${response.status}`);
        return { data: [], total: 0, summary: { totalFee: '0', totalAmount: '0', totalCount: 0 }, pagination: { page, pageSize, total: 0, totalPages: 0 } };
      }
      const result = await response.json();
      const body = result.data || result;
      return {
        ...body,
        pagination: {
          page,
          pageSize,
          total: body.total,
          totalPages: Math.ceil(body.total / pageSize),
        },
      };
    } catch (error: any) {
      this.logger.warn(`Failed to fetch P2P transfers: ${error.message}`);
      return { data: [], total: 0, summary: { totalFee: '0', totalAmount: '0', totalCount: 0 }, pagination: { page, pageSize, total: 0, totalPages: 0 } };
    }
  }
}
