import { Controller, Post, Req, Res, HttpCode, HttpStatus } from '@nestjs/common';
import { Request, Response } from 'express';
import { ApiTags, ApiOperation, ApiExcludeEndpoint } from '@nestjs/swagger';
import { ResponseService } from 'src/common/response-handling/response-handler';
import { handleControllerError } from 'src/common/utils/controller-response-handling';
import { ZOOM_ANALYTICS_SWAGGER } from '../constants/zoom-analytics.constants';
import { ZoomAnalyticsWebhookService } from '../services/zoom-analytics-webhook.service';

/**
 * Public, unauthenticated endpoint — Zoom cannot send our bearer tokens, so
 * authenticity comes from HMAC signature verification inside the service
 * instead (see ZoomAnalyticsWebhookSignatureUtil). Reads the raw parsed body
 * via @Req() rather than a @Body()-bound DTO so Nest's global whitelisting
 * ValidationPipe can't strip/reorder fields the signature was computed over.
 */
@ApiTags(ZOOM_ANALYTICS_SWAGGER.TAG)
@Controller('zoom/analytics/webhook')
export class ZoomAnalyticsWebhookController {
  constructor(
    private readonly webhookService: ZoomAnalyticsWebhookService,
    private readonly responseService: ResponseService,
  ) {}

  @Post()
  @HttpCode(HttpStatus.OK)
  @ApiExcludeEndpoint()
  @ApiOperation({ summary: ZOOM_ANALYTICS_SWAGGER.WEBHOOK })
  async receive(@Req() req: Request, @Res() res: Response) {
    try {
      const result = await this.webhookService.process(req.body, req.headers as Record<string, unknown>);
      if (result) {
        // Zoom's URL-validation handshake requires the raw { plainToken, encryptedToken }
        // object at the top level of the response body — the app's standard
        // { statusCode, message, data } envelope breaks Zoom's validation.
        res.status(HttpStatus.OK).json(result);
        return;
      }
      await this.responseService.success(res, 'Zoom analytics webhook processed');
    } catch (error) {
      handleControllerError(res, error);
    }
  }
}
