import Decimal from 'decimal.js';
import { ContributionAmount } from '../value-objects/contribution-amount.vo';

/**
 * 贡献值来源类型
 */
export enum ContributionSourceType {
  PERSONAL = 'PERSONAL',       // 来自自己认种
  TEAM_LEVEL = 'TEAM_LEVEL',   // 来自团队层级
  TEAM_BONUS = 'TEAM_BONUS',   // 来自团队额外奖励
}

/**
 * 算力账户聚合根
 * 管理用户的贡献值/算力
 */
export class ContributionAccountAggregate {
  private _id: bigint | null;
  private _accountSequence: string;
  private _personalContribution: ContributionAmount;
  private _teamLevelContribution: ContributionAmount;
  private _teamBonusContribution: ContributionAmount;
  private _totalContribution: ContributionAmount;
  private _effectiveContribution: ContributionAmount;
  private _hasAdopted: boolean;
  private _directReferralAdoptedCount: number;
  private _unlockedLevelDepth: number;
  private _unlockedBonusTiers: number;
  private _version: number;
  private _createdAt: Date;
  private _updatedAt: Date;

  constructor(props: {
    id?: bigint | null;
    accountSequence: string;
    personalContribution?: ContributionAmount;
    teamLevelContribution?: ContributionAmount;
    teamBonusContribution?: ContributionAmount;
    totalContribution?: ContributionAmount;
    effectiveContribution?: ContributionAmount;
    hasAdopted?: boolean;
    directReferralAdoptedCount?: number;
    unlockedLevelDepth?: number;
    unlockedBonusTiers?: number;
    version?: number;
    createdAt?: Date;
    updatedAt?: Date;
  }) {
    this._id = props.id ?? null;
    this._accountSequence = props.accountSequence;
    this._personalContribution = props.personalContribution ?? ContributionAmount.zero();
    this._teamLevelContribution = props.teamLevelContribution ?? ContributionAmount.zero();
    this._teamBonusContribution = props.teamBonusContribution ?? ContributionAmount.zero();
    this._totalContribution = props.totalContribution ?? ContributionAmount.zero();
    this._effectiveContribution = props.effectiveContribution ?? ContributionAmount.zero();
    this._hasAdopted = props.hasAdopted ?? false;
    this._directReferralAdoptedCount = props.directReferralAdoptedCount ?? 0;
    this._unlockedLevelDepth = props.unlockedLevelDepth ?? 0;
    this._unlockedBonusTiers = props.unlockedBonusTiers ?? 0;
    this._version = props.version ?? 1;
    this._createdAt = props.createdAt ?? new Date();
    this._updatedAt = props.updatedAt ?? new Date();
  }

  // Getters
  get id(): bigint | null { return this._id; }
  get accountSequence(): string { return this._accountSequence; }
  get personalContribution(): ContributionAmount { return this._personalContribution; }
  get teamLevelContribution(): ContributionAmount { return this._teamLevelContribution; }
  get teamBonusContribution(): ContributionAmount { return this._teamBonusContribution; }
  get totalContribution(): ContributionAmount { return this._totalContribution; }
  get effectiveContribution(): ContributionAmount { return this._effectiveContribution; }
  get hasAdopted(): boolean { return this._hasAdopted; }
  get directReferralAdoptedCount(): number { return this._directReferralAdoptedCount; }
  get unlockedLevelDepth(): number { return this._unlockedLevelDepth; }
  get unlockedBonusTiers(): number { return this._unlockedBonusTiers; }
  get version(): number { return this._version; }
  get createdAt(): Date { return this._createdAt; }
  get updatedAt(): Date { return this._updatedAt; }

  /**
   * 添加个人贡献值
   */
  addPersonalContribution(amount: ContributionAmount): void {
    this._personalContribution = this._personalContribution.add(amount);
    this.recalculateTotal();
  }

  /**
   * 添加团队层级贡献值
   */
  addTeamLevelContribution(amount: ContributionAmount): void {
    this._teamLevelContribution = this._teamLevelContribution.add(amount);
    this.recalculateTotal();
  }

  /**
   * 添加团队额外奖励贡献值
   */
  addTeamBonusContribution(amount: ContributionAmount): void {
    this._teamBonusContribution = this._teamBonusContribution.add(amount);
    this.recalculateTotal();
  }

  /**
   * 标记用户已认种
   */
  markAsAdopted(): void {
    this._hasAdopted = true;
    this.updateUnlockStatus();
  }

