import { Injectable, Logger } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';

export enum AnalyticsEvent {
  // User lifecycle
  USER_REGISTERED = 'user_registered',
  USER_LOGIN = 'user_login',
  USER_LOGOUT = 'user_logout',
  USER_ONBOARDING_COMPLETED = 'user_onboarding_completed',

  // Family management
  FAMILY_CREATED = 'family_created',
  FAMILY_MEMBER_INVITED = 'family_member_invited',
  FAMILY_MEMBER_JOINED = 'family_member_joined',

  // Child management
  CHILD_ADDED = 'child_added',
  CHILD_UPDATED = 'child_updated',
  CHILD_REMOVED = 'child_removed',

  // Activity tracking
  ACTIVITY_LOGGED = 'activity_logged',
  ACTIVITY_EDITED = 'activity_edited',
  ACTIVITY_DELETED = 'activity_deleted',
  VOICE_INPUT_USED = 'voice_input_used',

  // AI assistant
  AI_CHAT_STARTED = 'ai_chat_started',
  AI_MESSAGE_SENT = 'ai_message_sent',
  AI_CONVERSATION_DELETED = 'ai_conversation_deleted',

  // Analytics and insights
  INSIGHTS_VIEWED = 'insights_viewed',
  REPORT_GENERATED = 'report_generated',
  REPORT_EXPORTED = 'report_exported',
  PATTERN_DISCOVERED = 'pattern_discovered',

  // Premium features
  PREMIUM_TRIAL_STARTED = 'premium_trial_started',
  PREMIUM_SUBSCRIBED = 'premium_subscribed',
  PREMIUM_CANCELLED = 'premium_cancelled',

  // Engagement
  NOTIFICATION_RECEIVED = 'notification_received',
  NOTIFICATION_CLICKED = 'notification_clicked',
  SHARE_INITIATED = 'share_initiated',
  FEEDBACK_SUBMITTED = 'feedback_submitted',
  FEATURE_UPVOTED = 'feature_upvoted',

  // Errors and issues
  ERROR_OCCURRED = 'error_occurred',
  API_ERROR = 'api_error',
  OFFLINE_MODE_ACTIVATED = 'offline_mode_activated',
  SYNC_FAILED = 'sync_failed',
}

export interface AnalyticsEventData {
  event: AnalyticsEvent;
  userId?: string;
  familyId?: string;
  timestamp?: Date;
  properties?: Record<string, any>;
  metadata?: {
    platform?: 'web' | 'ios' | 'android';
    appVersion?: string;
    deviceType?: string;
    sessionId?: string;
  };
}

export interface UserProperties {
  userId: string;
  email?: string;
  name?: string;
  role?: string;
  familySize?: number;
  childrenCount?: number;
  isPremium?: boolean;
  signupDate?: Date;
  lastActiveDate?: Date;
  locale?: string;
}

@Injectable()
export class AnalyticsService {
  private readonly logger = new Logger(AnalyticsService.name);
  private analyticsEnabled: boolean;
  private analyticsProvider: 'posthog' | 'matomo' | 'mixpanel' | 'none';
  private apiKey: string;

  constructor(private configService: ConfigService) {
    this.analyticsEnabled =
      this.configService.get('ANALYTICS_ENABLED', 'true') === 'true';
    this.analyticsProvider = this.configService.get(
      'ANALYTICS_PROVIDER',
      'posthog',
    ) as any;
    this.apiKey = this.configService.get('ANALYTICS_API_KEY', '');

    if (this.analyticsEnabled && !this.apiKey) {
      this.logger.warn(
        'Analytics enabled but no API key configured. Events will be logged only.',
      );
    }
  }

  /**
   * Track an event
   */
  async trackEvent(eventData: AnalyticsEventData): Promise<void> {
    if (!this.analyticsEnabled) {
      return;
    }

    try {
      // Log event locally for debugging
      this.logger.debug(
        `Analytics Event: ${eventData.event}`,
        JSON.stringify(eventData, null, 2),
      );

      // Send to analytics provider
      switch (this.analyticsProvider) {
        case 'posthog':
          await this.sendToPostHog(eventData);
          break;
        case 'matomo':
          await this.sendToMatomo(eventData);
          break;
        case 'mixpanel':
          await this.sendToMixpanel(eventData);
          break;
        default:
          this.logger.debug('No analytics provider configured, logging only');
      }
    } catch (error) {
      this.logger.error(
        `Failed to track event: ${eventData.event}`,
        error.stack,
      );
      // Don't throw - analytics failures should not break app functionality
    }
  }

