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

import java.util.Locale;
import java.util.Map;

import org.springframework.stereotype.Service;

import com.iqser.red.service.persistence.management.v1.processor.entity.configuration.LegalBasisEntity;
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.LegalBasisMappingRepository;

import jakarta.transaction.Transactional;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

@Service
@Transactional
@RequiredArgsConstructor
@Slf4j
public class LegalBasisMigrationService {

    private static final Map<String, String> technicalNameMapping = Map.ofEntries(Map.entry("Article 39(e)(3) of Regulation (EC) No 178/2002",
                                                                                            "personal_data_geolocation_article_39e3"),
                                                                                  Map.entry("Article 39(e)(2) of Regulation (EC) No 178/2002",
                                                                                            "vertebrate_study_personal_data_geolocation_article_39e2"),
                                                                                  Map.entry(
                                                                                          "Article 63(2)(a) of Regulation (EC) No 1107/2009 (making reference to Article 39 of Regulation EC No 178/2002)",
                                                                                          "manufacturing_production_process"),
                                                                                  Map.entry(
                                                                                          "Article 63(2)(a) of Regulation (EC) No 1107/2009 (making reference to Article 39 of Regulation EC No  178/2002)",
                                                                                          "links_producer_applicant"),
                                                                                  Map.entry(
                                                                                          "Article 63(2)(a) of Regulation (EC) No​1107/2009 (making reference to Article 39 of Regulation EC No 178/2002)",
                                                                                          "links_producer_applicant"),
                                                                                  Map.entry(
                                                                                          "Article 63(2)(a) of Regulation (EC) No 1107/2009  (making reference to Article 39 of Regulation EC No 178/2002)",
                                                                                          "commercial_information"),
                                                                                  Map.entry(
                                                                                          "Article 63(2)(a) of Regulation (EC) No 1107/2009​‌‌​ (making reference to Article 39 of Regulation EC No 178/2002)",
                                                                                          "commercial_information"),
                                                                                  Map.entry(
                                                                                          "Article 63(2)(a) of Regulation (EC) No  1107/2009 (making reference to Article 39 of Regulation EC No 178/2002)",
                                                                                          "quantitative_composition"),
                                                                                  Map.entry(
                                                                                          "Article 63(2)(a) of Regulation (EC) No ​‌‌​ 1107/2009 ​‌‌​ (making reference to Article 39 of Regulation EC No 178/2002)",
                                                                                          "quantitative_composition"),
                                                                                  Map.entry("Article 63(2)(b) of Regulation (EC) No 1107/2009", "specification_impurity"),
                                                                                  Map.entry("Article 63(2)(c) of Regulation (EC) No 1107/2009", "results_production_batches"),
                                                                                  Map.entry("Article 63(2)(d) of Regulation (EC) No 1107/2009",
                                                                                            "composition_plant_protection_product"),
                                                                                  Map.entry("Reg (EC) No 1107/2009 Art. 63 (2a)", "method_manufacture"),
                                                                                  Map.entry("Reg (EC) No 1107/2009 Art. 63 (2b)", "specification_impurity_active_substance"),
                                                                                  Map.entry("Reg (EC) No 1107/2009 Art. 63 (2c)", "results_production_batches"),
                                                                                  Map.entry("Reg (EC) No 1107/2009 Art. 63 (2d)", "methods_analysis_impurities"),
                                                                                  Map.entry("Reg (EC) No 1107/2009 Art. 63 (2e)", "links_producer_applicant"),
                                                                                  Map.entry("Reg (EC) No 1107/2009 Art. 63 (2f)", "composition_plant_protection_product"),
                                                                                  Map.entry("Reg (EC) No 1107/2009 Art. 63 (2g)", "names_addresses_persons"),
                                                                                  Map.entry("Article 4(1)(b), Regulation (EC) No 1049/2001 (Personal data)",
                                                                                            "personal_data_geolocation"),
                                                                                  Map.entry("Article 4(2), first indent, Regulation (EC) No 1049/2001 (commercial interest)",
                                                                                            "proprietary_information"),
                                                                                  Map.entry("N/A", "n_a"),
                                                                                  Map.entry("n-a.", "n-a."));

    private final LegalBasisMappingRepository legalBasisMappingRepository;


    public void migrate() {

        log.info("Starting migration: Adding technical names to legal basis");

        this.legalBasisMappingRepository.findAll()
                .stream()
                .peek(entry -> entry.getLegalBasis()
                        .forEach(lb -> lb.setTechnicalName(getTechnicalNameOrFallback(lb))))
                .forEach(legalBasisMappingRepository::save);
        log.info("Finishing migration: Adding technical names to legal basis");
    }


    private static String getTechnicalNameOrFallback(LegalBasisEntity legalBasisEntity) {

        return technicalNameMapping.getOrDefault(legalBasisEntity.getReason(), generateNewTechnicalName(legalBasisEntity.getName()));

    }


    private static String generateNewTechnicalName(String name) {

        return name.toLowerCase(Locale.ROOT).replaceAll("\\.", "").replaceAll("\\s+", "_");
    }

}
