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

import java.util.Collections;
import java.util.List;
import java.util.Set;

import org.springframework.stereotype.Service;

import com.iqser.red.service.persistence.management.v1.processor.dataexchange.models.FileExchangeImportModel;
import com.iqser.red.service.persistence.management.v1.processor.dataexchange.models.TemplateImportInfo;
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.DossierCreatorService;
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.CreateOrUpdateDossierRequest;
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.Dossier;

import io.micrometer.observation.annotation.Observed;
import lombok.AccessLevel;
import lombok.RequiredArgsConstructor;
import lombok.experimental.FieldDefaults;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@Service
@RequiredArgsConstructor
@FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE)
public class DossierImportService {

    DossierCreatorService dossierCreatorService;
    FileImportService fileImportService;
    EntityTypeImportService entityTypeImportService;


    @Observed(name = "DossierImportService", contextualName = "import-dossier")
    public void importDossier(FileExchangeImportModel fileExchangeImportModel,
                              String userId,
                              Dossier dossierToImport,
                              TemplateImportInfo templateImportInfo,
                              List<String> allReportTemplateIds) {

        String dossierId = getDossierForImport(templateImportInfo, dossierToImport, userId, allReportTemplateIds);

        entityTypeImportService.importEntityTypes(templateImportInfo.getDossierTemplateId(),
                                                  dossierId,
                                                  fileExchangeImportModel.getDossierTypes()
                                                          .get(dossierToImport.getId()));

        List<FileExchangeImportModel.FileImport> files = fileExchangeImportModel.getFiles().getOrDefault(dossierToImport.getId(), Collections.emptyList());

        fileImportService.importFilesInParallel(files, userId, templateImportInfo, dossierId);
    }


    private String getDossierForImport(TemplateImportInfo templateImportInfo, Dossier dossier, String userId, List<String> reportTemplateIds) {

        String dossierTemplateId = templateImportInfo.getDossierTemplateId();

        CreateOrUpdateDossierRequest request = CreateOrUpdateDossierRequest.builder()
                .dossierName(dossier.getName())
                .description(dossier.getDescription())
                .downloadFileTypes(dossier.getDownloadFileTypes())
                .dueDate(dossier.getDueDate())
                .dossierTemplateId(dossierTemplateId)
                .requestingUser(userId)
                .reportTemplateIds(reportTemplateIds)
                .build();

        Dossier importedDossier = null;
        int retries = 0;
        while (importedDossier == null && retries < 100) {
            try {
                importedDossier = dossierCreatorService.addDossier(request, Set.of(userId), Set.of(userId), userId);
            } catch (ConflictException e) {
                retries++;
                request.setDossierName(String.format("%s (%d)", dossier.getName(), retries));
            }
        }
        if (importedDossier == null) {
            throw new BadRequestException(String.format("Could not create dossier with name %s in %d retries", dossier.getName(), retries));
        }
        return importedDossier.getId();
    }

}
