package com.iqser.red.service.persistence.management.v1.processor.service.queue;

import java.time.OffsetDateTime;
import java.time.temporal.ChronoUnit;

import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Service;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.iqser.red.service.persistence.management.v1.processor.configuration.MessagingConfiguration;
import com.iqser.red.service.persistence.management.v1.processor.service.FileStatusProcessingUpdateService;
import com.iqser.red.service.persistence.management.v1.processor.service.FileStatusService;
import com.iqser.red.service.persistence.management.v1.processor.service.layoutparsing.LayoutParsingRequestIdentifierService;
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.file.FileErrorInfo;
import com.knecon.fforesight.service.layoutparser.internal.api.queue.LayoutParsingFinishedEvent;
import com.knecon.fforesight.service.layoutparser.internal.api.queue.LayoutParsingQueueNames;
import com.knecon.fforesight.service.layoutparser.internal.api.queue.LayoutParsingRequest;

import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@Service
@RequiredArgsConstructor
public class LayoutParsingFinishedMessageReceiver {

    private final FileStatusService fileStatusService;
    private final FileStatusProcessingUpdateService fileStatusProcessingUpdateService;
    private final ObjectMapper objectMapper;
    private final LayoutParsingRequestIdentifierService layoutParsingRequestIdentifierService;


    @SneakyThrows
    @RabbitListener(queues = LayoutParsingQueueNames.LAYOUT_PARSING_FINISHED_EVENT_QUEUE)
    public void receive(LayoutParsingFinishedEvent response) {

        fileStatusService.setStatusAnalyse(layoutParsingRequestIdentifierService.parseDossierId(response.identifier()),
                layoutParsingRequestIdentifierService.parseFileId(response.identifier()),
                layoutParsingRequestIdentifierService.parsePriority(response.identifier()));

        fileStatusService.updateLayoutProcessedTime(layoutParsingRequestIdentifierService.parseFileId(response.identifier()));

        log.info("Received message {} in {}", response, LayoutParsingQueueNames.LAYOUT_PARSING_FINISHED_EVENT_QUEUE);
    }


    @SneakyThrows
    @RabbitListener(queues = LayoutParsingQueueNames.LAYOUT_PARSING_DLQ)
    public void handleDLQMessage(Message failedMessage) {

        var analyzeRequest = objectMapper.readValue(failedMessage.getBody(), LayoutParsingRequest.class);
        log.info("Failed to process analyze request: {}", analyzeRequest);
        String errorCause = failedMessage.getMessageProperties().getHeader(MessagingConfiguration.X_ERROR_INFO_HEADER);
        OffsetDateTime timestamp = failedMessage.getMessageProperties().getHeader(MessagingConfiguration.X_ERROR_INFO_TIMESTAMP_HEADER);
        timestamp = timestamp != null ? timestamp : OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS);
        log.info("Failed to process layout parsing request, errorCause: {}, timestamp: {}", errorCause, timestamp);
        fileStatusProcessingUpdateService.analysisFailed(layoutParsingRequestIdentifierService.parseDossierId(analyzeRequest.identifier()),
                layoutParsingRequestIdentifierService.parseFileId(analyzeRequest.identifier()),
                new FileErrorInfo(errorCause, LayoutParsingQueueNames.LAYOUT_PARSING_DLQ, "layoutparser-service", timestamp));

    }

}
