import { Injectable, OnModuleInit } from '@nestjs/common';
import { OnlineTypeEnum } from 'src/common/enum/online-type.enum';
import { ZoomAnalyticsResourceType } from 'src/common/enum/zoom-analytics-resource-type.enum';
import { AppLoggerService } from 'src/common/services/logger.service';
import { ZoomWebinarRepository } from '../repositories/zoom-webinar.repository';
import { ZoomRegistrationRepository } from '../repositories/zoom-registration.repository';
import { ZoomReportApiClient, ZoomAnalyticsSessionReport } from './zoom-report-api.client';
import { ZoomAnalyticsProviderRegistry } from '../registries/zoom-analytics-provider.registry';
import {
  ZoomAnalyticsRosterRepository,
  ZoomAnalyticsRosterEntry,
} from '../repositories/zoom-analytics-roster.repository';
import { ZoomAnalyticsSessionSummaryRepository } from '../repositories/zoom-analytics-session-summary.repository';
import { ZoomAnalyticsAttendeeSummaryRepository } from '../repositories/zoom-analytics-attendee-summary.repository';
import { ZoomAnalyticsLiveEventRepository } from '../repositories/zoom-analytics-live-event.repository';
import { ZoomAnalyticsConfigService } from './zoom-analytics-config.service';
import { OnlineAttendanceService } from 'src/online-attendance/online-attendance.service';
import { ZoomGeneratedRegistrantLinkRepository } from '../repositories/zoom-generated-registrant-link.repository';
import { ZoomLiveEventAnalyticsProviderBase } from './zoom-live-event-analytics-provider.base';

/**
 * Zoom Meeting analytics provider. Meetings have no panelist concept — every
 * meeting registrant gets `isPanelist: false` (see
 * MeetingService.addParticipant) — so the roster here is every REGISTERED
 * registrant on the online session (ZoomAnalyticsRosterRepository.
 * findRegistrantRosterByOnlineSession), not the panelist-filtered query
 * webinars use. Meetings in this deployment always require registration, so
 * every attendee has a registrant record and the same `+reg<registrationId>`
 * email-tagging trick webinars rely on for identity matching still applies.
 * The post-session report comes from `GET /report/meetings/{id}`. All the
 * live-event-log-driven logic (KPIs, attendee table, live status, join/leave
 * recording, self-heal) lives in ZoomLiveEventAnalyticsProviderBase.
 */
@Injectable()
export class ZoomMeetingAnalyticsProvider extends ZoomLiveEventAnalyticsProviderBase implements OnModuleInit {
  readonly key = ZoomAnalyticsResourceType.MEETING;
  protected readonly expectedOnlineType = OnlineTypeEnum.MEETING;

  constructor(
    private readonly registry: ZoomAnalyticsProviderRegistry,
    webinarRepository: ZoomWebinarRepository,
    private readonly reportApiClient: ZoomReportApiClient,
    rosterRepository: ZoomAnalyticsRosterRepository,
    sessionSummaryRepository: ZoomAnalyticsSessionSummaryRepository,
    attendeeSummaryRepository: ZoomAnalyticsAttendeeSummaryRepository,
    liveEventRepository: ZoomAnalyticsLiveEventRepository,
    config: ZoomAnalyticsConfigService,
    logger: AppLoggerService,
    onlineAttendanceService: OnlineAttendanceService,
    registrationRepository: ZoomRegistrationRepository,
    generatedLinkRepository: ZoomGeneratedRegistrantLinkRepository,
  ) {
    super(
      webinarRepository,
      rosterRepository,
      sessionSummaryRepository,
      attendeeSummaryRepository,
      liveEventRepository,
      config,
      logger,
      onlineAttendanceService,
      registrationRepository,
      generatedLinkRepository,
    );
  }

  onModuleInit(): void {
    this.registry.register(this.key, this);
  }

  protected fetchRoster(onlineSessionId: number, rmContactId?: number): Promise<ZoomAnalyticsRosterEntry[]> {
    return rmContactId
      ? this.rosterRepository.findRegistrantRosterByOnlineSession(onlineSessionId, rmContactId)
      : this.rosterRepository.findRegistrantRosterByOnlineSession(onlineSessionId);
  }

  protected fetchReport(extId: string): Promise<ZoomAnalyticsSessionReport | null> {
    return this.reportApiClient.fetchMeetingReport(extId);
  }
}
