/**
 * Domain Entity: EngagementEvent
 *
 * Represents user interactions beyond page views.
 * Tracks clicks, downloads, sign-ups, and other engagement actions.
 */

import { Entity } from '@core/shared/domain/Entity';
import type {
    EngagementAction,
    EngagementEntityType,
    EngagementEventProps,
} from '../types/EngagementEvent';
import { AnalyticsEntityId } from '../value-objects/AnalyticsEntityId';

export type { EngagementAction, EngagementEntityType } from '../types/EngagementEvent';

export class EngagementEvent extends Entity<string> {
  readonly action: EngagementAction;
  readonly entityType: EngagementEntityType;
  readonly actorId: string | undefined;
  readonly actorType: 'anonymous' | 'driver' | 'sponsor';
  readonly sessionId: string;
  readonly metadata: Record<string, string | number | boolean> | undefined;
  readonly timestamp: Date;

  private readonly entityIdVo: AnalyticsEntityId;

  private constructor(props: EngagementEventProps) {
    super(props.id);
    
    this.action = props.action;
    this.entityType = props.entityType;
    this.entityIdVo = AnalyticsEntityId.create(props.entityId);
    this.actorId = props.actorId;
    this.actorType = props.actorType;
    this.sessionId = props.sessionId;
    this.metadata = props.metadata;
    this.timestamp = props.timestamp;
  }

  get entityId(): string {
    return this.entityIdVo.value;
  }

  static create(props: Omit<EngagementEventProps, 'timestamp'> & { timestamp?: Date }): EngagementEvent {
    this.validate(props);

    return new EngagementEvent({
      ...props,
      timestamp: props.timestamp ?? new Date(),
    });
  }

  private static validate(props: Omit<EngagementEventProps, 'timestamp'>): void {
    if (!props.id || props.id.trim().length === 0) {
      throw new Error('EngagementEvent ID is required');
    }

    if (!props.action) {
      throw new Error('EngagementEvent action is required');
    }

    if (!props.entityType) {
      throw new Error('EngagementEvent entityType is required');
    }

    if (!props.entityId || props.entityId.trim().length === 0) {
      throw new Error('EngagementEvent entityId is required');
    }

    if (!props.sessionId || props.sessionId.trim().length === 0) {
      throw new Error('EngagementEvent sessionId is required');
    }
  }

  /**
   * Check if this is a sponsor-related engagement
   */
  isSponsorEngagement(): boolean {
    return this.action.startsWith('click_sponsor') || 
           this.action === 'contact_sponsor' ||
           this.entityType === 'sponsor' ||
           this.entityType === 'sponsorship';
  }

  /**
   * Check if this is a conversion event (high-value action)
   */
  isConversionEvent(): boolean {
    return ['join_league', 'register_race', 'click_sponsor_url', 'contact_sponsor'].includes(this.action);
  }

  /**
   * Get engagement weight for analytics calculations
   */
  getEngagementWeight(): number {
    const weights: Record<EngagementAction, number> = {
      'click_sponsor_logo': 2,
      'click_sponsor_url': 5,
      'download_livery_pack': 3,
      'join_league': 10,
      'register_race': 8,
      'view_standings': 1,
      'view_schedule': 1,
      'share_social': 4,
      'contact_sponsor': 15,
    };
    return weights[this.action] || 1;
  }
}