package com.flightticket.service;

import com.flightticket.model.entity.AuditLog;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 * Service for managing audit logs
 * Requirements: 12.1, 12.2, 12.3, 12.4, 12.6
 */
public interface AuditLogService {
    
    /**
     * Create an audit log entry
     * @param userId User performing the action
     * @param agencyId Agency associated with the action
     * @param action Action being performed
     * @param entityType Type of entity being acted upon
     * @param entityId ID of the entity
     * @param details Additional details as key-value pairs
     * @param ipAddress IP address of the request
     * @param userAgent User agent string
     * @return Created audit log
     */
    AuditLog createAuditLog(
        UUID userId,
        UUID agencyId,
        String action,
        String entityType,
        String entityId,
        Map<String, Object> details,
        String ipAddress,
        String userAgent
    );
    
    /**
     * Log authentication attempt
     * Requirements: 12.1
     * @param username Username attempting authentication
     * @param success Whether authentication was successful
     * @param ipAddress IP address of the request
     * @param userAgent User agent string
     * @param failureReason Reason for failure (if applicable)
     */
    void logAuthenticationAttempt(
        String username,
        boolean success,
        String ipAddress,
        String userAgent,
        String failureReason
    );
    
    /**
     * Log Amadeus API call
     * Requirements: 12.2
     * @param userId User making the API call
     * @param agencyId Agency associated with the call
     * @param endpoint Amadeus API endpoint
     * @param requestParams Request parameters
     * @param responseStatus HTTP response status
     * @param executionTimeMs Execution time in milliseconds
     * @param success Whether the call was successful
     * @param errorMessage Error message (if applicable)
     */
    void logAmadeusApiCall(
        UUID userId,
        UUID agencyId,
        String endpoint,
        Map<String, Object> requestParams,
        int responseStatus,
        long executionTimeMs,
        boolean success,
        String errorMessage
    );
    
    /**
     * Log wallet transaction
     * Requirements: 12.3
     * @param userId User performing the transaction
     * @param agencyId Agency owning the wallet
     * @param transactionId Transaction ID
     * @param transactionType Type of transaction
     * @param amount Transaction amount
     * @param balanceBefore Balance before transaction
     * @param balanceAfter Balance after transaction
     * @param reference Transaction reference
     */
    void logWalletTransaction(
        UUID userId,
        UUID agencyId,
        UUID transactionId,
        String transactionType,
        String amount,
        String balanceBefore,
        String balanceAfter,
        String reference
    );
    
    /**
     * Log administrative action
     * Requirements: 12.4
     * @param userId User performing the action
     * @param agencyId Agency associated with the action (if applicable)
     * @param action Action being performed
     * @param entityType Type of entity being acted upon
     * @param entityId ID of the entity
     * @param details Additional details
     * @param ipAddress IP address of the request
     * @param userAgent User agent string
     */
    void logAdministrativeAction(
        UUID userId,
        UUID agencyId,
        String action,
        String entityType,
        String entityId,
        Map<String, Object> details,
        String ipAddress,
        String userAgent
    );
    
    /**
     * Search audit logs with filters
     * Requirements: 12.6
     * @param userId Filter by user ID (optional)
     * @param agencyId Filter by agency ID (optional)
     * @param action Filter by action (optional)
     * @param entityType Filter by entity type (optional)
     * @param startDate Start date for date range filter (optional)
     * @param endDate End date for date range filter (optional)
     * @return List of matching audit logs
     */
    List<AuditLog> searchAuditLogs(
        UUID userId,
        UUID agencyId,
        String action,
        String entityType,
        LocalDateTime startDate,
        LocalDateTime endDate
    );
    
    /**
     * Get audit logs for a specific user
     * @param userId User ID
     * @return List of audit logs for the user
     */
    List<AuditLog> getAuditLogsByUser(UUID userId);
    
    /**
     * Get audit logs for a specific agency
     * @param agencyId Agency ID
     * @return List of audit logs for the agency
     */
    List<AuditLog> getAuditLogsByAgency(UUID agencyId);
    
    /**
     * Get audit logs for a specific entity
     * @param entityType Entity type
     * @param entityId Entity ID
     * @return List of audit logs for the entity
     */
    List<AuditLog> getAuditLogsByEntity(String entityType, String entityId);
    
    /**
     * Get audit logs within a date range
     * @param startDate Start date
     * @param endDate End date
     * @return List of audit logs within the date range
     */
    List<AuditLog> getAuditLogsByDateRange(LocalDateTime startDate, LocalDateTime endDate);
    
    /**
     * Log modification attempt
     * Requirements: 8.1
     * @param agentId Agent performing the modification
     * @param agencyId Agency associated with the modification
     * @param modificationType Type of modification being attempted
     * @param bookingId Booking being modified
     * @param ipAddress IP address of the request
     * @param userAgent User agent string
     */
    void logModificationAttempt(
        UUID agentId,
        UUID agencyId,
        String modificationType,
        String bookingId,
        String ipAddress,
        String userAgent
    );
    
    /**
     * Log successful modification
     * Requirements: 8.2
     * @param agentId Agent who performed the modification
     * @param agencyId Agency associated with the modification
     * @param modificationId ID of the modification record
     * @param bookingId Booking that was modified
     * @param modificationType Type of modification
     * @param beforeState State before modification (as JSON)
     * @param afterState State after modification (as JSON)
     * @param cost Cost of the modification
     * @param ipAddress IP address of the request
     * @param userAgent User agent string
     */
    void logModificationSuccess(
        UUID agentId,
        UUID agencyId,
        String modificationId,
        String bookingId,
        String modificationType,
        Map<String, Object> beforeState,
        Map<String, Object> afterState,
        String cost,
        String ipAddress,
        String userAgent
    );
    
    /**
     * Log failed modification
     * Requirements: 8.4
     * @param agentId Agent who attempted the modification
     * @param agencyId Agency associated with the modification
     * @param modificationId ID of the modification record (if created)
     * @param bookingId Booking that was being modified
     * @param modificationType Type of modification
     * @param failureReason Reason for failure
     * @param errorDetails Additional error details
     * @param ipAddress IP address of the request
     * @param userAgent User agent string
     */
    void logModificationFailure(
        UUID agentId,
        UUID agencyId,
        String modificationId,
        String bookingId,
        String modificationType,
        String failureReason,
        Map<String, Object> errorDetails,
        String ipAddress,
        String userAgent
    );
    
    /**
     * Query modification history for a booking
     * Requirements: 8.5
     * @param bookingId Booking ID
     * @return List of modification audit logs ordered by timestamp DESC (most recent first)
     */
    List<AuditLog> queryModificationHistory(String bookingId);
}