  /**
   * Identify a user (set user properties)
   */
  async identifyUser(userProperties: UserProperties): Promise<void> {
    if (!this.analyticsEnabled) {
      return;
    }

    try {
      this.logger.debug(
        `Identifying user: ${userProperties.userId}`,
        JSON.stringify(userProperties, null, 2),
      );

      switch (this.analyticsProvider) {
        case 'posthog':
          await this.identifyPostHogUser(userProperties);
          break;
        case 'matomo':
          await this.identifyMatomoUser(userProperties);
          break;
        case 'mixpanel':
          await this.identifyMixpanelUser(userProperties);
          break;
      }
    } catch (error) {
      this.logger.error('Failed to identify user', error.stack);
    }
  }

  /**
   * Track page view (for web analytics)
   */
  async trackPageView(
    userId: string,
    path: string,
    properties?: Record<string, any>,
  ): Promise<void> {
    await this.trackEvent({
      event: 'page_viewed' as any,
      userId,
      timestamp: new Date(),
      properties: {
        path,
        ...properties,
      },
    });
  }

  /**
   * Track feature usage for product analytics
   */
  async trackFeatureUsage(
    userId: string,
    featureName: string,
    properties?: Record<string, any>,
  ): Promise<void> {
    await this.trackEvent({
      event: 'feature_used' as any,
      userId,
      timestamp: new Date(),
      properties: {
        featureName,
        ...properties,
      },
    });
  }

  /**
   * Track conversion funnel step
   */
  async trackFunnelStep(
    userId: string,
    funnelName: string,
    step: string,
    stepNumber: number,
    properties?: Record<string, any>,
  ): Promise<void> {
    await this.trackEvent({
      event: 'funnel_step' as any,
      userId,
      timestamp: new Date(),
      properties: {
        funnelName,
        step,
        stepNumber,
        ...properties,
      },
    });
  }

  /**
   * Track user retention metric
   */
  async trackRetention(
    userId: string,
    cohort: string,
    daysSinceSignup: number,
  ): Promise<void> {
    await this.trackEvent({
      event: 'retention_check' as any,
      userId,
      timestamp: new Date(),
      properties: {
        cohort,
        daysSinceSignup,
      },
    });
  }

  // Provider-specific implementations

  private async sendToPostHog(eventData: AnalyticsEventData): Promise<void> {
    if (!this.apiKey) return;

    const { default: fetch } = await import('node-fetch');

    await fetch('https://app.posthog.com/capture/', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        api_key: this.apiKey,
        event: eventData.event,
        properties: {
          distinct_id: eventData.userId,
          ...eventData.properties,
          ...eventData.metadata,
        },
        timestamp: eventData.timestamp.toISOString(),
      }),
    });
  }

  private async identifyPostHogUser(
    userProperties: UserProperties,
  ): Promise<void> {
    if (!this.apiKey) return;

    const { default: fetch } = await import('node-fetch');

    await fetch('https://app.posthog.com/capture/', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        api_key: this.apiKey,
        event: '$identify',
        properties: {
          distinct_id: userProperties.userId,
          $set: userProperties,
        },
      }),
    });
  }

  private async sendToMatomo(eventData: AnalyticsEventData): Promise<void> {
    // Matomo implementation placeholder
    this.logger.debug('Matomo tracking not yet implemented');
  }

  private async identifyMatomoUser(
    userProperties: UserProperties,
  ): Promise<void> {
    this.logger.debug('Matomo user identification not yet implemented');
  }

  private async sendToMixpanel(eventData: AnalyticsEventData): Promise<void> {
    // Mixpanel implementation placeholder
    this.logger.debug('Mixpanel tracking not yet implemented');
  }

  private async identifyMixpanelUser(
    userProperties: UserProperties,
  ): Promise<void> {
    this.logger.debug('Mixpanel user identification not yet implemented');
  }

  /**
   * Get analytics summary for dashboard
   */
  async getAnalyticsSummary(
    startDate: Date,
    endDate: Date,
  ): Promise<{
    totalUsers: number;
    activeUsers: number;
    totalEvents: number;
    topEvents: Array<{ event: string; count: number }>;
  }> {
    // This would typically query your analytics database
    // For now, return placeholder data
    return {
      totalUsers: 0,
      activeUsers: 0,
      totalEvents: 0,
      topEvents: [],
    };
  }
}
