package de.avatic.lcc.service.transformer.nodes;

import de.avatic.lcc.dto.configuration.nodes.view.NodeDetailDTO;
import de.avatic.lcc.dto.generic.NodeDTO;
import de.avatic.lcc.dto.generic.NodeType;
import de.avatic.lcc.model.db.nodes.Node;
import de.avatic.lcc.repositories.NodeRepository;
import de.avatic.lcc.repositories.country.CountryRepository;
import de.avatic.lcc.service.transformer.generic.CountryTransformer;
import de.avatic.lcc.service.transformer.generic.LocationTransformer;
import de.avatic.lcc.service.transformer.generic.NodeTransformer;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

@Service
public class NodeDetailTransformer {

    private final CountryTransformer countryTransformer;
    private final CountryRepository countryRepository;
    private final LocationTransformer locationTransformer;
    private final NodeTransformer nodeTransformer;
    private final NodeRepository nodeRepository;

    public NodeDetailTransformer(CountryTransformer countryTransformer, CountryRepository countryRepository, LocationTransformer locationTransformer, NodeTransformer nodeTransformer, NodeRepository nodeRepository) {
        this.countryTransformer = countryTransformer;
        this.countryRepository = countryRepository;
        this.locationTransformer = locationTransformer;
        this.nodeTransformer = nodeTransformer;
        this.nodeRepository = nodeRepository;
    }

    public NodeDetailDTO toNodeDetailDTO(Node node) {
        NodeDetailDTO dto = new NodeDetailDTO();

        var chains = new ArrayList<Map<Integer, NodeDTO>>();

        var foundChains = node.getNodePredecessors();

        for (var chain : foundChains) {
            Map<Integer, NodeDTO> predecessorChain = new HashMap<>();
            for (Integer seq : chain.keySet())
                predecessorChain.put(seq, nodeTransformer.toNodeDTO(nodeRepository.getById(chain.get(seq)).orElseThrow()));
            chains.add(predecessorChain);
        }

        dto.setId(node.getId());
        dto.setDeprecated(node.getDeprecated());
        dto.setCountry(countryTransformer.toCountryDTO(countryRepository.getById(node.getCountryId()).orElseThrow()));
        dto.setName(node.getName());
        dto.setAddress(node.getAddress());
        dto.setLocation(locationTransformer.toLocationDTO(node));
        dto.setTypes(toNodeTypeArrayList(node));
        dto.setPredecessors(chains);
        dto.setOutboundCountries(node.getOutboundCountries().stream().map(id -> countryTransformer.toCountryDTO(countryRepository.getById(id).orElseThrow())).toList());
        dto.setExternalMappingId(node.getExternalMappingId());

        return dto;
    }

    private ArrayList<NodeType> toNodeTypeArrayList(Node entity) {
        ArrayList<NodeType> types = new ArrayList<>();
        if (entity.getDestination()) types.add(NodeType.DESTINATION);
        if (entity.getSource()) types.add(NodeType.SOURCE);
        if (entity.getIntermediate()) types.add(NodeType.INTERMEDIATE);
        return types;
    }

}
