import Decimal from 'decimal.js';
import { ContributionAmount } from '../value-objects/contribution-amount.vo';
import { DistributionRate } from '../value-objects/distribution-rate.vo';
import { ContributionSourceType } from './contribution-account.aggregate';

/**
 * 贡献值记录聚合根
 * 记录每一笔贡献值的来源和详情
 */
export class ContributionRecordAggregate {
  private _id: bigint | null;
  private _accountSequence: string;
  private _sourceType: ContributionSourceType;
  private _sourceAdoptionId: bigint;
  private _sourceAccountSequence: string;
  private _treeCount: number;
  private _baseContribution: ContributionAmount;
  private _distributionRate: DistributionRate;
  private _levelDepth: number | null;
  private _bonusTier: number | null;
  private _amount: ContributionAmount;
  private _effectiveDate: Date;
  private _expireDate: Date;
  private _isExpired: boolean;
  private _expiredAt: Date | null;
  private _createdAt: Date;

  constructor(props: {
    id?: bigint | null;
    accountSequence: string;
    sourceType: ContributionSourceType;
    sourceAdoptionId: bigint;
    sourceAccountSequence: string;
    treeCount: number;
    baseContribution: ContributionAmount;
    distributionRate: DistributionRate;
    levelDepth?: number | null;
    bonusTier?: number | null;
    amount: ContributionAmount;
    effectiveDate: Date;
    expireDate: Date;
    isExpired?: boolean;
    expiredAt?: Date | null;
    createdAt?: Date;
  }) {
    this._id = props.id ?? null;
    this._accountSequence = props.accountSequence;
    this._sourceType = props.sourceType;
    this._sourceAdoptionId = props.sourceAdoptionId;
    this._sourceAccountSequence = props.sourceAccountSequence;
    this._treeCount = props.treeCount;
    this._baseContribution = props.baseContribution;
    this._distributionRate = props.distributionRate;
    this._levelDepth = props.levelDepth ?? null;
    this._bonusTier = props.bonusTier ?? null;
    this._amount = props.amount;
    this._effectiveDate = props.effectiveDate;
    this._expireDate = props.expireDate;
    this._isExpired = props.isExpired ?? false;
    this._expiredAt = props.expiredAt ?? null;
    this._createdAt = props.createdAt ?? new Date();
  }

  // Getters
  get id(): bigint | null { return this._id; }
  get accountSequence(): string { return this._accountSequence; }
  get sourceType(): ContributionSourceType { return this._sourceType; }
  get sourceAdoptionId(): bigint { return this._sourceAdoptionId; }
  get sourceAccountSequence(): string { return this._sourceAccountSequence; }
  get treeCount(): number { return this._treeCount; }
  get baseContribution(): ContributionAmount { return this._baseContribution; }
  get distributionRate(): DistributionRate { return this._distributionRate; }
  get levelDepth(): number | null { return this._levelDepth; }
  get bonusTier(): number | null { return this._bonusTier; }
  get amount(): ContributionAmount { return this._amount; }
  get effectiveDate(): Date { return this._effectiveDate; }
  get expireDate(): Date { return this._expireDate; }
  get isExpired(): boolean { return this._isExpired; }
  get expiredAt(): Date | null { return this._expiredAt; }
  get createdAt(): Date { return this._createdAt; }

  /**
   * 标记为已过期
   */
  markAsExpired(): void {
    if (this._isExpired) {
      return;
    }
    this._isExpired = true;
    this._expiredAt = new Date();
  }

  /**
   * 检查是否应该过期
   */
  shouldExpire(currentDate: Date = new Date()): boolean {
    return !this._isExpired && currentDate >= this._expireDate;
  }

  /**
   * 创建个人贡献值记录
   */
  static createPersonal(props: {
    accountSequence: string;
    sourceAdoptionId: bigint;
    treeCount: number;
    baseContribution: ContributionAmount;
    effectiveDate: Date;
    expireDate: Date;
  }): ContributionRecordAggregate {
    const rate = DistributionRate.PERSONAL;
    const amount = props.baseContribution.multiply(props.treeCount).multiply(rate.value);

    return new ContributionRecordAggregate({
      accountSequence: props.accountSequence,
      sourceType: ContributionSourceType.PERSONAL,
      sourceAdoptionId: props.sourceAdoptionId,
      sourceAccountSequence: props.accountSequence,
      treeCount: props.treeCount,
      baseContribution: props.baseContribution,
      distributionRate: rate,
      amount: amount,
      effectiveDate: props.effectiveDate,
      expireDate: props.expireDate,
    });
  }

