import { DomainEvent } from '../../events/domain-event.base';
import { ConfigUpdatedEvent } from '../../events/config-updated.event';
import { LeaderboardType } from '../../value-objects/leaderboard-type.enum';

/**
 * 龙虎榜配置聚合根
 *
 * 不变式:
 * 1. 虚拟账户数量不能为负数
 * 2. 显示数量必须大于0
 * 3. 刷新间隔必须大于0
 */
export class LeaderboardConfig {
  private _id: bigint | null = null;
  private readonly _configKey: string;

  // 榜单开关
  private _dailyEnabled: boolean;
  private _weeklyEnabled: boolean;
  private _monthlyEnabled: boolean;

  // 虚拟排名设置
  private _virtualRankingEnabled: boolean;
  private _virtualAccountCount: number;

  // 显示设置
  private _displayLimit: number;

  // 刷新设置
  private _refreshIntervalMinutes: number;

  private readonly _createdAt: Date;

  private _domainEvents: DomainEvent[] = [];

  private constructor(
    configKey: string,
    dailyEnabled: boolean,
    weeklyEnabled: boolean,
    monthlyEnabled: boolean,
    virtualRankingEnabled: boolean,
    virtualAccountCount: number,
    displayLimit: number,
    refreshIntervalMinutes: number,
  ) {
    this._configKey = configKey;
    this._dailyEnabled = dailyEnabled;
    this._weeklyEnabled = weeklyEnabled;
    this._monthlyEnabled = monthlyEnabled;
    this._virtualRankingEnabled = virtualRankingEnabled;
    this._virtualAccountCount = virtualAccountCount;
    this._displayLimit = displayLimit;
    this._refreshIntervalMinutes = refreshIntervalMinutes;
    this._createdAt = new Date();
  }

  // ============ Getters ============
  get id(): bigint | null { return this._id; }
  get configKey(): string { return this._configKey; }
  get dailyEnabled(): boolean { return this._dailyEnabled; }
  get weeklyEnabled(): boolean { return this._weeklyEnabled; }
  get monthlyEnabled(): boolean { return this._monthlyEnabled; }
  get virtualRankingEnabled(): boolean { return this._virtualRankingEnabled; }
  get virtualAccountCount(): number { return this._virtualAccountCount; }
  get displayLimit(): number { return this._displayLimit; }
  get refreshIntervalMinutes(): number { return this._refreshIntervalMinutes; }
  get createdAt(): Date { return this._createdAt; }
  get domainEvents(): DomainEvent[] { return [...this._domainEvents]; }

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

  static createDefault(): LeaderboardConfig {
    return new LeaderboardConfig(
      'GLOBAL',
      true,   // dailyEnabled
      true,   // weeklyEnabled
      true,   // monthlyEnabled
      false,  // virtualRankingEnabled
      0,      // virtualAccountCount
      30,     // displayLimit
      5,      // refreshIntervalMinutes
    );
  }

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

  /**
   * 更新榜单开关
   */
  updateLeaderboardSwitch(
    type: 'daily' | 'weekly' | 'monthly',
    enabled: boolean,
    updatedBy: string,
  ): void {
    const changes: Record<string, any> = {};

    switch (type) {
      case 'daily':
        this._dailyEnabled = enabled;
        changes.dailyEnabled = enabled;
        break;
      case 'weekly':
        this._weeklyEnabled = enabled;
        changes.weeklyEnabled = enabled;
        break;
      case 'monthly':
        this._monthlyEnabled = enabled;
        changes.monthlyEnabled = enabled;
        break;
    }

    this._domainEvents.push(new ConfigUpdatedEvent({
      configKey: this._configKey,
      changes,
      updatedBy,
    }));
  }

  /**
   * 更新虚拟排名设置
   */
  updateVirtualRankingSettings(
    enabled: boolean,
    accountCount: number,
    updatedBy: string,
  ): void {
    if (accountCount < 0) {
      throw new Error('虚拟账户数量不能为负数');
    }

    this._virtualRankingEnabled = enabled;
    this._virtualAccountCount = accountCount;

    this._domainEvents.push(new ConfigUpdatedEvent({
      configKey: this._configKey,
      changes: {
        virtualRankingEnabled: enabled,
        virtualAccountCount: accountCount,
      },
      updatedBy,
    }));
  }

  /**
   * 更新显示数量
   */
  updateDisplayLimit(limit: number, updatedBy: string): void {
    if (limit <= 0) {
      throw new Error('显示数量必须大于0');
    }

    this._displayLimit = limit;

    this._domainEvents.push(new ConfigUpdatedEvent({
      configKey: this._configKey,
      changes: { displayLimit: limit },
      updatedBy,
    }));
  }

  /**
   * 更新刷新间隔
   */
  updateRefreshInterval(minutes: number, updatedBy: string): void {
    if (minutes <= 0) {
      throw new Error('刷新间隔必须大于0');
    }

    this._refreshIntervalMinutes = minutes;

    this._domainEvents.push(new ConfigUpdatedEvent({
      configKey: this._configKey,
      changes: { refreshIntervalMinutes: minutes },
      updatedBy,
    }));
  }

  /**
   * 检查榜单是否启用
   */
  isLeaderboardEnabled(type: LeaderboardType): boolean {
    switch (type) {
      case LeaderboardType.DAILY:
        return this._dailyEnabled;
      case LeaderboardType.WEEKLY:
        return this._weeklyEnabled;
      case LeaderboardType.MONTHLY:
        return this._monthlyEnabled;
      default:
        return false;
    }
  }

  /**
   * 获取虚拟排名应占据的位置数
   */
  getVirtualRankingSlots(): number {
    if (!this._virtualRankingEnabled) {
      return 0;
    }
    return this._virtualAccountCount;
  }

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

  clearDomainEvents(): void {
    this._domainEvents = [];
  }

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

  static reconstitute(data: {
    id: bigint;
    configKey: string;
    dailyEnabled: boolean;
    weeklyEnabled: boolean;
    monthlyEnabled: boolean;
    virtualRankingEnabled: boolean;
    virtualAccountCount: number;
    displayLimit: number;
    refreshIntervalMinutes: number;
  }): LeaderboardConfig {
    const config = new LeaderboardConfig(
      data.configKey,
      data.dailyEnabled,
      data.weeklyEnabled,
      data.monthlyEnabled,
      data.virtualRankingEnabled,
      data.virtualAccountCount,
      data.displayLimit,
      data.refreshIntervalMinutes,
    );
    config._id = data.id;
    return config;
  }
}
