import { Injectable, Inject, Logger, NotFoundException, BadRequestException } from '@nestjs/common';
import {
  REFERRAL_RELATIONSHIP_REPOSITORY,
  IReferralRelationshipRepository,
  TEAM_STATISTICS_REPOSITORY,
  ITeamStatisticsRepository,
  ReferralRelationship,
  ReferralChainService,
} from '../../domain';
import { EventPublisherService } from '../../infrastructure';
import { CreateReferralRelationshipCommand } from '../commands';
import {
  GetUserReferralInfoQuery,
  UserReferralInfoResult,
  GetDirectReferralsQuery,
  DirectReferralsResult,
} from '../queries';

@Injectable()
export class ReferralService {
  private readonly logger = new Logger(ReferralService.name);

  constructor(
    @Inject(REFERRAL_RELATIONSHIP_REPOSITORY)
    private readonly referralRepo: IReferralRelationshipRepository,
    @Inject(TEAM_STATISTICS_REPOSITORY)
    private readonly teamStatsRepo: ITeamStatisticsRepository,
    private readonly referralChainService: ReferralChainService,
    private readonly eventPublisher: EventPublisherService,
  ) {}

  /**
   * 创建推荐关系 (用户注册时调用)
   * 支持通过推荐码或inviterAccountSequence查找推荐人
   */
  async createReferralRelationship(
    command: CreateReferralRelationshipCommand,
  ): Promise<{ referralCode: string }> {
    // 检查用户是否已有推荐关系
    const exists = await this.referralRepo.existsByUserId(command.userId);
    if (exists) {
      throw new BadRequestException('用户已存在推荐关系');
    }

    let referrerId: bigint | null = null;
    let referrerReferralCode: string | null = null;  // 推荐人的推荐码
    let parentChain: bigint[] = [];

    // 优先通过推荐码查找推荐人
    if (command.referrerCode) {
      const referrer = await this.referralRepo.findByReferralCode(command.referrerCode);
      if (!referrer) {
        throw new NotFoundException('推荐码不存在');
      }
      referrerId = referrer.userId;
      referrerReferralCode = referrer.referralCode;  // 获取推荐人的推荐码
      parentChain = referrer.referralChain;

      // 验证推荐链
      if (!this.referralChainService.validateChain(parentChain, command.userId)) {
        throw new BadRequestException('无效的推荐关系');
      }
    }
    // 如果没有推荐码，尝试通过inviterAccountSequence查找
    else if (command.inviterAccountSequence) {
      const referrer = await this.referralRepo.findByAccountSequence(command.inviterAccountSequence);
      if (referrer) {
        referrerId = referrer.userId;
        referrerReferralCode = referrer.referralCode;  // 获取推荐人的推荐码
        parentChain = referrer.referralChain;

        // 验证推荐链
        if (!this.referralChainService.validateChain(parentChain, command.userId)) {
          this.logger.warn(`Invalid referral chain for user ${command.userId}, ignoring inviter`);
          referrerId = null;
          referrerReferralCode = null;
          parentChain = [];
        }
      } else {
        this.logger.warn(`Inviter with accountSequence ${command.inviterAccountSequence} not found, creating without referrer`);
      }
    }

    // 创建推荐关系（传入用户自己的推荐码和推荐人的推荐码）
    const relationship = ReferralRelationship.create(
      command.userId,
      command.accountSequence,
      command.referralCode,   // 用户自己的推荐码（由 identity-service 生成）
      referrerId,
      referrerReferralCode,  // 推荐人的推荐码
      parentChain,
    );
    const saved = await this.referralRepo.save(relationship);

    // 创建团队统计记录
    await this.teamStatsRepo.create(command.userId, command.accountSequence);

    // 如果有推荐人,更新推荐人的直推计数
    if (referrerId) {
      let referrerStats = await this.teamStatsRepo.findByUserId(referrerId);
      // 如果推荐人没有统计记录（历史用户），先创建
      if (!referrerStats) {
        this.logger.warn(`Creating missing team statistics for referrer ${referrerId}`);
        // 获取推荐人的 accountSequence
        const referrerRelationship = await this.referralRepo.findByUserId(referrerId);
        const referrerAccountSequence = referrerRelationship?.accountSequence ?? '';
        referrerStats = await this.teamStatsRepo.create(referrerId, referrerAccountSequence);
      }
      referrerStats.addDirectReferral(command.userId);
      await this.teamStatsRepo.save(referrerStats);
    }

    // 发布领域事件
    await this.eventPublisher.publishDomainEvents(saved.domainEvents);
    saved.clearDomainEvents();

    this.logger.log(`Created referral relationship for user ${command.userId}, accountSequence: ${command.accountSequence}`);

    return { referralCode: saved.referralCode };
  }

