import type { PageViewRepository } from '@core/analytics/application/repositories/PageViewRepository';
import type { EngagementRepository } from '@core/analytics/domain/repositories/EngagementRepository';
import type { Logger } from '@core/shared/domain/Logger';
import { Provider } from '@nestjs/common';

import {
    ANALYTICS_ENGAGEMENT_REPOSITORY_TOKEN,
    ANALYTICS_PAGE_VIEW_REPOSITORY_TOKEN,
} from '../../../../persistence/analytics/AnalyticsPersistenceTokens';

const LOGGER_TOKEN = 'Logger';

import { GetAnalyticsMetricsUseCase } from '@core/analytics/application/use-cases/GetAnalyticsMetricsUseCase';
import { GetDashboardDataUseCase } from '@core/analytics/application/use-cases/GetDashboardDataUseCase';
import { RecordEngagementUseCase } from '@core/analytics/application/use-cases/RecordEngagementUseCase';
import { RecordPageViewUseCase } from '@core/analytics/application/use-cases/RecordPageViewUseCase';
import { AnalyticsService } from './AnalyticsService';
import { GetAnalyticsMetricsPresenter } from './presenters/GetAnalyticsMetricsPresenter';
import { GetDashboardDataPresenter } from './presenters/GetDashboardDataPresenter';
import { RecordEngagementPresenter } from './presenters/RecordEngagementPresenter';
import { RecordPageViewPresenter } from './presenters/RecordPageViewPresenter';

export const AnalyticsProviders: Provider[] = [
  AnalyticsService,
  RecordPageViewPresenter,
  RecordEngagementPresenter,
  GetDashboardDataPresenter,
  GetAnalyticsMetricsPresenter,
  {
    provide: RecordPageViewUseCase,
    useFactory: (repo: PageViewRepository, logger: Logger) =>
      new RecordPageViewUseCase(repo, logger),
    inject: [ANALYTICS_PAGE_VIEW_REPOSITORY_TOKEN, LOGGER_TOKEN],
  },
  {
    provide: RecordEngagementUseCase,
    useFactory: (repo: EngagementRepository, logger: Logger) =>
      new RecordEngagementUseCase(repo, logger),
    inject: [ANALYTICS_ENGAGEMENT_REPOSITORY_TOKEN, LOGGER_TOKEN],
  },
  {
    provide: GetDashboardDataUseCase,
    useFactory: (logger: Logger) =>
      new GetDashboardDataUseCase(logger),
    inject: [LOGGER_TOKEN],
  },
  {
    provide: GetAnalyticsMetricsUseCase,
    useFactory: (logger: Logger, repo: PageViewRepository) =>
      new GetAnalyticsMetricsUseCase(logger, repo),
    inject: [LOGGER_TOKEN, ANALYTICS_PAGE_VIEW_REPOSITORY_TOKEN],
  },
];