/**
 * Value Object: EventName
 * Validates and encapsulates a telemetry event name.
 * Event names must be non-empty, max 64 characters, and follow snake_case convention.
 */
export class EventName {
  private static readonly MAX_LENGTH = 64;
  private static readonly PATTERN = /^[a-z][a-z0-9_]*$/;

  private constructor(private readonly value: string) {}

  static create(name: string): EventName {
    if (!name || name.trim().length === 0) {
      throw new Error('Event name cannot be empty');
    }
    if (name.length > EventName.MAX_LENGTH) {
      throw new Error(`Event name must be at most ${EventName.MAX_LENGTH} characters, got ${name.length}`);
    }
    if (!EventName.PATTERN.test(name)) {
      throw new Error(`Event name must be snake_case (lowercase letters, digits, underscores): "${name}"`);
    }
    return new EventName(name);
  }

  /**
   * Create an EventName without strict pattern validation (for legacy/external events).
   * Still enforces max length.
   */
  static createLenient(name: string): EventName {
    if (!name || name.trim().length === 0) {
      throw new Error('Event name cannot be empty');
    }
    if (name.length > EventName.MAX_LENGTH) {
      throw new Error(`Event name must be at most ${EventName.MAX_LENGTH} characters, got ${name.length}`);
    }
    return new EventName(name);
  }

  toString(): string {
    return this.value;
  }

  equals(other: EventName): boolean {
    return this.value === other.value;
  }

  /** Check if this is a session-related event */
  isSessionEvent(): boolean {
    return this.value === 'app_session_start' || this.value === 'app_session_end';
  }

  /** Check if this is a heartbeat-related event */
  isHeartbeatEvent(): boolean {
    return this.value === 'heartbeat' || this.value === 'app_heartbeat';
  }
}
