package com.flightticket.aspect;

import com.flightticket.metrics.BusinessMetricsService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

/**
 * AOP aspect for automatic metrics recording.
 * Intercepts service methods to record business metrics.
 * Validates: Requirement 13.6
 */
@Slf4j
@Aspect
@Component
@RequiredArgsConstructor
public class MetricsLoggingAspect {

    private final BusinessMetricsService metricsService;

    /**
     * Records metrics for flight search operations
     */
    @Around("execution(* com.flightticket.service.FlightService.searchFlights(..))")
    public Object recordFlightSearchMetrics(ProceedingJoinPoint joinPoint) throws Throwable {
        long startTime = System.currentTimeMillis();
        try {
            Object result = joinPoint.proceed();
            long duration = System.currentTimeMillis() - startTime;
            metricsService.recordFlightSearchDuration(duration);
            return result;
        } catch (Exception e) {
            long duration = System.currentTimeMillis() - startTime;
            metricsService.recordFlightSearchDuration(duration);
            throw e;
        }
    }

    /**
     * Records metrics for booking creation operations
     */
    @Around("execution(* com.flightticket.service.BookingService.createBooking(..))")
    public Object recordBookingMetrics(ProceedingJoinPoint joinPoint) throws Throwable {
        long startTime = System.currentTimeMillis();
        try {
            Object result = joinPoint.proceed();
            long duration = System.currentTimeMillis() - startTime;
            metricsService.recordBookingCreationDuration(duration);
            return result;
        } catch (Exception e) {
            long duration = System.currentTimeMillis() - startTime;
            metricsService.recordBookingCreationDuration(duration);
            throw e;
        }
    }

    /**
     * Records metrics for ticket issuance operations
     */
    @Around("execution(* com.flightticket.service.TicketingService.issueTicket(..))")
    public Object recordTicketIssuanceMetrics(ProceedingJoinPoint joinPoint) throws Throwable {
        long startTime = System.currentTimeMillis();
        try {
            Object result = joinPoint.proceed();
            long duration = System.currentTimeMillis() - startTime;
            metricsService.recordTicketIssuanceDuration(duration);
            return result;
        } catch (Exception e) {
            long duration = System.currentTimeMillis() - startTime;
            metricsService.recordTicketIssuanceDuration(duration);
            throw e;
        }
    }
}
