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

import java.time.OffsetDateTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import org.springframework.stereotype.Service;

import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.EntityLog;
import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.EntityLogEntry;
import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.FilteredEntityLogRequest;

import lombok.RequiredArgsConstructor;

@Service
@RequiredArgsConstructor
public class EntityLogService {

    private final FileManagementStorageService fileManagementStorageService;
    private final FileStatusService fileStatusService;


    public EntityLog getEntityLog(String dossierId, String fileId) {

        return getEntityLog(dossierId, fileId, Collections.emptyList());
    }


    public EntityLog getEntityLog(String dossierId, String fileId, List<String> excludedTypes) {

        var fileStatus = fileStatusService.getStatus(fileId);

        EntityLog redactionLog;

        redactionLog = fileManagementStorageService.getEntityLog(dossierId, fileId);

        if (fileStatus.isExcluded()) {
            redactionLog.setEntityLogEntry(new ArrayList<>());
        }

        if (excludedTypes != null) {
            redactionLog.getEntityLogEntry().removeIf(nextEntry -> excludedTypes.contains(nextEntry.getType()));
        }

        return redactionLog;
    }


    public EntityLog getFilteredEntityLog(String dossierId, String fileId, FilteredEntityLogRequest filteredEntityLogRequest) {

        if (filteredEntityLogRequest.getSpecifiedDate() == null) {
            filteredEntityLogRequest.setSpecifiedDate(OffsetDateTime.MIN);
        }

        var entityLog = getEntityLog(dossierId, fileId, filteredEntityLogRequest.getExcludedTypes());
        var entityLogEntry = entityLog.getEntityLogEntry();

        Iterator<EntityLogEntry> it = entityLogEntry.iterator();
        while (it.hasNext()) {
            var redactionLogEntry = it.next();
            boolean isAfterSpecifiedDate = false;
            for (var change : redactionLogEntry.getChanges()) {
                if (change.getDateTime() != null && change.getDateTime().isAfter(filteredEntityLogRequest.getSpecifiedDate())) {
                    isAfterSpecifiedDate = true;
                    break;
                }
            }
            for (var manualChange : redactionLogEntry.getManualChanges()) {
                if (manualChange.getProcessedDate() != null && manualChange.getProcessedDate()
                        .isAfter(filteredEntityLogRequest.getSpecifiedDate()) || manualChange.getRequestedDate() != null && manualChange.getRequestedDate()
                        .isAfter(filteredEntityLogRequest.getSpecifiedDate())) {
                    isAfterSpecifiedDate = true;
                    break;
                }
            }

            if (!isAfterSpecifiedDate) {
                it.remove();
            }

        }

        return entityLog;
    }

}
