/**
 * @TrackAnalytics Decorator - Method-level analytics tracking
 *
 * Use this decorator to track specific controller methods with custom events.
 */

import { SetMetadata } from '@nestjs/common';

export const TRACK_ANALYTICS_KEY = 'track_analytics';

export interface TrackAnalyticsOptions {
  /**
   * Event name (e.g., 'user_signup', 'order_placed')
   */
  event: string;

  /**
   * Event category for grouping
   */
  category?: string;

  /**
   * Static metadata to include with every event
   */
  metadata?: Record<string, unknown>;

  /**
   * Extract dynamic metadata from request/response
   * Return value is merged with static metadata
   */
  extractMetadata?: (context: {
    request: any;
    response: any;
    result: any;
  }) => Record<string, unknown>;
}

/**
 * Decorator to track analytics on a specific endpoint.
 *
 * @example
 * ```ts
 * @Post('signup')
 * @TrackAnalytics({
 *   event: 'user_signup',
 *   category: 'auth',
 *   extractMetadata: ({ result }) => ({
 *     userId: result.id,
 *     plan: result.plan,
 *   }),
 * })
 * async signup(@Body() dto: SignupDto) {
 *   return this.authService.signup(dto);
 * }
 * ```
 */
export const TrackAnalytics = (options: TrackAnalyticsOptions) =>
  SetMetadata(TRACK_ANALYTICS_KEY, options);

/**
 * Example decorated controller:
 *
 * ```ts
 * @Controller('orders')
 * export class OrderController {
 *   @Post()
 *   @TrackAnalytics({
 *     event: 'order_placed',
 *     category: 'commerce',
 *     extractMetadata: ({ request, result }) => ({
 *       orderId: result.id,
 *       total: result.total,
 *       itemCount: result.items.length,
 *       userId: request.user?.id,
 *     }),
 *   })
 *   async createOrder(@Body() dto: CreateOrderDto, @Request() req) {
 *     return this.orderService.create(dto, req.user);
 *   }
 *
 *   @Delete(':id')
 *   @TrackAnalytics({
 *     event: 'order_cancelled',
 *     category: 'commerce',
 *     extractMetadata: ({ request }) => ({
 *       orderId: request.params.id,
 *       userId: request.user?.id,
 *     }),
 *   })
 *   async cancelOrder(@Param('id') id: string, @Request() req) {
 *     return this.orderService.cancel(id, req.user);
 *   }
 * }
 * ```
 */
