import { Injectable } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import axios from 'axios';
import { ZOOM_ENV_KEYS, ZOOM_DEFAULTS } from 'src/common/constants/zoom.constants';
import { ZoomOAuthService } from './zoom-oauth.service';

/**
 * Small shared HTTP helper for the new Zoom analytics API clients
 * (ZoomReportApiClient, ZoomDashboardApiClient). Reuses the existing,
 * module-internal ZoomOAuthService for token fetch/cache/invalidate — this is
 * the one place the "attach bearer token, retry once on 401" logic is
 * written, so it isn't duplicated across both new client files. Does not
 * touch ZoomApiService — that class's own request/retry logic is untouched.
 */
@Injectable()
export class ZoomAnalyticsHttpUtil {
  constructor(
    private readonly oauthService: ZoomOAuthService,
    private readonly configService: ConfigService,
  ) {}

  async get<T>(path: string, params?: Record<string, unknown>): Promise<T> {
    const token = await this.oauthService.getAccessToken();
    try {
      return await this.execute<T>(path, params, token);
    } catch (error: any) {
      if (error?.response?.status === 401) {
        this.oauthService.invalidate();
        const refreshed = await this.oauthService.getAccessToken();
        return await this.execute<T>(path, params, refreshed);
      }
      throw error;
    }
  }

  private async execute<T>(path: string, params: Record<string, unknown> | undefined, token: string): Promise<T> {
    const baseUrl = this.configService.get<string>(ZOOM_ENV_KEYS.BASE_URL) ?? ZOOM_DEFAULTS.BASE_URL;
    const response = await axios.get<T>(`${baseUrl}${path}`, {
      headers: { Authorization: `Bearer ${token}` },
      params,
    });
    return response.data;
  }
}
