package com.iqser.red.service.peristence.v1.server.integration.tests;

import static org.assertj.core.api.Assertions.assertThat;

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

import org.assertj.core.util.Lists;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;

import com.iqser.red.service.peristence.v1.server.integration.client.DossierAttributeClient;
import com.iqser.red.service.peristence.v1.server.integration.client.DossierAttributeConfigClient;
import com.iqser.red.service.peristence.v1.server.integration.service.DossierTesterAndProvider;
import com.iqser.red.service.peristence.v1.server.integration.utils.AbstractPersistenceServerServiceTest;
import com.iqser.red.service.persistence.service.v1.api.shared.model.DossierAttributes;
import com.iqser.red.service.persistence.service.v1.api.shared.model.DossierAttributesConfig;
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.DossierAttributeConfig;
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.SneakyThrows;

public class DossierAttributeTest extends AbstractPersistenceServerServiceTest {

    @Autowired
    private DossierTesterAndProvider dossierTesterAndProvider;

    @Autowired
    private DossierAttributeConfigClient dossierAttributeConfigClient;

    @Autowired
    private DossierAttributeClient dossierAttributeClient;


    @SneakyThrows
    @Test
    public void testDossierAttributes() {

        var dossier = dossierTesterAndProvider.provideTestDossier();

        var loadedAttributes = dossierAttributeConfigClient.getDossierAttributesConfig(dossier.getDossierTemplateId());
        assertThat(loadedAttributes.getDossierAttributeConfigs()).isEmpty();

        DossierAttributeConfig attribute = new DossierAttributeConfig();
        attribute.setLabel("test");
        attribute.setEditable(true);
        attribute.setType(DossierAttributeType.TEXT);

        dossierAttributeConfigClient.addOrUpdateDossierAttributeConfig(dossier.getDossierTemplateId(), attribute);
        loadedAttributes = dossierAttributeConfigClient.getDossierAttributesConfig(dossier.getDossierTemplateId());
        assertThat(loadedAttributes.getDossierAttributeConfigs()).isNotEmpty();

        dossierAttributeConfigClient.setDossierAttributesConfig(dossier.getDossierTemplateId(), new DossierAttributesConfig());
        loadedAttributes = dossierAttributeConfigClient.getDossierAttributesConfig(dossier.getDossierTemplateId());
        assertThat(loadedAttributes.getDossierAttributeConfigs()).isEmpty();

        dossierAttributeConfigClient.setDossierAttributesConfig(dossier.getDossierTemplateId(), new DossierAttributesConfig(List.of(attribute)));
        loadedAttributes = dossierAttributeConfigClient.getDossierAttributesConfig(dossier.getDossierTemplateId());
        assertThat(loadedAttributes.getDossierAttributeConfigs()).isNotEmpty();

        dossierAttributeConfigClient.deleteDossierAttributesConfig(dossier.getDossierTemplateId(),
                loadedAttributes.getDossierAttributeConfigs().stream().map(DossierAttributeConfig::getId).collect(Collectors.toList()));
        dossierAttributeConfigClient.setDossierAttributesConfig(dossier.getDossierTemplateId(), new DossierAttributesConfig(List.of(attribute)));
        loadedAttributes = dossierAttributeConfigClient.getDossierAttributesConfig(dossier.getDossierTemplateId());
        assertThat(loadedAttributes.getDossierAttributeConfigs()).isNotEmpty();

        var configId = loadedAttributes.getDossierAttributeConfigs().iterator().next().getId();

        List<DossierAttribute> dossierAttributes = new ArrayList<>();
        dossierAttributes.add(DossierAttribute.builder().dossierAttributeConfigId(configId).dossierId(dossier.getId()).value("lorem ipsum").build());
        dossierAttributeClient.setDossierAttributes(dossier.getId(), new DossierAttributes(dossierAttributes));

        var loadedAttributeValues = dossierAttributeClient.getDossierAttributes(dossier.getId());
        assertThat(loadedAttributeValues.getDossierAttributeList()).isNotEmpty();

        var firstAttribute = loadedAttributeValues.getDossierAttributeList().iterator().next();
        assertThat(firstAttribute.getValue()).isEqualTo("lorem ipsum");

        firstAttribute.setValue("  ");
        dossierAttributeClient.addOrUpdateDossierAttribute(dossier.getId(), firstAttribute);

        loadedAttributeValues = dossierAttributeClient.getDossierAttributes(dossier.getId());
        assertThat(loadedAttributeValues.getDossierAttributeList()).isNotEmpty();
        firstAttribute = loadedAttributeValues.getDossierAttributeList().iterator().next();
        assertThat(firstAttribute.getValue()).isNull();

        firstAttribute.setValue(null);
        dossierAttributeClient.addOrUpdateDossierAttribute(dossier.getId(), firstAttribute);

        loadedAttributeValues = dossierAttributeClient.getDossierAttributes(dossier.getId());
        assertThat(loadedAttributeValues.getDossierAttributeList()).isNotEmpty();
        firstAttribute = loadedAttributeValues.getDossierAttributeList().iterator().next();
        assertThat(firstAttribute.getValue()).isNull();

        dossierAttributeClient.deleteDossierAttribute(dossier.getId(), firstAttribute.getDossierAttributeConfigId());
        loadedAttributeValues = dossierAttributeClient.getDossierAttributes(dossier.getId());
        assertThat(loadedAttributeValues.getDossierAttributeList()).isEmpty();

        dossierAttributeClient.setDossierAttributes(dossier.getId(), new DossierAttributes(dossierAttributes));
        loadedAttributeValues = dossierAttributeClient.getDossierAttributes(dossier.getId());
        assertThat(loadedAttributeValues.getDossierAttributeList()).isNotEmpty();

        //delete the list of dossier attribute config with child
        dossierAttributeConfigClient.deleteDossierAttributesConfig(dossier.getDossierTemplateId(),
                Lists.newArrayList(loadedAttributes.getDossierAttributeConfigs().iterator().next().getId()));
        loadedAttributes = dossierAttributeConfigClient.getDossierAttributesConfig(dossier.getDossierTemplateId());
        assertThat(loadedAttributes.getDossierAttributeConfigs()).isEmpty();
        loadedAttributeValues = dossierAttributeClient.getDossierAttributes(dossier.getId());
        assertThat(loadedAttributeValues.getDossierAttributeList()).isEmpty();

    }

}
