package com.iqser.red.persistence.service.v2.external.api.impl.mapper;

import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.factory.Mappers;

import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.componentlog.ComponentLog;
import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.componentlog.ComponentLogEntry;
import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.componentlog.ComponentLogEntryValue;
import com.iqser.red.service.persistence.service.v2.api.external.model.Component;
import com.iqser.red.service.persistence.service.v2.api.external.model.ComponentValue;
import com.iqser.red.service.persistence.service.v2.api.external.model.FileComponents;

@Mapper
public interface ComponentMapper {

    ComponentMapper INSTANCE = Mappers.getMapper(ComponentMapper.class);


    @Mapping(target = "entityReferences", source = "componentLogEntityReferences")
    ComponentValue toComponentValue(ComponentLogEntryValue entry);


    @Mapping(target = "componentLogEntityReferences", source = "entityReferences")
    ComponentLogEntryValue toComponentLogEntry(ComponentValue value);


    List<ComponentValue> toComponentValues(List<ComponentLogEntryValue> entries);


    List<ComponentLogEntryValue> toComponentLogEntries(List<ComponentValue> values);

    @Mapping(target = "componentValues", source = "values")
    Component toComponent(ComponentLogEntry entry);


    List<Component> toComponents(List<ComponentLogEntry> entries);

    @Mapping(target = "values", source = "componentValues")
    ComponentLogEntry toComponentLogEntry(Component component);


    default FileComponents toFileComponents(ComponentLog componentLog, String dossierTemplateId, String dossierId, String fileId, String fileName, boolean includeDetails) {

        Map<String, List<String>> basicComponent = new LinkedHashMap<>();
        for (ComponentLogEntry componentLogEntry : componentLog.getComponentLogEntries()) {
            basicComponent.put(componentLogEntry.getName(),
                               componentLogEntry.getValues()
                                       .stream()
                                       .map(ComponentLogEntryValue::getValue)
                                       .toList());
        }

        Map<String, Component> componentsDetails = new LinkedHashMap<>();
        if (includeDetails) {
            for (ComponentLogEntry entry : componentLog.getComponentLogEntries()) {
                componentsDetails.put(entry.getName(), toComponent(entry));
            }
        }

        return FileComponents.builder()
                .dossierTemplateId(dossierTemplateId)
                .dossierId(dossierId)
                .filename(fileName)
                .fileId(fileId)
                .components(basicComponent)
                .componentDetails(componentsDetails)
                .build();
    }

}
