import { Injectable, NotFoundException } from '@nestjs/common';
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 {
  constructor(private readonly prisma: PrismaService) {}

  /**
   * 获取用户列表
   */
  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 } },
      ];
    }

    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,
        },
      }),
      this.prisma.syncedUser.count({ where }),
    ]);

    return {
      data: users.map((user) => this.formatUserListItem(user)),
      pagination: {
        page,
        pageSize,
        total,
        totalPages: Math.ceil(total / pageSize),
      },
    };
  }

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

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

    return this.formatUserDetail(user);
  }

  /**
   * 获取用户算力记录（从同步表获取概要）
   * 注：详细流水需要调用 contribution-service
   */
  async getUserContributions(
    accountSequence: string,
    page: number,
    pageSize: number,
  ) {
    const user = await this.prisma.syncedUser.findUnique({
      where: { accountSequence },
      include: { contributionAccount: true },
    });

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

    // 返回算力账户概要
    const contribution = user.contributionAccount;
    if (!contribution) {
      return {
        summary: {
          accountSequence,
          personalContribution: '0',
          teamLevelContribution: '0',
          teamBonusContribution: '0',
          totalContribution: '0',
          effectiveContribution: '0',
          hasAdopted: false,
        },
        records: [],
        pagination: { page, pageSize, total: 0, totalPages: 0 },
      };
    }

    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,
      },
      // 详细流水需要从 contribution-service 获取
      records: [],
      pagination: { page, pageSize, total: 0, totalPages: 0 },
      note: '详细算力流水请查看 contribution-service',
    };
  }

  /**
   * 获取用户挖矿记录（从同步表获取概要）
   * 注：详细流水需要调用 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;
    if (!mining) {
      return {
        summary: {
          accountSequence,
          totalMined: '0',
          availableBalance: '0',
          frozenBalance: '0',
          totalContribution: '0',
        },
        records: [],
        pagination: { page, pageSize, total: 0, totalPages: 0 },
      };
    }

    return {
      summary: {
        accountSequence,
        totalMined: mining.totalMined.toString(),
        availableBalance: mining.availableBalance.toString(),
        frozenBalance: mining.frozenBalance.toString(),
        totalContribution: mining.totalContribution.toString(),
      },
      // 详细流水需要从 mining-service 获取
      records: [],
      pagination: { page, pageSize, total: 0, totalPages: 0 },
      note: '详细挖矿记录请查看 mining-service',
    };
  }

  /**
   * 获取用户交易订单（从同步表获取概要）
   * 注：详细订单需要调用 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',
    };
  }

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

  private formatUserListItem(user: any) {
    return {
      accountSequence: user.accountSequence,
      phone: this.maskPhone(user.phone),
      status: user.status,
      kycStatus: user.kycStatus,
      realName: user.realName,
      isLegacyUser: user.isLegacyUser,
      createdAt: user.createdAt,
      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) {
    return {
      accountSequence: user.accountSequence,
      phone: user.phone,
      status: user.status,
      kycStatus: user.kycStatus,
      realName: user.realName,
      isLegacyUser: user.isLegacyUser,
      createdAt: user.createdAt,
      syncedAt: user.syncedAt,
      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,
          }
        : 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);
  }
}
