package com.cameleer.server.core.admin;

import jakarta.servlet.http.HttpServletRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;

import java.util.Map;

public class AuditService {
    private static final Logger log = LoggerFactory.getLogger(AuditService.class);
    private final AuditRepository repository;

    public AuditService(AuditRepository repository) {
        this.repository = repository;
    }

    /** Log an action using the current SecurityContext for username */
    public void log(String action, AuditCategory category, String target,
                    Map<String, Object> detail, AuditResult result,
                    HttpServletRequest request) {
        String username = extractUsername();
        log(username, action, category, target, detail, result, request);
    }

    /** Log an action with explicit username (for pre-auth contexts like login) */
    public void log(String username, String action, AuditCategory category, String target,
                    Map<String, Object> detail, AuditResult result,
                    HttpServletRequest request) {
        String ip = request != null ? request.getRemoteAddr() : null;
        String userAgent = request != null ? request.getHeader("User-Agent") : null;
        AuditRecord auditRecord = AuditRecord.create(username, action, category, target, detail, result, ip, userAgent);

        repository.insert(auditRecord);

        if (request != null) {
            request.setAttribute("audit.logged", true);
        }

        log.info("AUDIT: user={} action={} category={} target={} result={}",
                username, action, category, target, result);
    }

    private String extractUsername() {
        Authentication auth = SecurityContextHolder.getContext().getAuthentication();
        if (auth != null && auth.getName() != null) {
            String name = auth.getName();
            return name.startsWith("user:") ? name.substring(5) : name;
        }
        return "unknown";
    }
}
