import { UserId, LeaderboardScore, ProvinceCityDistribution } from '../../value-objects';
import { DomainEvent, TeamStatisticsUpdatedEvent } from '../../events';

export interface DirectReferralStats {
  referralId: bigint;
  teamCount: number;
}

export interface TeamStatisticsProps {
  id: bigint;
  userId: bigint;
  accountSequence: string;  // 账户序列号，用于事件发布
  directReferralCount: number;
  totalTeamCount: number;
  personalPlantingCount: number;
  teamPlantingCount: number;
  leaderboardScore: number;
  maxDirectTeamCount: number;
  provinceCityDistribution: Record<string, Record<string, number>> | null;
  lastCalculatedAt: Date;
  createdAt: Date;
  updatedAt: Date;
  directReferrals?: DirectReferralStats[];
}

/**
 * 团队统计聚合根
 *
 * 职责:
 * - 维护用户的团队统计数据
 * - 计算龙虎榜分值
 * - 跟踪省市认种分布
 */
export class TeamStatistics {
  private _domainEvents: DomainEvent[] = [];

  private constructor(
    private readonly _id: bigint,
    private readonly _userId: UserId,
    private readonly _accountSequence: string,  // 账户序列号
    private _directReferralCount: number,
    private _totalTeamCount: number,
    private _personalPlantingCount: number,
    private _teamPlantingCount: number,
    private _leaderboardScore: LeaderboardScore,
    private _provinceCityDistribution: ProvinceCityDistribution,
    private _lastCalculatedAt: Date,
    private readonly _createdAt: Date,
    private _updatedAt: Date,
    private _directReferralStats: Map<bigint, number> = new Map(),
  ) {}

  // Getters
  get id(): bigint {
    return this._id;
  }
  get userId(): bigint {
    return this._userId.value;
  }
  get accountSequence(): string {
    return this._accountSequence;
  }
  get directReferralCount(): number {
    return this._directReferralCount;
  }
  get totalTeamCount(): number {
    return this._totalTeamCount;
  }
  get personalPlantingCount(): number {
    return this._personalPlantingCount;
  }
  get teamPlantingCount(): number {
    return this._teamPlantingCount;
  }
  get leaderboardScore(): number {
    return this._leaderboardScore.score;
  }
  get maxDirectTeamCount(): number {
    return this._leaderboardScore.maxDirectTeamCount;
  }
  get provinceCityDistribution(): ProvinceCityDistribution {
    return this._provinceCityDistribution;
  }
  get lastCalculatedAt(): Date {
    return this._lastCalculatedAt;
  }
  get createdAt(): Date {
    return this._createdAt;
  }
  get updatedAt(): Date {
    return this._updatedAt;
  }
  get domainEvents(): DomainEvent[] {
    return [...this._domainEvents];
  }

  /**
   * 创建新的团队统计记录 (推荐关系创建时)
   */
  static create(userId: bigint, accountSequence: string): TeamStatistics {
    const now = new Date();
    return new TeamStatistics(
      0n,
      UserId.create(userId),
      accountSequence,
      0,
      0,
      0,
      0,
      LeaderboardScore.zero(),
      ProvinceCityDistribution.empty(),
      now,
      now,
      now,
    );
  }

  /**
   * 从持久化数据重建
   */
  static reconstitute(props: TeamStatisticsProps): TeamStatistics {
    const directTeamCounts = props.directReferrals?.map((d) => d.teamCount) ?? [];
    const leaderboardScore = LeaderboardScore.calculate(props.totalTeamCount, directTeamCounts);

    const directReferralStats = new Map<bigint, number>();
    props.directReferrals?.forEach((d) => {
      directReferralStats.set(d.referralId, d.teamCount);
    });

    return new TeamStatistics(
      props.id,
      UserId.create(props.userId),
      props.accountSequence,
      props.directReferralCount,
      props.totalTeamCount,
      props.personalPlantingCount,
      props.teamPlantingCount,
      leaderboardScore,
      ProvinceCityDistribution.fromJson(props.provinceCityDistribution),
      props.lastCalculatedAt,
      props.createdAt,
      props.updatedAt,
      directReferralStats,
    );
  }

  /**
   * 新增直推成员
   */
  addDirectReferral(referralUserId: bigint): void {
    this._directReferralCount++;
    this._directReferralStats.set(referralUserId, 0);
    this._updatedAt = new Date();
  }

