package com.mvrent.carrental.service;

import com.mvrent.carrental.model.AuditLog;
import com.mvrent.carrental.repository.AuditLogRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.PageRequest;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.util.List;

/**
 * Builds audit entries from the current security context / request and hands
 * them to {@link AuditWriter} to persist in an independent transaction.
 */
@Service
@RequiredArgsConstructor
public class AuditService {

    private final AuditLogRepository auditLogRepository;
    private final AuditWriter auditWriter;

    public List<AuditLog> recent(int limit) {
        return auditLogRepository.findAllByOrderByCreatedAtDesc(PageRequest.of(0, limit));
    }

    /** Log an action performed by the currently authenticated principal. */
    public void log(String action, String entityType, String entityId, String detail) {
        Authentication auth = SecurityContextHolder.getContext().getAuthentication();
        String username = (auth != null && auth.isAuthenticated()) ? auth.getName() : "system";
        String role = (auth != null && auth.getAuthorities() != null)
                ? auth.getAuthorities().stream().map(Object::toString)
                    .filter(a -> a.startsWith("ROLE_")).findFirst().map(a -> a.substring(5)).orElse(null)
                : null;
        auditWriter.write(AuditLog.builder()
                .username(username).role(role).action(action)
                .entityType(entityType).entityId(entityId)
                .detail(detail).ip(currentIp())
                .build());
    }

    /** Log an authentication event with an explicit username. */
    public void logAuth(String action, String username) {
        auditWriter.write(AuditLog.builder()
                .username(username).action(action).entityType("Auth").ip(currentIp())
                .build());
    }

    private static String currentIp() {
        try {
            var attrs = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            if (attrs == null) return null;
            var req = attrs.getRequest();
            String fwd = req.getHeader("X-Forwarded-For");
            return (fwd != null && !fwd.isBlank()) ? fwd.split(",")[0].trim() : req.getRemoteAddr();
        } catch (Exception ex) {
            return null;
        }
    }
}
