import {
  Controller,
  Post,
  Body,
  HttpCode,
  HttpStatus,
  Logger,
} from '@nestjs/common';
import { ApiTags, ApiOperation, ApiResponse } from '@nestjs/swagger';
import { MetricsService } from '../../infrastructure/metrics.service';
import { WebVitalsBatchDto } from '../dto/web-vitals.dto';

/**
 * Public endpoint for receiving Core Web Vitals from the frontend.
 *
 * No auth required — these are anonymous, best-effort telemetry beacons
 * sent via `navigator.sendBeacon` during page transitions.
 *
 * Rate limiting and abuse protection should be handled at the
 * reverse-proxy / CDN layer.
 */
@ApiTags('web-vitals')
@Controller('web-vitals')
export class WebVitalsController {
  private readonly logger = new Logger(WebVitalsController.name);

  constructor(private readonly metricsService: MetricsService) {}

  @Post()
  @HttpCode(HttpStatus.NO_CONTENT)
  @ApiOperation({ summary: 'Ingest a batch of Core Web Vitals metrics' })
  @ApiResponse({ status: 204, description: 'Metrics accepted' })
  @ApiResponse({ status: 400, description: 'Invalid payload' })
  ingest(@Body() dto: WebVitalsBatchDto): void {
    for (const metric of dto.metrics) {
      try {
        this.metricsService.recordWebVital(
          metric.name,
          metric.value,
          metric.rating,
          this.normalisePage(metric.url),
        );
      } catch (error) {
        this.logger.warn(
          `Failed to record web vital ${metric.name}: ${error}`,
        );
      }
    }
  }

  /**
   * Normalise the raw URL path into a route-level label to keep
   * Prometheus cardinality manageable (e.g. `/vi/listings/abc123` → `/[locale]/listings/[id]`).
   */
  private normalisePage(url: string): string {
    if (!url) return '/';

    return (
      url
        // Strip query string and fragment
        .split('?')[0]!
        .split('#')[0]!
        // Replace locale segment
        .replace(/^\/(vi|en)/, '/[locale]')
        // Replace UUIDs
        .replace(
          /\/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/gi,
          '/[id]',
        )
        // Replace numeric IDs
        .replace(/\/\d+/g, '/[id]')
        // Replace trailing slash
        .replace(/\/$/, '') || '/'
    );
  }
}
