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

import de.avatic.lcc.dto.calculation.RouteDTO;
import de.avatic.lcc.dto.generic.TransportType;
import de.avatic.lcc.model.db.premises.route.RouteNode;
import de.avatic.lcc.model.db.premises.route.RouteSection;
import de.avatic.lcc.repositories.premise.RouteNodeRepository;
import de.avatic.lcc.repositories.premise.RouteSectionRepository;
import de.avatic.lcc.service.transformer.generic.NodeTransformer;
import org.springframework.stereotype.Service;
import de.avatic.lcc.model.db.premises.route.Route;

import java.util.ArrayList;
import java.util.List;

@Service
public class RouteTransformer {

    private final RouteSectionRepository routeSectionRepository;
    private final RouteNodeRepository routeNodeRepository;
    private final NodeTransformer nodeTransformer;

    public RouteTransformer(RouteSectionRepository routeSectionRepository, RouteNodeRepository routeNodeRepository, NodeTransformer nodeTransformer) {
        this.routeSectionRepository = routeSectionRepository;
        this.routeNodeRepository = routeNodeRepository;
        this.nodeTransformer = nodeTransformer;
    }

    public RouteDTO toRouteDTO(Route entity) {
        var dto = new RouteDTO();

        dto.setId(entity.getId());

        dto.setCheapest(entity.getCheapest());
        dto.setFastest(entity.getFastest());
        dto.setSelected(entity.getSelected());

        List<RouteSection> sections = routeSectionRepository.getByRouteId(entity.getId());

        dto.setTransitNodes(getRouteNodes(sections).stream().map(nodeTransformer::toNodeDTO).toList());

        var mainRun = sections.stream().filter(RouteSection::getMainRun).findFirst().orElse(null);
        dto.setType(mainRun == null ? TransportType.ROAD : mainRun.getTransportType());

        return dto;
    }

    private List<RouteNode> getRouteNodes(List<RouteSection>  sections) {
        List<RouteNode> nodes = new ArrayList<>();

        nodes.add(routeNodeRepository.getById(sections.getFirst().getFromRouteNodeId()).orElseThrow());

        for (RouteSection section : sections) {
            nodes.add(routeNodeRepository.getById(section.getToRouteNodeId()).orElseThrow());
        }

        return nodes;
    }


}