  /**
   * 创建团队层级贡献值记录
   */
  static createTeamLevel(props: {
    accountSequence: string;
    sourceAdoptionId: bigint;
    sourceAccountSequence: string;
    treeCount: number;
    baseContribution: ContributionAmount;
    levelDepth: number;
    effectiveDate: Date;
    expireDate: Date;
  }): ContributionRecordAggregate {
    const rate = DistributionRate.LEVEL_PER;
    const amount = props.baseContribution.multiply(props.treeCount).multiply(rate.value);

    return new ContributionRecordAggregate({
      accountSequence: props.accountSequence,
      sourceType: ContributionSourceType.TEAM_LEVEL,
      sourceAdoptionId: props.sourceAdoptionId,
      sourceAccountSequence: props.sourceAccountSequence,
      treeCount: props.treeCount,
      baseContribution: props.baseContribution,
      distributionRate: rate,
      levelDepth: props.levelDepth,
      amount: amount,
      effectiveDate: props.effectiveDate,
      expireDate: props.expireDate,
    });
  }

  /**
   * 创建团队额外奖励贡献值记录
   */
  static createTeamBonus(props: {
    accountSequence: string;
    sourceAdoptionId: bigint;
    sourceAccountSequence: string;
    treeCount: number;
    baseContribution: ContributionAmount;
    bonusTier: number;
    effectiveDate: Date;
    expireDate: Date;
  }): ContributionRecordAggregate {
    const rate = DistributionRate.BONUS_PER;
    const amount = props.baseContribution.multiply(props.treeCount).multiply(rate.value);

    return new ContributionRecordAggregate({
      accountSequence: props.accountSequence,
      sourceType: ContributionSourceType.TEAM_BONUS,
      sourceAdoptionId: props.sourceAdoptionId,
      sourceAccountSequence: props.sourceAccountSequence,
      treeCount: props.treeCount,
      baseContribution: props.baseContribution,
      distributionRate: rate,
      bonusTier: props.bonusTier,
      amount: amount,
      effectiveDate: props.effectiveDate,
      expireDate: props.expireDate,
    });
  }

  /**
   * 从持久化数据恢复
   */
  static fromPersistence(data: {
    id: bigint;
    accountSequence: string;
    sourceType: string;
    sourceAdoptionId: bigint;
    sourceAccountSequence: string;
    treeCount: number;
    baseContribution: Decimal;
    distributionRate: Decimal;
    levelDepth: number | null;
    bonusTier: number | null;
    amount: Decimal;
    effectiveDate: Date;
    expireDate: Date;
    isExpired: boolean;
    expiredAt: Date | null;
    createdAt: Date;
  }): ContributionRecordAggregate {
    return new ContributionRecordAggregate({
      id: data.id,
      accountSequence: data.accountSequence,
      sourceType: data.sourceType as ContributionSourceType,
      sourceAdoptionId: data.sourceAdoptionId,
      sourceAccountSequence: data.sourceAccountSequence,
      treeCount: data.treeCount,
      baseContribution: new ContributionAmount(data.baseContribution),
      distributionRate: new DistributionRate(data.distributionRate),
      levelDepth: data.levelDepth,
      bonusTier: data.bonusTier,
      amount: new ContributionAmount(data.amount),
      effectiveDate: data.effectiveDate,
      expireDate: data.expireDate,
      isExpired: data.isExpired,
      expiredAt: data.expiredAt,
      createdAt: data.createdAt,
    });
  }

  /**
   * 转换为持久化数据
   */
  toPersistence(): {
    accountSequence: string;
    sourceType: string;
    sourceAdoptionId: bigint;
    sourceAccountSequence: string;
    treeCount: number;
    baseContribution: Decimal;
    distributionRate: Decimal;
    levelDepth: number | null;
    bonusTier: number | null;
    amount: Decimal;
    effectiveDate: Date;
    expireDate: Date;
    isExpired: boolean;
    expiredAt: Date | null;
  } {
    return {
      accountSequence: this._accountSequence,
      sourceType: this._sourceType,
      sourceAdoptionId: this._sourceAdoptionId,
      sourceAccountSequence: this._sourceAccountSequence,
      treeCount: this._treeCount,
      baseContribution: this._baseContribution.value,
      distributionRate: this._distributionRate.value,
      levelDepth: this._levelDepth,
      bonusTier: this._bonusTier,
      amount: this._amount.value,
      effectiveDate: this._effectiveDate,
      expireDate: this._expireDate,
      isExpired: this._isExpired,
      expiredAt: this._expiredAt,
    };
  }
}
