import { VirtualAccountType } from '../value-objects/virtual-account-type.enum';

/**
 * 虚拟账户实体
 *
 * 用于管理系统虚拟账户，包括：
 * - 排名虚拟账户（用于占据榜单前列位置）
 * - 系统省公司账户
 * - 系统市公司账户
 * - 总部社区账户
 */
export class VirtualAccount {
  private _id: bigint | null = null;
  private readonly _accountType: VirtualAccountType;
  private _displayName: string;
  private _avatar: string | null;
  private readonly _provinceCode: string | null;
  private readonly _cityCode: string | null;
  private _minScore: number | null;
  private _maxScore: number | null;
  private _currentScore: number;
  private _usdtBalance: number;
  private _hashpowerBalance: number;
  private _isActive: boolean;
  private readonly _createdAt: Date;

  private constructor(
    accountType: VirtualAccountType,
    displayName: string,
    avatar: string | null,
    provinceCode: string | null,
    cityCode: string | null,
    minScore: number | null,
    maxScore: number | null,
  ) {
    this._accountType = accountType;
    this._displayName = displayName;
    this._avatar = avatar;
    this._provinceCode = provinceCode;
    this._cityCode = cityCode;
    this._minScore = minScore;
    this._maxScore = maxScore;
    this._currentScore = 0;
    this._usdtBalance = 0;
    this._hashpowerBalance = 0;
    this._isActive = true;
    this._createdAt = new Date();
  }

  // ============ Getters ============
  get id(): bigint | null { return this._id; }
  get accountType(): VirtualAccountType { return this._accountType; }
  get displayName(): string { return this._displayName; }
  get avatar(): string | null { return this._avatar; }
  get provinceCode(): string | null { return this._provinceCode; }
  get cityCode(): string | null { return this._cityCode; }
  get minScore(): number | null { return this._minScore; }
  get maxScore(): number | null { return this._maxScore; }
  get currentScore(): number { return this._currentScore; }
  get usdtBalance(): number { return this._usdtBalance; }
  get hashpowerBalance(): number { return this._hashpowerBalance; }
  get isActive(): boolean { return this._isActive; }
  get createdAt(): Date { return this._createdAt; }

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

  /**
   * 创建排名虚拟账户
   */
  static createRankingVirtual(params: {
    displayName: string;
    avatar?: string;
    minScore: number;
    maxScore: number;
  }): VirtualAccount {
    return new VirtualAccount(
      VirtualAccountType.RANKING_VIRTUAL,
      params.displayName,
      params.avatar || null,
      null,
      null,
      params.minScore,
      params.maxScore,
    );
  }

  /**
   * 创建系统省公司账户
   */
  static createSystemProvince(provinceCode: string, provinceName: string): VirtualAccount {
    return new VirtualAccount(
      VirtualAccountType.SYSTEM_PROVINCE,
      `系统省公司-${provinceName}`,
      null,
      provinceCode,
      null,
      null,
      null,
    );
  }

  /**
   * 创建系统市公司账户
   */
  static createSystemCity(cityCode: string, cityName: string): VirtualAccount {
    return new VirtualAccount(
      VirtualAccountType.SYSTEM_CITY,
      `系统市公司-${cityName}`,
      null,
      null,
      cityCode,
      null,
      null,
    );
  }

  /**
   * 创建总部社区账户
   */
  static createHeadquarters(): VirtualAccount {
    return new VirtualAccount(
      VirtualAccountType.HEADQUARTERS,
      '总部',
      null,
      null,
      null,
      null,
      null,
    );
  }

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

  /**
   * 生成随机分值
   */
  generateRandomScore(): number {
    if (this._minScore === null || this._maxScore === null) {
      return 0;
    }
    this._currentScore = Math.floor(
      Math.random() * (this._maxScore - this._minScore + 1) + this._minScore
    );
    return this._currentScore;
  }

  /**
   * 设置当前分值
   */
  setCurrentScore(score: number): void {
    this._currentScore = score;
  }

  /**
   * 增加余额
   */
  addBalance(usdtAmount: number, hashpowerAmount: number): void {
    this._usdtBalance += usdtAmount;
    this._hashpowerBalance += hashpowerAmount;
  }

  /**
   * 扣减余额
   */
  deductBalance(usdtAmount: number, hashpowerAmount: number): void {
    if (this._usdtBalance < usdtAmount) {
      throw new Error('USDT余额不足');
    }
    if (this._hashpowerBalance < hashpowerAmount) {
      throw new Error('算力余额不足');
    }
    this._usdtBalance -= usdtAmount;
    this._hashpowerBalance -= hashpowerAmount;
  }

  /**
   * 激活账户
   */
  activate(): void {
    this._isActive = true;
  }

  /**
   * 停用账户
   */
  deactivate(): void {
    this._isActive = false;
  }

  /**
   * 更新显示信息
   */
  updateDisplayInfo(displayName: string, avatar?: string): void {
    this._displayName = displayName;
    if (avatar !== undefined) {
      this._avatar = avatar;
    }
  }

  /**
   * 更新分值范围
   */
  updateScoreRange(minScore: number, maxScore: number): void {
    if (minScore > maxScore) {
      throw new Error('最小分值不能大于最大分值');
    }
    this._minScore = minScore;
    this._maxScore = maxScore;
  }

  /**
   * 判断是否是排名虚拟账户
   */
  isRankingVirtual(): boolean {
    return this._accountType === VirtualAccountType.RANKING_VIRTUAL;
  }

  /**
   * 判断是否是系统账户（省/市公司或总部）
   */
  isSystemAccount(): boolean {
    return [
      VirtualAccountType.SYSTEM_PROVINCE,
      VirtualAccountType.SYSTEM_CITY,
      VirtualAccountType.HEADQUARTERS,
    ].includes(this._accountType);
  }

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

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

  static reconstitute(data: {
    id: bigint;
    accountType: VirtualAccountType;
    displayName: string;
    avatar: string | null;
    provinceCode: string | null;
    cityCode: string | null;
    minScore: number | null;
    maxScore: number | null;
    currentScore: number;
    usdtBalance: number;
    hashpowerBalance: number;
    isActive: boolean;
    createdAt: Date;
  }): VirtualAccount {
    const account = new VirtualAccount(
      data.accountType,
      data.displayName,
      data.avatar,
      data.provinceCode,
      data.cityCode,
      data.minScore,
      data.maxScore,
    );
    account._id = data.id;
    account._currentScore = data.currentScore;
    account._usdtBalance = data.usdtBalance;
    account._hashpowerBalance = data.hashpowerBalance;
    account._isActive = data.isActive;
    return account;
  }
}
