import { Money } from '../../value-objects/money.vo';
import { Hashpower } from '../../value-objects/hashpower.vo';

/**
 * 奖励汇总聚合根
 * 维护用户的各类收益汇总数据
 */
export class RewardSummary {
  private _id: bigint | null = null;
  private readonly _userId: bigint;
  private readonly _accountSequence: string;

  // 待领取收益
  private _pendingUsdt: Money;
  private _pendingHashpower: Hashpower;
  private _pendingExpireAt: Date | null;

  // 可结算收益
  private _settleableUsdt: Money;
  private _settleableHashpower: Hashpower;

  // 已结算收益 (累计)
  private _settledTotalUsdt: Money;
  private _settledTotalHashpower: Hashpower;

  // 已过期收益 (累计)
  private _expiredTotalUsdt: Money;
  private _expiredTotalHashpower: Hashpower;

  private _lastUpdateAt: Date;
  private readonly _createdAt: Date;

  private constructor(userId: bigint, accountSequence: string) {
    this._userId = userId;
    this._accountSequence = accountSequence;
    this._pendingUsdt = Money.zero();
    this._pendingHashpower = Hashpower.zero();
    this._pendingExpireAt = null;
    this._settleableUsdt = Money.zero();
    this._settleableHashpower = Hashpower.zero();
    this._settledTotalUsdt = Money.zero();
    this._settledTotalHashpower = Hashpower.zero();
    this._expiredTotalUsdt = Money.zero();
    this._expiredTotalHashpower = Hashpower.zero();
    this._lastUpdateAt = new Date();
    this._createdAt = new Date();
  }

  // ============ Getters ============
  get id(): bigint | null { return this._id; }
  get userId(): bigint { return this._userId; }
  get accountSequence(): string { return this._accountSequence; }
  get pendingUsdt(): Money { return this._pendingUsdt; }
  get pendingHashpower(): Hashpower { return this._pendingHashpower; }
  get pendingExpireAt(): Date | null { return this._pendingExpireAt; }
  get settleableUsdt(): Money { return this._settleableUsdt; }
  get settleableHashpower(): Hashpower { return this._settleableHashpower; }
  get settledTotalUsdt(): Money { return this._settledTotalUsdt; }
  get settledTotalHashpower(): Hashpower { return this._settledTotalHashpower; }
  get expiredTotalUsdt(): Money { return this._expiredTotalUsdt; }
  get expiredTotalHashpower(): Hashpower { return this._expiredTotalHashpower; }
  get lastUpdateAt(): Date { return this._lastUpdateAt; }
  get createdAt(): Date { return this._createdAt; }

  // ============ 工厂方法 ============

  static create(userId: bigint, accountSequence: string): RewardSummary {
    return new RewardSummary(userId, accountSequence);
  }

  // ============ 领域行为 ============

  /**
   * 增加待领取收益
   */
  addPending(usdt: Money, hashpower: Hashpower, expireAt: Date): void {
    this._pendingUsdt = this._pendingUsdt.add(usdt);
    this._pendingHashpower = this._pendingHashpower.add(hashpower);
    // 更新为最早的过期时间
    if (!this._pendingExpireAt || expireAt < this._pendingExpireAt) {
      this._pendingExpireAt = expireAt;
    }
    this._lastUpdateAt = new Date();
  }

  /**
   * 待领取 → 可结算 (用户认种)
   */
  movePendingToSettleable(usdt: Money, hashpower: Hashpower): void {
    this._pendingUsdt = this._pendingUsdt.subtract(usdt);
    this._pendingHashpower = this._pendingHashpower.subtract(hashpower);
    this._settleableUsdt = this._settleableUsdt.add(usdt);
    this._settleableHashpower = this._settleableHashpower.add(hashpower);

    // 如果待领取清空了，清除过期时间
    if (this._pendingUsdt.isZero()) {
      this._pendingExpireAt = null;
    }
    this._lastUpdateAt = new Date();
  }

  /**
   * 待领取 → 已过期
   */
  movePendingToExpired(usdt: Money, hashpower: Hashpower): void {
    this._pendingUsdt = this._pendingUsdt.subtract(usdt);
    this._pendingHashpower = this._pendingHashpower.subtract(hashpower);
    this._expiredTotalUsdt = this._expiredTotalUsdt.add(usdt);
    this._expiredTotalHashpower = this._expiredTotalHashpower.add(hashpower);

    if (this._pendingUsdt.isZero()) {
      this._pendingExpireAt = null;
    }
    this._lastUpdateAt = new Date();
  }

  /**
   * 增加可结算收益 (直接可结算的奖励)
   */
  addSettleable(usdt: Money, hashpower: Hashpower): void {
    this._settleableUsdt = this._settleableUsdt.add(usdt);
    this._settleableHashpower = this._settleableHashpower.add(hashpower);
    this._lastUpdateAt = new Date();
  }

  /**
   * 可结算 → 已结算
   */
  settle(usdt: Money, hashpower: Hashpower): void {
    this._settleableUsdt = this._settleableUsdt.subtract(usdt);
    this._settleableHashpower = this._settleableHashpower.subtract(hashpower);
    this._settledTotalUsdt = this._settledTotalUsdt.add(usdt);
    this._settledTotalHashpower = this._settledTotalHashpower.add(hashpower);
    this._lastUpdateAt = new Date();
  }

  setId(id: bigint): void {
    this._id = id;
  }

  // ============ 重建 ============

  static reconstitute(data: {
    id: bigint;
    userId: bigint;
    accountSequence: string;
    pendingUsdt: number;
    pendingHashpower: number;
    pendingExpireAt: Date | null;
    settleableUsdt: number;
    settleableHashpower: number;
    settledTotalUsdt: number;
    settledTotalHashpower: number;
    expiredTotalUsdt: number;
    expiredTotalHashpower: number;
    lastUpdateAt: Date;
    createdAt: Date;
  }): RewardSummary {
    const summary = new RewardSummary(data.userId, data.accountSequence);
    summary._id = data.id;
    summary._pendingUsdt = Money.USDT(data.pendingUsdt);
    summary._pendingHashpower = Hashpower.create(data.pendingHashpower);
    summary._pendingExpireAt = data.pendingExpireAt;
    summary._settleableUsdt = Money.USDT(data.settleableUsdt);
    summary._settleableHashpower = Hashpower.create(data.settleableHashpower);
    summary._settledTotalUsdt = Money.USDT(data.settledTotalUsdt);
    summary._settledTotalHashpower = Hashpower.create(data.settledTotalHashpower);
    summary._expiredTotalUsdt = Money.USDT(data.expiredTotalUsdt);
    summary._expiredTotalHashpower = Hashpower.create(data.expiredTotalHashpower);
    return summary;
  }
}
