import {
  Controller,
  Get,
  Param,
  Query,
  HttpCode,
  HttpStatus,
  NotFoundException,
  Inject,
} from '@nestjs/common';
import { ListUsersDto } from '../dto/request/user-query.dto';
import { UserListResponseDto, UserListItemDto, UserDetailDto } from '../dto/response/user.dto';
import {
  IUserQueryRepository,
  USER_QUERY_REPOSITORY,
  UserQueryItem,
  UserQueryFilters,
  UserQuerySort,
} 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 提供用户查询接口
 */
@Controller('admin/users')
export class UserController {
  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
   */
  @Get()
  @HttpCode(HttpStatus.OK)
  async listUsers(@Query() query: ListUsersDto): Promise<UserListResponseDto> {
    // 构建筛选条件
    const filters: UserQueryFilters = {
      keyword: query.keyword,
      status: query.status,
      kycStatus: query.kycStatus,
      hasInviter: query.hasInviter,
      minAdoptions: query.minAdoptions,
      maxAdoptions: query.maxAdoptions,
      registeredAfter: query.registeredAfter ? new Date(query.registeredAfter) : undefined,
      registeredBefore: query.registeredBefore ? new Date(query.registeredBefore) : undefined,
    };

    // 构建排序条件
    const sort: UserQuerySort | undefined = query.sortBy ? {
      field: query.sortBy as UserQuerySort['field'],
      order: query.sortOrder || 'desc',
    } : undefined;

    // 查询数据
    const result = await this.userQueryRepository.findMany(
      filters,
      { page: query.page || 1, pageSize: query.pageSize || 10 },
      sort,
    );

    // 批量获取实时统计数据
    const accountSequences = result.items.map(item => item.accountSequence);
    const [statsMap, prePlantingStatsMap] = await Promise.all([
      this.userDetailRepository.getBatchUserStats(accountSequences),
      this.referralProxyService.batchGetPrePlantingStats(accountSequences),
    ]);

    // 获取所有用户的团队总认种数用于计算百分比（使用实时数据）
    let totalTeamAdoptions = 0;
    for (const stats of statsMap.values()) {
      totalTeamAdoptions += stats.teamAdoptionCount;
    }

    return {
      items: result.items.map((item) => this.mapToListItem(item, totalTeamAdoptions, statsMap.get(item.accountSequence), prePlantingStatsMap[item.accountSequence])),
      total: result.total,
      page: result.page,
      pageSize: result.pageSize,
      totalPages: result.totalPages,
    };
  }

  /**
   * 获取用户详情
   * GET /admin/users/:id
   */
  @Get(':id')
  @HttpCode(HttpStatus.OK)
  async getUserDetail(@Param('id') id: string): Promise<UserDetailDto> {
    let user: UserQueryItem | null = null;

    // 尝试作为账号序列号查询
    if (id.startsWith('D')) {
      user = await this.userQueryRepository.findByAccountSequence(id);
    }

    // 如果不是序列号或未找到，尝试作为 userId 查询
    if (!user) {
      try {
        const userId = BigInt(id);
        user = await this.userQueryRepository.findById(userId);
      } catch {
        // 无法转换为 BigInt，忽略
      }
    }

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

    return this.mapToDetail(user);
  }

  /**
   * 获取用户统计信息
   * GET /admin/users/stats/summary
   */
  @Get('stats/summary')
  @HttpCode(HttpStatus.OK)
  async getUserStats(): Promise<{
    totalUsers: number;
    activeUsers: number;
    frozenUsers: number;
    verifiedUsers: number;
  }> {
    const [total, active, frozen, verified] = await Promise.all([
      this.userQueryRepository.count(),
      this.userQueryRepository.count({ status: 'ACTIVE' }),
      this.userQueryRepository.count({ status: 'FROZEN' }),
      this.userQueryRepository.count({ kycStatus: 'VERIFIED' }),
    ]);

    return {
      totalUsers: total,
      activeUsers: active,
      frozenUsers: frozen,
      verifiedUsers: verified,
    };
  }

  // ==================== Private Methods ====================

  private mapToListItem(
    item: UserQueryItem,
    totalTeamAdoptions: number,
    realTimeStats?: {
      personalAdoptionCount: number;
      teamAddressCount: number;
      teamAdoptionCount: number;
      provinceAdoptionCount: number;
      cityAdoptionCount: number;
    },
    prePlantingStats?: {
      selfPrePlantingPortions: number;
      teamPrePlantingPortions: number;
    },
  ): UserListItemDto {
    // 使用实时统计数据（如果有），否则使用预计算数据
    const personalAdoptions = realTimeStats?.personalAdoptionCount ?? item.personalAdoptionCount;
    const teamAddresses = realTimeStats?.teamAddressCount ?? item.teamAddressCount;
    const teamAdoptions = realTimeStats?.teamAdoptionCount ?? item.teamAdoptionCount;
    const provinceAdoptions = realTimeStats?.provinceAdoptionCount ?? item.provinceAdoptionCount;
    const cityAdoptions = realTimeStats?.cityAdoptionCount ?? item.cityAdoptionCount;

    // 计算省市认种百分比（相对于该用户的团队总认种量）
    const userTeamAdoptions = teamAdoptions > 0 ? teamAdoptions : 1;
    const provincePercentage = teamAdoptions > 0
      ? Math.round((provinceAdoptions / userTeamAdoptions) * 100)
      : 0;
    const cityPercentage = teamAdoptions > 0
      ? Math.round((cityAdoptions / userTeamAdoptions) * 100)
      : 0;

    return {
      accountId: item.userId.toString(),
      accountSequence: item.accountSequence,
      avatar: item.avatarUrl,
      nickname: item.nickname,
      phoneNumberMasked: item.phoneNumberMasked,
      personalAdoptions,
      selfPrePlantingPortions: prePlantingStats?.selfPrePlantingPortions ?? 0,
      teamPrePlantingPortions: prePlantingStats?.teamPrePlantingPortions ?? 0,
      teamAddresses,
      teamAdoptions,
      provincialAdoptions: {
        count: provinceAdoptions,
        percentage: provincePercentage,
      },
      cityAdoptions: {
        count: cityAdoptions,
        percentage: cityPercentage,
      },
      referrerId: item.inviterSequence,
      ranking: item.leaderboardRank,
      status: this.mapStatus(item.status),
      isOnline: item.isOnline,
    };
  }

  private mapToDetail(item: UserQueryItem): UserDetailDto {
    const listItem = this.mapToListItem(item, 0);

    return {
      ...listItem,
      kycStatus: item.kycStatus,
      registeredAt: item.registeredAt.toISOString(),
      lastActiveAt: item.lastActiveAt?.toISOString() || null,
    };
  }

  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';
    }
  }
}
