package com.iqser.red.service.peristence.v1.server;

import java.lang.reflect.Type;
import java.util.Map;

import org.springframework.core.MethodParameter;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.servlet.mvc.method.annotation.RequestBodyAdvice;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;

import jakarta.servlet.http.HttpServletRequest;
import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@ControllerAdvice
public class GenericRequestBodyAdvice implements RequestBodyAdvice {

    private final ObjectMapper objectMapper = new ObjectMapper();


    @Override
    public boolean supports(@NonNull MethodParameter methodParameter, @NonNull Type targetType, @NonNull Class<? extends HttpMessageConverter<?>> converterType) {

        return true;
    }


    @Override
    public @NonNull HttpInputMessage beforeBodyRead(@NonNull HttpInputMessage inputMessage,
                                                    @NonNull MethodParameter parameter,
                                                    @NonNull Type targetType,
                                                    @NonNull Class<? extends HttpMessageConverter<?>> converterType) {

        return inputMessage;
    }


    @Override
    public @NonNull Object afterBodyRead(@NonNull Object body,
                                         @NonNull HttpInputMessage inputMessage,
                                         @NonNull MethodParameter parameter,
                                         @NonNull Type targetType,
                                         @NonNull Class<? extends HttpMessageConverter<?>> converterType) {

        ServletRequestAttributes attrs = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if (attrs == null) {
            return body;
        }

        HttpServletRequest request = attrs.getRequest();

        try {
            Map<String, Object> bodyMap = objectMapper.convertValue(body, new TypeReference<>() {
            });

            storeFieldIfPresent(bodyMap, "dossierId", request);
            storeFieldIfPresent(bodyMap, "dossierTemplateId", request);
            storeFieldIfPresent(bodyMap, "fileId", request);
        } catch (Exception ignored) {
        }

        return body;
    }


    @Override
    public Object handleEmptyBody(Object body,
                                  @NonNull HttpInputMessage inputMessage,
                                  @NonNull MethodParameter parameter,
                                  @NonNull Type targetType,
                                  @NonNull Class<? extends HttpMessageConverter<?>> converterType) {

        return body;
    }


    private void storeFieldIfPresent(Map<String, Object> bodyMap, String fieldName, HttpServletRequest request) {

        if (bodyMap.containsKey(fieldName)) {
            Object value = bodyMap.get(fieldName);
            if (value != null) {
                request.setAttribute(fieldName, value.toString());
            }
        }
    }

}
