/**
 * Analytics Event Types and Definitions
 *
 * Defines event types for tracking player actions and game metrics.
 * Ported from Python: ws/analytics/events.py
 */

// ============================================================================
// Event Types
// ============================================================================

/**
 * Core event categories
 */
export type EventCategory =
  | 'session'
  | 'purchase'
  | 'gameplay'
  | 'social'
  | 'progression'
  | 'tutorial'
  | 'retention'
  | 'system';

/**
 * Standard event names by category
 */
export const EVENT_NAMES = {
  // Session events
  SESSION_START: 'session_start',
  SESSION_END: 'session_end',
  SESSION_RESUME: 'session_resume',

  // Purchase events
  PURCHASE_INITIATED: 'purchase_initiated',
  PURCHASE_COMPLETED: 'purchase_completed',
  PURCHASE_FAILED: 'purchase_failed',
  PURCHASE_RESTORED: 'purchase_restored',

  // Gameplay events
  GAME_START: 'game_start',
  GAME_PAUSE: 'game_pause',
  GAME_RESUME: 'game_resume',
  GAME_SAVE: 'game_save',
  CHARACTER_CREATED: 'character_created',
  CHARACTER_DEATH: 'character_death',
  AGE_UP: 'age_up',
  ACTIVITY_STARTED: 'activity_started',
  ACTIVITY_COMPLETED: 'activity_completed',

  // Social events
  CONVERSATION_STARTED: 'conversation_started',
  CONVERSATION_SENT: 'conversation_sent',
  CONVERSATION_RECEIVED: 'conversation_received',
  RELATIONSHIP_FORMED: 'relationship_formed',
  RELATIONSHIP_ENDED: 'relationship_ended',
  FRIEND_MADE: 'friend_made',
  DATING_STARTED: 'dating_started',
  MARRIAGE: 'marriage',
  CHILD_BORN: 'child_born',

  // Progression events
  LEVEL_UP: 'level_up',
  ACHIEVEMENT_UNLOCKED: 'achievement_unlocked',
  QUEST_COMPLETED: 'quest_completed',
  MILESTONE_REACHED: 'milestone_reached',
  JOB_OBTAINED: 'job_obtained',
  JOB_PROMOTION: 'job_promotion',
  JOB_FIRED: 'job_fired',
  EDUCATION_STARTED: 'education_started',
  EDUCATION_COMPLETED: 'education_completed',
  MONEY_EARNED: 'money_earned',
  MONEY_SPENT: 'money_spent',

  // Tutorial events
  TUTORIAL_STARTED: 'tutorial_started',
  TUTORIAL_STEP: 'tutorial_step',
  TUTORIAL_COMPLETED: 'tutorial_completed',
  TUTORIAL_SKIPPED: 'tutorial_skipped',
  ONBOARDING_COMPLETED: 'onboarding_completed',

  // Retention events
  DAILY_LOGIN: 'daily_login',
  STREAK_CONTINUED: 'streak_continued',
  STREAK_BROKEN: 'streak_broken',
  DAILY_REWARD_CLAIMED: 'daily_reward_claimed',
  DAILY_QUEST_STARTED: 'daily_quest_started',
  DAILY_QUEST_COMPLETED: 'daily_quest_completed',

  // System events
  ERROR: 'error',
  CRASH: 'crash',
  PERFORMANCE_WARNING: 'performance_warning',
} as const;

export type EventName = (typeof EVENT_NAMES)[keyof typeof EVENT_NAMES];

// ============================================================================
// Event Properties
// ============================================================================

/**
 * Base properties for all events
 */
export interface BaseEventProperties {
  [key: string]: unknown;
}

/**
 * Session event properties
 */
export interface SessionEventProperties extends BaseEventProperties {
  sessionDuration?: number; // in seconds
  platform?: string;
  appVersion?: string;
  deviceModel?: string;
}

/**
 * Purchase event properties
 */
export interface PurchaseEventProperties extends BaseEventProperties {
  itemId: string;
  price: number;
  currency: string;
  transactionId?: string;
  productName?: string;
  category?: string;
}

/**
 * Gameplay event properties
 */
export interface GameplayEventProperties extends BaseEventProperties {
  characterAge?: number;
  gameTime?: string;
  activityType?: string;
  locationId?: string;
  locationName?: string;
  outcome?: string;
}

/**
 * Social event properties
 */
export interface SocialEventProperties extends BaseEventProperties {
  npcId?: string;
  npcName?: string;
  relationshipType?: string;
  affinityLevel?: number;
  messageType?: string;
}

