package com.progetto.VEBS.service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.io.ParseException;
import org.locationtech.jts.io.WKTReader;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.rest.webmvc.ResourceNotFoundException;
import org.springframework.stereotype.Service;

import com.progetto.VEBS.mapper.PoligonoComuneMapper;
import com.progetto.VEBS.model.dto.PoligonoComuneDTO;
import com.progetto.VEBS.model.entity.PoligonoComune;
import com.progetto.VEBS.model.repository.AreaBluRepository;
import com.progetto.VEBS.model.repository.AreaVerdeRepository;
import com.progetto.VEBS.model.repository.IngressoRepository;
import com.progetto.VEBS.model.repository.PoligonoAreaVerdeRepository;
import com.progetto.VEBS.model.repository.PoligonoComuneRepository;
import com.progetto.VEBS.model.repository.PoligonoPopolazioneRepository;

@Service
public class PoligonoComuneService {

		@Autowired
		private PoligonoComuneMapper mapper;
		
		@Autowired
		private PoligonoComuneRepository poligonoComuneRepository;
		
		@Autowired
		private AreaVerdeRepository areaVerdeRepository;
		
		@Autowired
		private AreaBluRepository areaBluRepository;
		
		@Autowired
		private IngressoRepository ingressoRepository;
		
		@Autowired
		private PoligonoPopolazioneRepository poligonoPopolazioneRepository;

		public List<PoligonoComuneDTO> getAllPoligoniComuni() {
		    return poligonoComuneRepository.findAll().stream()
		        .map(mapper::toDTO)
		        .collect(Collectors.toList());
		}

		public PoligonoComuneDTO getPoligonoComuneById(Integer id) {
		    return poligonoComuneRepository.findById(id).map(mapper::toDTO)
		            .orElse(null);
		}

		public void savePoligono(PoligonoComuneDTO poligono_comune) {
			poligonoComuneRepository.save(mapper.toEntity(poligono_comune));			
		}

		public void deletePoligonoComuneById(Integer id) throws ResourceNotFoundException {
			poligonoComuneRepository.findById(id).orElseThrow(() -> new ResourceNotFoundException("Record non trovato")); 
			poligonoComuneRepository.deleteById(id);
		}

		public void updatePoligonoComune(PoligonoComuneDTO poligono_comune_dto) throws ResourceNotFoundException {
			PoligonoComune poligono = poligonoComuneRepository.findById(poligono_comune_dto.getId()).orElseThrow(() -> new ResourceNotFoundException("Record non trovato")); 
			
			WKTReader reader = new WKTReader();
			Geometry geom;
			try {
				geom = reader.read(poligono_comune_dto.getGeometria());
				poligono.setGeometria(geom);
			} catch (ParseException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			poligono.setId(poligono_comune_dto.getId());
			poligono.setId(poligono_comune_dto.getId());
			poligono.setCodice_procom(poligono_comune_dto.getCodice_procom());
			poligono.setCodice_procom_t(poligono_comune_dto.getCodice_procom_t());
			poligono.setCodice_regione(poligono_comune_dto.getCodice_regione());
			poligono.setComune(poligono_comune_dto.getComune());
			poligono.setPerimetro(poligono_comune_dto.getPerimetro());
			poligono.setArea(poligono_comune_dto.getArea());

			poligonoComuneRepository.saveAndFlush(poligono);
		}
		
		public List<Map<String,Object>> getComuneFromGeometry(String geomWKT) {
			
			List<Object[]> results = poligonoComuneRepository.getNamePolygonComuneFromGeometry(geomWKT);
			
			List<Map<String,Object>> result = new ArrayList(); 
			
			if(results.isEmpty()) {
				return result;
			}
			
			for(Object[] res : results) {
				Map<String,Object> val = new HashMap();
				val.put("comune", res[0]);
				result.add(val);
			}
			
			return result;
		}

		public List<Map<String, Object>> getStatsNumerositaElementi(String name) {
			
			Integer numAreeVerdi = areaVerdeRepository.getNumAreeVerdiFromName(name);
			
			Integer numAreeBlu = areaBluRepository.getNumAreeBluFromName(name);
			
			Integer numIngressi = ingressoRepository.getNumIngressiFromName(name);
			
			Integer numEdificiPop = poligonoPopolazioneRepository.getNumAreeEdificiPopFromName(name);
			
			List<Map<String,Object>> result = new ArrayList(); 
			
			Map<String,Object> map = new HashMap();
			
			map.put("name", name);
			
			List<Map<String,Object>> children = new ArrayList();

			map.clear();

			map.put("id", "Aree Verdi");
			map.put("value", numAreeVerdi);
			
			children.add(map);
			
			map.clear();

			map.put("id", "Aree Blu");
			map.put("value", numAreeBlu);
			
			children.add(map);
			
			map.clear();

			map.put("id", "Ingressi");
			map.put("value", numIngressi);
			
			children.add(map);
			
			map.clear();

			map.put("id", "Edifici");
			map.put("value", numEdificiPop);
			
			children.add(map);
			
			map.clear();
			
			map.put("children", children);
			
			result.add(map);
						
			return result;
		}
}