  /**
   * 增加直推认种用户数
   */
  incrementDirectReferralAdoptedCount(): void {
    this._directReferralAdoptedCount++;
    this.updateUnlockStatus();
  }

  /**
   * 设置直推认种用户数
   */
  setDirectReferralAdoptedCount(count: number): void {
    this._directReferralAdoptedCount = count;
    this.updateUnlockStatus();
  }

  /**
   * 更新有效贡献值（扣除过期的）
   */
  updateEffectiveContribution(effective: ContributionAmount): void {
    this._effectiveContribution = effective;
    this._updatedAt = new Date();
  }

  /**
   * 重新计算总贡献值
   */
  private recalculateTotal(): void {
    this._totalContribution = this._personalContribution
      .add(this._teamLevelContribution)
      .add(this._teamBonusContribution);
    this._effectiveContribution = this._totalContribution; // 初始时有效=总量
    this._updatedAt = new Date();
  }

  /**
   * 更新解锁状态
   * 根据直推认种用户数和是否认种过
   */
  private updateUnlockStatus(): void {
    // 层级解锁规则
    if (this._directReferralAdoptedCount >= 5) {
      this._unlockedLevelDepth = 15;
    } else if (this._directReferralAdoptedCount >= 3) {
      this._unlockedLevelDepth = 10;
    } else if (this._directReferralAdoptedCount >= 1) {
      this._unlockedLevelDepth = 5;
    } else {
      this._unlockedLevelDepth = 0;
    }

    // 额外奖励解锁规则
    let bonusTiers = 0;
    if (this._hasAdopted) bonusTiers++;
    if (this._directReferralAdoptedCount >= 2) bonusTiers++;
    if (this._directReferralAdoptedCount >= 4) bonusTiers++;
    this._unlockedBonusTiers = bonusTiers;

    this._updatedAt = new Date();
  }

  /**
   * 增加版本号（乐观锁）
   */
  incrementVersion(): void {
    this._version++;
    this._updatedAt = new Date();
  }

  /**
   * 创建新账户
   */
  static create(accountSequence: string): ContributionAccountAggregate {
    return new ContributionAccountAggregate({ accountSequence });
  }

  /**
   * 从持久化数据恢复
   */
  static fromPersistence(data: {
    id: bigint;
    accountSequence: string;
    personalContribution: Decimal;
    teamLevelContribution: Decimal;
    teamBonusContribution: Decimal;
    totalContribution: Decimal;
    effectiveContribution: Decimal;
    hasAdopted: boolean;
    directReferralAdoptedCount: number;
    unlockedLevelDepth: number;
    unlockedBonusTiers: number;
    version: number;
    createdAt: Date;
    updatedAt: Date;
  }): ContributionAccountAggregate {
    return new ContributionAccountAggregate({
      id: data.id,
      accountSequence: data.accountSequence,
      personalContribution: new ContributionAmount(data.personalContribution),
      teamLevelContribution: new ContributionAmount(data.teamLevelContribution),
      teamBonusContribution: new ContributionAmount(data.teamBonusContribution),
      totalContribution: new ContributionAmount(data.totalContribution),
      effectiveContribution: new ContributionAmount(data.effectiveContribution),
      hasAdopted: data.hasAdopted,
      directReferralAdoptedCount: data.directReferralAdoptedCount,
      unlockedLevelDepth: data.unlockedLevelDepth,
      unlockedBonusTiers: data.unlockedBonusTiers,
      version: data.version,
      createdAt: data.createdAt,
      updatedAt: data.updatedAt,
    });
  }

  /**
   * 转换为持久化数据
   */
  toPersistence(): {
    accountSequence: string;
    personalContribution: Decimal;
    teamLevelContribution: Decimal;
    teamBonusContribution: Decimal;
    totalContribution: Decimal;
    effectiveContribution: Decimal;
    hasAdopted: boolean;
    directReferralAdoptedCount: number;
    unlockedLevelDepth: number;
    unlockedBonusTiers: number;
    version: number;
  } {
    return {
      accountSequence: this._accountSequence,
      personalContribution: this._personalContribution.value,
      teamLevelContribution: this._teamLevelContribution.value,
      teamBonusContribution: this._teamBonusContribution.value,
      totalContribution: this._totalContribution.value,
      effectiveContribution: this._effectiveContribution.value,
      hasAdopted: this._hasAdopted,
      directReferralAdoptedCount: this._directReferralAdoptedCount,
      unlockedLevelDepth: this._unlockedLevelDepth,
      unlockedBonusTiers: this._unlockedBonusTiers,
      version: this._version,
    };
  }
}
