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


import de.avatic.lcc.dto.calculation.PremiseDTO;
import de.avatic.lcc.dto.calculation.edit.PremiseDetailDTO;
import de.avatic.lcc.dto.generic.LocationDTO;
import de.avatic.lcc.dto.generic.NodeDTO;
import de.avatic.lcc.dto.generic.NodeType;
import de.avatic.lcc.model.db.premises.Premise;
import de.avatic.lcc.model.db.premises.PremiseListEntry;
import de.avatic.lcc.repositories.MaterialRepository;
import de.avatic.lcc.repositories.NodeRepository;
import de.avatic.lcc.repositories.country.CountryRepository;
import de.avatic.lcc.repositories.premise.DestinationRepository;
import de.avatic.lcc.repositories.users.UserNodeRepository;
import de.avatic.lcc.repositories.users.UserRepository;
import de.avatic.lcc.service.transformer.generic.CountryTransformer;
import de.avatic.lcc.service.transformer.generic.DimensionTransformer;
import de.avatic.lcc.service.transformer.generic.MaterialTransformer;
import de.avatic.lcc.service.transformer.generic.NodeTransformer;
import org.springframework.stereotype.Service;

import java.util.ArrayList;

@Service
public class PremiseTransformer {

    private final MaterialTransformer materialTransformer;
    private final UserRepository userRepository;
    private final CountryRepository countryRepository;
    private final CountryTransformer countryTransformer;
    private final NodeTransformer nodeTransformer;
    private final MaterialRepository materialRepository;
    private final DimensionTransformer dimensionTransformer;
    private final NodeRepository nodeRepository;
    private final UserNodeRepository userNodeRepository;
    private final DestinationRepository destinationRepository;
    private final DestinationTransformer destinationTransformer;

    public PremiseTransformer(MaterialTransformer materialTransformer, UserRepository userRepository, CountryRepository countryRepository, CountryTransformer countryTransformer, NodeTransformer nodeTransformer, MaterialRepository materialRepository, DimensionTransformer dimensionTransformer, NodeRepository nodeRepository, UserNodeRepository userNodeRepository, DestinationRepository destinationRepository, DestinationTransformer destinationTransformer) {
        this.materialTransformer = materialTransformer;
        this.userRepository = userRepository;
        this.countryRepository = countryRepository;
        this.countryTransformer = countryTransformer;
        this.nodeTransformer = nodeTransformer;
        this.materialRepository = materialRepository;
        this.dimensionTransformer = dimensionTransformer;
        this.nodeRepository = nodeRepository;
        this.userNodeRepository = userNodeRepository;
        this.destinationRepository = destinationRepository;
        this.destinationTransformer = destinationTransformer;
    }

    public PremiseDTO toPremiseDTOWithUserInfo(PremiseListEntry entity) {
        var dto = toPremiseDTO(entity);
        dto.setOwner(userRepository.getById(entity.getOwnerId()));
        return dto;
    }

    public PremiseDTO toPremiseDTO(PremiseListEntry entity) {
        NodeDTO node = new NodeDTO();

        ArrayList<NodeType> types = new ArrayList<>();
        if (entity.isSupplierIsDestination()) types.add(NodeType.DESTINATION);
        if (entity.isSupplierIsSource()) types.add(NodeType.SOURCE);
        if (entity.isSupplierIsIntermediate()) types.add(NodeType.INTERMEDIATE);

        node.setUserNode(entity.isUserSupplier());
        node.setName(entity.getSupplierName());
        node.setId(entity.getSupplierId());
        node.setName(entity.getSupplierName());
        node.setCountry(countryTransformer.toCountryDTO(countryRepository.getById(entity.getSupplierCountryId()).orElseThrow()));
        node.setAddress(entity.getSupplierAddress());
        node.setLocation(new LocationDTO(entity.getSupplierGeoLatitude().doubleValue(), entity.getSupplierGeoLongitude().doubleValue()));
        node.setTypes(types);
        node.setDeprecated(entity.getDeprecated());

        PremiseDTO dto = new PremiseDTO();

        dto.setId(entity.getId());
        dto.setState(entity.getState());
        dto.setMaterial(materialTransformer.toMaterialDTO(entity.getMaterial()));
        dto.setOwner(null);

        dto.setSupplier(node);

        return dto;
    }

    public PremiseDetailDTO toPremiseDetailDTO(Premise entity) {
        var dto = new PremiseDetailDTO();

        dto.setId(entity.getId());
        dto.setMaterial(materialTransformer.toMaterialDTO(materialRepository.getByIdIncludeDeprecated(entity.getMaterialId()).orElseThrow()));
        dto.setMixable(entity.getHuMixable());
        dto.setStackable(entity.getHuStackable());


        dto.setDimension(dimensionTransformer.toDimensionDTO(entity));

        if (entity.getSupplierNodeId() != null)
            dto.setSupplier(nodeRepository.getById(entity.getSupplierNodeId()).map(nodeTransformer::toNodeDTO).orElseThrow());

        if (entity.getUserSupplierNodeId() != null) {
            dto.setSupplier(userNodeRepository.getById(entity.getUserSupplierNodeId()).map(nodeTransformer::toUserNodeDTO).orElseThrow());
            dto.getSupplier().setUserNode(true);
        }

        dto.setDestinations(destinationRepository.getByPremiseId(entity.getId()).stream().map(destinationTransformer::toDestinationDTO).toList());

        dto.setHsCode(entity.getHsCode());
        dto.setTariffRate(entity.getTariffRate() == null ? null : entity.getTariffRate().doubleValue());
        dto.setTariffUnlocked(entity.getTariffUnlocked());

        dto.setFcaEnabled(entity.getFcaEnabled());
        dto.setOverseaShare(entity.getOverseaShare() == null ? null : entity.getOverseaShare().doubleValue());
        dto.setMaterialCost(entity.getMaterialCost() == null ? null : entity.getMaterialCost().doubleValue());


        return dto;

    }
}