  /**
   * 增加团队认种量
   * @param count 认种数量
   * @param provinceCode 省份代码
   * @param cityCode 城市代码
   * @param fromDirectReferralId 来自哪个直推 (如果是直推的下级)
   */
  addTeamPlanting(
    count: number,
    provinceCode: string,
    cityCode: string,
    fromDirectReferralId?: bigint,
  ): void {
    this._teamPlantingCount += count;
    this._totalTeamCount += count;
    this._provinceCityDistribution = this._provinceCityDistribution.add(
      provinceCode,
      cityCode,
      count,
    );

    // 更新直推团队统计
    if (fromDirectReferralId) {
      const currentCount = this._directReferralStats.get(fromDirectReferralId) ?? 0;
      this._directReferralStats.set(fromDirectReferralId, currentCount + count);
    }

    // 重新计算龙虎榜分值
    this.recalculateLeaderboardScore();
    this._lastCalculatedAt = new Date();
    this._updatedAt = new Date();

    this._domainEvents.push(
      new TeamStatisticsUpdatedEvent(
        this._userId.value,
        this._accountSequence,
        this._totalTeamCount,
        this._directReferralCount,
        this._leaderboardScore.score,
        'planting_added',
      ),
    );
  }

  /**
   * 增加个人认种量
   * 注意：个人认种不计入团队认种（teamPlantingCount 只统计下级的认种）
   */
  addPersonalPlanting(count: number, provinceCode: string, cityCode: string): void {
    this._personalPlantingCount += count;
    // 不更新 _teamPlantingCount，因为团队认种不包含自己
    this._provinceCityDistribution = this._provinceCityDistribution.add(
      provinceCode,
      cityCode,
      count,
    );
    this._lastCalculatedAt = new Date();
    this._updatedAt = new Date();

    this._domainEvents.push(
      new TeamStatisticsUpdatedEvent(
        this._userId.value,
        this._accountSequence,
        this._teamPlantingCount,
        this._directReferralCount,
        this._leaderboardScore.score,
        'planting_added',
      ),
    );
  }

  /**
   * 减少个人认种量
   * [纯新增] 用于转让卖方减持，与 addPersonalPlanting 对称
   * 注意：个人认种不计入 teamPlantingCount，所以只更新个人统计和省市分布
   */
  removePersonalPlanting(count: number, provinceCode: string, cityCode: string): void {
    this._personalPlantingCount = Math.max(0, this._personalPlantingCount - count);
    this._provinceCityDistribution = this._provinceCityDistribution.subtract(
      provinceCode,
      cityCode,
      count,
    );
    this._lastCalculatedAt = new Date();
    this._updatedAt = new Date();

    this._domainEvents.push(
      new TeamStatisticsUpdatedEvent(
        this._userId.value,
        this._accountSequence,
        this._teamPlantingCount,
        this._directReferralCount,
        this._leaderboardScore.score,
        'transfer_removed',
      ),
    );
  }

  /**
   * 重新计算龙虎榜分值
   */
  private recalculateLeaderboardScore(): void {
    const directTeamCounts = Array.from(this._directReferralStats.values());
    this._leaderboardScore = this._leaderboardScore.recalculate(
      this._totalTeamCount,
      directTeamCounts,
    );
  }

  /**
   * 获取直推团队统计
   */
  getDirectReferralStats(): Map<bigint, number> {
    return new Map(this._directReferralStats);
  }

  /**
   * 清除领域事件
   */
  clearDomainEvents(): void {
    this._domainEvents = [];
  }

  /**
   * 转换为持久化格式
   */
  toPersistence(): TeamStatisticsProps {
    const directReferrals: DirectReferralStats[] = [];
    this._directReferralStats.forEach((teamCount, referralId) => {
      directReferrals.push({ referralId, teamCount });
    });

    return {
      id: this._id,
      userId: this._userId.value,
      accountSequence: this._accountSequence,
      directReferralCount: this._directReferralCount,
      totalTeamCount: this._totalTeamCount,
      personalPlantingCount: this._personalPlantingCount,
      teamPlantingCount: this._teamPlantingCount,
      leaderboardScore: this._leaderboardScore.score,
      maxDirectTeamCount: this._leaderboardScore.maxDirectTeamCount,
      provinceCityDistribution: this._provinceCityDistribution.toJson(),
      lastCalculatedAt: this._lastCalculatedAt,
      createdAt: this._createdAt,
      updatedAt: this._updatedAt,
      directReferrals,
    };
  }
}
