package com.saas.shared.dto.mapper;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.saas.admin.dto.response.AuditLogResponse;
import com.saas.shared.audit.entity.AuditLog;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Named;

import java.util.Map;

/**
 * Audit Log Mapper
 * 
 * MapStruct mapper for converting AuditLog entities to AuditLogResponse DTOs.
 * Provides automatic mapping with custom JSON String ↔ Map conversions.
 */
@Mapper(componentModel = "spring")
public interface AuditLogMapper {

    /**
     * Map AuditLog entity to response DTO
     * 
     * Automatically maps fields with same names.
     * Uses @Mapping for fields that require special handling.
     */
    @Mapping(target = "userEmail", source = "userId", qualifiedByName = "getUserEmailFromUserId")
    @Mapping(target = "oldValues", source = "oldValues", qualifiedByName = "stringToMap")
    @Mapping(target = "newValues", source = "newValues", qualifiedByName = "stringToMap")
    AuditLogResponse toResponse(AuditLog auditLog);

    /**
     * Custom mapping to extract user email from userId if needed
     * In a real implementation, this might lookup the user from repository
     */
    @Named("getUserEmailFromUserId")
    default String getUserEmailFromUserId(Long userId) {
        // In production, this would fetch user email from UserRepository
        // For now, return null as we don't have context to UserRepository here
        return null;
    }

    /**
     * Convert JSON String to Map<String, Object>
     * Used for oldValues and newValues fields
     */
    @Named("stringToMap")
    default Map<String, Object> stringToMap(String jsonString) {
        if (jsonString == null || jsonString.trim().isEmpty()) {
            return null;
        }
        try {
            ObjectMapper objectMapper = new ObjectMapper();
            return objectMapper.readValue(jsonString, new TypeReference<Map<String, Object>>() {});
        } catch (Exception e) {
            // Return null if JSON parsing fails
            return null;
        }
    }
}