  /**
   * 获取用户推荐信息
   */
  async getUserReferralInfo(query: GetUserReferralInfoQuery): Promise<UserReferralInfoResult> {
    const relationship = await this.referralRepo.findByAccountSequence(query.accountSequence);
    if (!relationship) {
      throw new NotFoundException('用户推荐关系不存在');
    }

    const teamStats = await this.teamStatsRepo.findByUserId(relationship.userId);

    return {
      userId: relationship.userId.toString(),
      referralCode: relationship.referralCode,
      referrerId: relationship.referrerId?.toString() ?? null,
      referralChainDepth: relationship.getChainDepth(),
      directReferralCount: teamStats?.directReferralCount ?? 0,
      totalTeamCount: teamStats?.totalTeamCount ?? 0,
      personalPlantingCount: teamStats?.personalPlantingCount ?? 0,
      teamPlantingCount: teamStats?.teamPlantingCount ?? 0,
      leaderboardScore: teamStats?.leaderboardScore ?? 0,
      leaderboardRank: null, // 排行榜功能已移至 leaderboard-service
      createdAt: relationship.createdAt,
    };
  }

  /**
   * 根据推荐码获取推荐人信息
   */
  async getReferrerByCode(code: string): Promise<{ userId: string; referralCode: string } | null> {
    const relationship = await this.referralRepo.findByReferralCode(code);
    if (!relationship) return null;

    return {
      userId: relationship.userId.toString(),
      referralCode: relationship.referralCode,
    };
  }

  /**
   * 获取直推列表
   */
  async getDirectReferrals(query: GetDirectReferralsQuery): Promise<DirectReferralsResult> {
    // 先通过 accountSequence 找到用户的 referral relationship
    const userRelationship = await this.referralRepo.findByAccountSequence(query.accountSequence);
    if (!userRelationship) {
      return { referrals: [], total: 0, hasMore: false };
    }

    const relationships = await this.referralRepo.findDirectReferrals(userRelationship.userId);

    // 分页
    const total = relationships.length;
    const paginated = relationships.slice(query.offset, query.offset + query.limit);

    // 批量查询直推用户的认种统计
    const directUserIds = paginated.map((r) => r.userId);
    const directStatsMap = new Map<string, { personal: number; team: number }>();

    if (directUserIds.length > 0) {
      const directStats = await this.teamStatsRepo.findByUserIds(directUserIds);
      for (const stats of directStats) {
        directStatsMap.set(stats.userId.toString(), {
          personal: stats.personalPlantingCount,
          team: stats.teamPlantingCount,
        });
      }
    }

    // 批量查询每个直推用户的直推人数（用于判断是否有下级）
    const directReferralCountMap = new Map<string, number>();
    for (const r of paginated) {
      const subReferrals = await this.referralRepo.findDirectReferrals(r.userId);
      directReferralCountMap.set(r.userId.toString(), subReferrals.length);
    }

    const referrals = paginated.map((r) => {
      const stats = directStatsMap.get(r.userId.toString());
      return {
        userId: r.userId.toString(),
        accountSequence: r.accountSequence,
        referralCode: r.referralCode,
        personalPlantingCount: stats?.personal ?? 0,
        teamPlantingCount: stats?.team ?? 0,
        directReferralCount: directReferralCountMap.get(r.userId.toString()) ?? 0,
        joinedAt: r.createdAt,
      };
    });

    return {
      referrals,
      total,
      hasMore: query.offset + query.limit < total,
    };
  }

  /**
   * 检查推荐码是否有效
   */
  async validateReferralCode(code: string): Promise<boolean> {
    return this.referralRepo.existsByReferralCode(code);
  }
}
