package com.iqser.red.service.persistence.service.v1.api.shared.model.annotations;

import java.time.OffsetDateTime;
import java.util.List;
import java.util.stream.Collectors;

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.ManualChange;
import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.ManualRedactionType;
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.entitymapped.BaseAnnotation;
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.entitymapped.IdRemoval;
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.entitymapped.ManualForceRedaction;
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.entitymapped.ManualLegalBasisChange;
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.entitymapped.ManualRecategorization;
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.entitymapped.ManualRedactionEntry;
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.entitymapped.ManualResizeRedaction;

import lombok.experimental.UtilityClass;

@UtilityClass
public class ManualChangeFactory {

    public List<ManualChange> toLocalManualChangeList(List<BaseAnnotation> manualChanges, boolean markAsProcessed, int processedAnalysisNumber) {

        return manualChanges.stream()
                .map(manualChange -> toLocalManualChange(manualChange, processedAnalysisNumber))
                .peek(manualChange -> {
                    if (markAsProcessed) {
                        manualChange.setProcessedDate(OffsetDateTime.now());
                    }
                })
                .collect(Collectors.toList());
    }


    public ManualChange toLocalManualChange(BaseAnnotation baseAnnotation, int processedAnalysisNumber) {

        if (!baseAnnotation.isLocal()) {
            throw new IllegalArgumentException(String.format("Manual change %s is not a local manual change", baseAnnotation));
        }

        ManualChange manualChange = ManualChange.from(baseAnnotation, processedAnalysisNumber);
        if (baseAnnotation instanceof ManualRecategorization recategorization) {
            manualChange.withManualRedactionType(ManualRedactionType.RECATEGORIZE)
                    .withChange("type", recategorization.getType())
                    .withChange("section", recategorization.getSection())
                    .withChange("legalBasis", recategorization.getLegalBasis())
                    .withChange("value", recategorization.getValue());
        } else if (baseAnnotation instanceof IdRemoval) {
            manualChange.withManualRedactionType(ManualRedactionType.REMOVE);
        } else if (baseAnnotation instanceof ManualForceRedaction manualForceRedaction) {
            manualChange.withManualRedactionType(ManualRedactionType.FORCE).withChange("legalBasis", manualForceRedaction.getLegalBasis());
        } else if (baseAnnotation instanceof ManualResizeRedaction manualResizeRedact) {
            manualChange.withManualRedactionType(ManualRedactionType.RESIZE).withChange("value", manualResizeRedact.getValue());
        } else if (baseAnnotation instanceof ManualRedactionEntry manualRedactionEntry) {
            manualChange.withManualRedactionType(ManualRedactionType.ADD).withChange("value", manualRedactionEntry.getValue());
        } else if (baseAnnotation instanceof ManualLegalBasisChange manualLegalBasisChange) {
            manualChange.withManualRedactionType(ManualRedactionType.LEGAL_BASIS_CHANGE)
                    .withChange("section", manualLegalBasisChange.getSection())
                    .withChange("value", manualLegalBasisChange.getValue())
                    .withChange("legalBasis", manualLegalBasisChange.getLegalBasis());
        }
        return manualChange;
    }

}