package de.avatic.lcc.service.calculation.execution.steps;

import de.avatic.lcc.model.calculation.ChangeRiskFactorCalculationResult;
import de.avatic.lcc.dto.generic.TransportType;
import de.avatic.lcc.model.db.properties.SystemPropertyMappingId;
import de.avatic.lcc.model.db.rates.ContainerRate;
import de.avatic.lcc.repositories.NodeRepository;
import de.avatic.lcc.repositories.properties.PropertyRepository;
import de.avatic.lcc.repositories.rates.ContainerRateRepository;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;

@Service
public class ChangeRiskFactorCalculationService {

    private final PropertyRepository propertyRepository;
    private final ContainerRateRepository containerRateRepository;
    private final NodeRepository nodeRepository;

    public ChangeRiskFactorCalculationService(PropertyRepository propertyRepository, ContainerRateRepository containerRateRepository, NodeRepository nodeRepository) {
        this.propertyRepository = propertyRepository;
        this.containerRateRepository = containerRateRepository;
        this.nodeRepository = nodeRepository;
    }

    public ChangeRiskFactorCalculationResult getChanceRiskFactors(Integer setId, Integer periodId) {
        var rate = findRate(setId, periodId);
        var riskValue = BigDecimal.valueOf(Double.parseDouble(propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.RISK_REF, setId).orElseThrow().getCurrentValue()));
        var chanceValue = BigDecimal.valueOf(Double.parseDouble(propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.CHANCE_REF, setId).orElseThrow().getCurrentValue()));

        var result = new ChangeRiskFactorCalculationResult();
        result.setChanceFactor(chanceValue.divide(rate.getRateFeu(), 2, RoundingMode.HALF_UP));
        result.setRiskFactor(riskValue.divide(rate.getRateFeu(), 2, RoundingMode.HALF_UP));
        return result;
    }

    private ContainerRate findRate(Integer setId, Integer periodId) {
        var startReference = propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.START_REF, setId).orElseThrow().getCurrentValue();
        var endReference = propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.END_REF, setId).orElseThrow().getCurrentValue();

        var startNode = nodeRepository.getByExternalMappingId(startReference).orElseThrow();
        var endNode = nodeRepository.getByExternalMappingId(endReference).orElseThrow();

        return containerRateRepository.findRoute(startNode.getId(), endNode.getId(), periodId, TransportType.SEA).orElseThrow();
    }

}