/**
 * Progression event properties
 */
export interface ProgressionEventProperties extends BaseEventProperties {
  level?: number;
  category?: string;
  achievementKey?: string;
  questId?: string;
  milestoneId?: string;
  jobId?: string;
  jobTitle?: string;
  educationLevel?: string;
  amount?: number;
}

/**
 * Tutorial event properties
 */
export interface TutorialEventProperties extends BaseEventProperties {
  stepName?: string;
  stepIndex?: number;
  completed?: boolean;
  timeSpent?: number; // in seconds
}

/**
 * Retention event properties
 */
export interface RetentionEventProperties extends BaseEventProperties {
  streakDays?: number;
  rewardDay?: number;
  rewardType?: string;
  rewardAmount?: number;
  questType?: string;
  questProgress?: number;
}

/**
 * System event properties
 */
export interface SystemEventProperties extends BaseEventProperties {
  errorType?: string;
  errorMessage?: string;
  stackTrace?: string;
  metric?: string;
  value?: number;
}

/**
 * Union of all event property types
 */
export type EventProperties =
  | BaseEventProperties
  | SessionEventProperties
  | PurchaseEventProperties
  | GameplayEventProperties
  | SocialEventProperties
  | ProgressionEventProperties
  | TutorialEventProperties
  | RetentionEventProperties
  | SystemEventProperties;

// ============================================================================
// Analytics Event Structure
// ============================================================================

/**
 * Complete analytics event structure
 */
export interface AnalyticsEvent {
  id: string;
  playerId: string;
  sessionId: string | null;
  eventName: EventName | string;
  category: EventCategory;
  properties: EventProperties | null;
  timestamp: number; // Unix timestamp in seconds
  createdAt?: Date;
}

/**
 * Session tracking structure
 */
export interface AnalyticsSession {
  sessionId: string;
  playerId: string;
  startedAt: number; // Unix timestamp
  endedAt: number | null;
  durationSeconds: number | null;
  eventsCount: number;
  platform?: string;
  appVersion?: string;
}

// ============================================================================
// Event Batching
// ============================================================================

/**
 * Batch of events for efficient storage
 */
export interface EventBatch {
  events: AnalyticsEvent[];
  createdAt: number;
  flushedAt: number | null;
}

/**
 * Event buffer configuration
 */
export interface EventBufferConfig {
  maxSize: number; // Max events before auto-flush
  flushIntervalMs: number; // Auto-flush interval in ms
  retryAttempts: number; // Number of retry attempts on failure
}

export const DEFAULT_BUFFER_CONFIG: EventBufferConfig = {
  maxSize: 100,
  flushIntervalMs: 30_000, // 30 seconds
  retryAttempts: 3,
};

// ============================================================================
// Event Categories Mapping
// ============================================================================

/**
 * Map event names to their categories
 */
export function getEventCategory(eventName: EventName | string): EventCategory {
  if (eventName.startsWith('session_')) return 'session';
  if (eventName.startsWith('purchase_')) return 'purchase';
  if (eventName.startsWith('game_') || eventName.startsWith('character_') ||
      eventName.startsWith('activity_') || eventName === 'age_up') return 'gameplay';
  if (eventName.startsWith('conversation_') || eventName.startsWith('relationship_') ||
      eventName.startsWith('friend_') || eventName.startsWith('dating_') ||
      eventName === 'marriage' || eventName === 'child_born') return 'social';
  if (eventName.startsWith('level_') || eventName.startsWith('achievement_') ||
      eventName.startsWith('quest_') || eventName.startsWith('milestone_') ||
      eventName.startsWith('job_') || eventName.startsWith('education_') ||
      eventName.startsWith('money_')) return 'progression';
  if (eventName.startsWith('tutorial_') || eventName === 'onboarding_completed') return 'tutorial';
  if (eventName.startsWith('daily_') || eventName.startsWith('streak_')) return 'retention';
  return 'system';
}

// ============================================================================
// Validation
// ============================================================================

/**
 * Validate an event has required fields
 */
export function validateEvent(event: Partial<AnalyticsEvent>): event is AnalyticsEvent {
  return !!(
    event.id &&
    event.playerId &&
    event.eventName &&
    event.timestamp
  );
}

/**
 * Check if an event name is a known standard event
 */
export function isKnownEvent(eventName: string): eventName is EventName {
  return Object.values(EVENT_NAMES).includes(eventName as EventName);
}
