import { Module, DynamicModule, Provider, Global, type Type } from '@nestjs/common';
import { AnalyticsService } from './services';
import { AnalyticsInterceptor } from './interceptors';
import type { CollectorConfig, BatchConfig } from './types';

export const ANALYTICS_OPTIONS = 'ANALYTICS_OPTIONS';

export interface AnalyticsModuleOptions {
  /** Collector service configuration */
  collector: CollectorConfig;
  /** Batching configuration */
  batch?: BatchConfig;
  /** Whether to enable tracking globally */
  enabled?: boolean;
  /** Whether to log events to console (development) */
  debug?: boolean;
}

export interface AnalyticsModuleAsyncOptions {
  imports?: Type<unknown>[];
  useFactory: (...args: unknown[]) => Promise<AnalyticsModuleOptions> | AnalyticsModuleOptions;
  inject?: (Type<unknown> | string | symbol)[];
}

@Global()
@Module({})
export class AnalyticsModule {
  static forRoot(options: AnalyticsModuleOptions): DynamicModule {
    const optionsProvider: Provider = {
      provide: ANALYTICS_OPTIONS,
      useValue: options,
    };

    return {
      module: AnalyticsModule,
      providers: [optionsProvider, AnalyticsService, AnalyticsInterceptor],
      exports: [AnalyticsService, AnalyticsInterceptor],
    };
  }

  static forRootAsync(options: AnalyticsModuleAsyncOptions): DynamicModule {
    const optionsProvider: Provider = {
      provide: ANALYTICS_OPTIONS,
      useFactory: options.useFactory,
      inject: options.inject || [],
    };

    return {
      module: AnalyticsModule,
      imports: options.imports || [],
      providers: [optionsProvider, AnalyticsService, AnalyticsInterceptor],
      exports: [AnalyticsService, AnalyticsInterceptor],
    };
  }
}
