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

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.springframework.stereotype.Service;

import com.iqser.red.service.persistence.management.v1.processor.entity.dossier.DossierAttributeConfigEntity;
import com.iqser.red.service.persistence.management.v1.processor.exception.BadRequestException;
import com.iqser.red.service.persistence.management.v1.processor.exception.ConflictException;
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.DossierAttributeConfigPersistenceService;
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.DossierAttributePersistenceService;
import com.knecon.fforesight.databasetenantcommons.providers.utils.MagicConverter;
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.DossierAttribute;
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.DossierAttributeType;

import lombok.RequiredArgsConstructor;

@Service
@RequiredArgsConstructor
public class DossierAttributesManagementService {

    private final DossierAttributePersistenceService dossierAttributePersistenceService;
    private final DossierAttributeConfigPersistenceService dossierAttributeConfigPersistenceService;
    private final DossierService dossierService;


    public List<DossierAttribute> setDossierAttributes(String dossierId, List<DossierAttribute> dossierAttributes) {

        var dossier = dossierService.getDossierById(dossierId);
        var config = dossierAttributeConfigPersistenceService.getDossierAttributes(dossier.getDossierTemplateId());

        var typeById = config.stream().collect(Collectors.toMap(entry -> entry.getId(), entry -> entry.getType()));
        for (DossierAttribute dossierAttribute : dossierAttributes) {
            validateDossierAttribute(typeById, dossierAttribute);
        }

        dossierAttributePersistenceService.deleteDossierAttribute(dossierId);

        for (DossierAttribute dossierAttribute : dossierAttributes) {
            dossierAttributePersistenceService.insertDossierAttribute(dossierId, dossierAttribute.getDossierAttributeConfigId(), dossierAttribute.getValue());
        }

        return getDossierAttributes(dossierId);
    }


    private void validateDossierAttribute(Map<String, DossierAttributeType> typeById, DossierAttribute dossierAttribute) {

        if (!typeById.containsKey(dossierAttribute.getDossierAttributeConfigId())) {
            throw new ConflictException("Dossier attribute configuration does not exist.");
        }

        DossierAttributeType type = typeById.get(dossierAttribute.getDossierAttributeConfigId());
        if (type.equals(DossierAttributeType.IMAGE) && dossierAttribute.getValue() != null && !(dossierAttribute.getValue()
                .startsWith("data:image/png;base64") || dossierAttribute.getValue().startsWith("data:image/jpg;base64") || dossierAttribute.getValue()
                .startsWith("data:image/jpeg;base64"))) {
            throw new BadRequestException("Only png, jpg and jpeg files are allowed for image dossier attributes");
        }
    }


    public List<DossierAttribute> getDossierAttributes(String dossierId) {

        return MagicConverter.convert(dossierAttributePersistenceService.getDossierAttributes(dossierId), DossierAttribute.class);
    }


    public DossierAttribute addOrUpdateDossierAttribute(String dossierId, DossierAttribute dossierAttribute) {

        var dossier = dossierService.getDossierById(dossierId);
        var dossierAttributes = dossierAttributePersistenceService.getDossierAttributes(dossierId);
        var config = dossierAttributeConfigPersistenceService.getDossierAttributes(dossier.getDossierTemplateId());

        var typeById = config.stream().collect(Collectors.toMap(DossierAttributeConfigEntity::getId, DossierAttributeConfigEntity::getType));
        validateDossierAttribute(typeById, dossierAttribute);

        if (dossierAttributes.stream()
                .anyMatch(d -> d.getId().getDossierId().equals(dossierAttribute.getDossierId()) && d.getId()
                        .getDossierAttributeConfigId()
                        .equals(dossierAttribute.getDossierAttributeConfigId()))) {
            dossierAttributePersistenceService.updateDossierAttribute(dossierId, dossierAttribute.getDossierAttributeConfigId(), dossierAttribute.getValue());
        } else {
            dossierAttributePersistenceService.insertDossierAttribute(dossierId, dossierAttribute.getDossierAttributeConfigId(), dossierAttribute.getValue());
        }

        return MagicConverter.convert(dossierAttributePersistenceService.findOne(dossierId, dossierAttribute.getDossierAttributeConfigId()), DossierAttribute.class);
    }


    public void deleteDossierAttribute(String dossierId, String dossierAttributeId) {

        dossierAttributePersistenceService.deleteDossierAttribute(dossierId, dossierAttributeId);
    }

}

