/**
 * Copyright
 * All right reserved.
 * 项目名称:运维系统
 * 创建日期:2022/5/22
 */
package org.springblade.modules.map.task;


import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.extern.slf4j.Slf4j;
import org.springblade.constant.BusinessConstant;
import org.springblade.core.oss.model.BladeFile;
import org.springblade.modules.etl.entity.EtlAdCdEntity;
import org.springblade.modules.etl.service.IEtlAdCdService;
import org.springblade.modules.map.entity.MapRegionEntity;
import org.springblade.modules.map.entity.MapRegionImportRecordEntity;
import org.springblade.modules.map.entity.MapRegionPointEntity;
import org.springblade.modules.map.service.*;

import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;

/***
 * Date:2022/5/22
 * Title: 河道水位抽取
 * Description：
 * @author swp
 * @version 1.0
 * Remark：认为有必要的其他信息
 */
@Slf4j
public class MapRegionImportTask implements Callable<Integer> {

	private BladeFile bladeFile;
	private MapRegionImportRecordEntity recordEntity;
	private IMapRegionService regionService;
	private IMapRegionPointService regionPointService;
	private IMapRegionImportService regionImportService;
	private IEtlAdCdService etlAdCdService;
	private int adType;


	public MapRegionImportTask(BladeFile bladeFile, int adType, MapRegionImportRecordEntity recordEntity, IEtlAdCdService etlAdCdService, IMapRegionService regionService, IMapRegionPointService regionPointService, IMapRegionImportService regionImportService) {
		this.bladeFile = bladeFile;
		this.adType = adType;
		this.recordEntity = recordEntity;
		this.regionService = regionService;
		this.regionPointService = regionPointService;
		this.regionImportService = regionImportService;
		this.etlAdCdService = etlAdCdService;
	}

	@Override
	public Integer call() {
		try {
			log.info("行政区导入任务开始执行*********************");
			URL url = new URL(bladeFile.getLink());
			HttpURLConnection conn = (HttpURLConnection) url.openConnection();
			//设置超时间为3秒
			conn.setConnectTimeout(3 * 1000);
			//防止屏蔽程序抓取而返回403错误
			conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
			//得到输入流
			InputStream inputStream = conn.getInputStream();
			String fileName = bladeFile.getOriginalName();
			if (!fileName.endsWith("geojson")) {
				recordEntity.setImportStatus(2L);
				regionImportService.saveOrUpdate(recordEntity);
				return 0;
			}

			JSONObject jsonObject = JSONObject.parseObject(inputStream, JSONObject.class);
			JSONArray featureList = jsonObject.getJSONArray("features");
			for (int j = 0; j < featureList.size(); j++) {
				MapRegionEntity entity = new MapRegionEntity();
				JSONObject feature = featureList.getJSONObject(j);
				JSONObject properties = feature.getJSONObject("properties");

				if (1 == adType) {
					String name = properties.getString("NAME");
					entity.setAdnm(name);
					entity.setAdcd(BusinessConstant.REGION_NM_ADCODE);
				} else if (2 == adType) {
					String name = properties.getString("NAME");
					entity.setAdnm(name);
					String adcd = properties.getString("ADCD").trim();
					StringBuilder builder = new StringBuilder();
					builder.append(adcd);
					for (int i = 0; i < BusinessConstant.REGION_NM_ADCODE.length() - adcd.length(); i++) {
						builder.append("0");
					}
					entity.setAdcd(builder.toString());

					entity.setParentAdcd(BusinessConstant.REGION_NM_ADCODE);

					//"LGTD": 111.49816505946669, "LTTD": 40.590490284924819

					double lng = properties.getDouble("LGTD");
					double lat = properties.getDouble("LTTD");

					entity.setCenterPointLat(lat);
					entity.setCenterPointLng(lng);

				} else if (3 == adType) {
					String name = properties.getString("NAME");
					entity.setAdnm(name);

					String adcd = properties.getString("ADCD").trim();
					StringBuilder builder = new StringBuilder();
					builder.append(adcd);
					for (int i = 0; i < BusinessConstant.REGION_NM_ADCODE.length() - adcd.length(); i++) {
						builder.append("0");
					}
					entity.setAdcd(builder.toString());

					EtlAdCdEntity dto = new EtlAdCdEntity();
					dto.setAdcd(entity.getAdcd());
					List<EtlAdCdEntity> etlAdCdEntityList = etlAdCdService.selectList(dto);
					if (null != etlAdCdEntityList && etlAdCdEntityList.size()>0){
						entity.setParentAdcd(etlAdCdEntityList.get(0).getSuperioradcd());
					}

					double lng = properties.getDouble("LGTD");
					double lat = properties.getDouble("LTTD");

					entity.setCenterPointLat(lat);
					entity.setCenterPointLng(lng);

				} else if (4 == adType) {
					String adcd = properties.getString("vi_code").trim();
					StringBuilder builder = new StringBuilder();
					builder.append(adcd);
					for (int i = 0; i < BusinessConstant.REGION_NM_ADCODE.length() - adcd.length(); i++) {
						builder.append("0");
					}
					entity.setAdcd(builder.toString());

					String name = properties.getString("vi_name");
					entity.setAdnm(name);


					adcd = properties.getString("adnm_code").trim();
					builder.setLength(0);
					builder.append(adcd);
					for (int i = 0; i < BusinessConstant.REGION_NM_ADCODE.length() - adcd.length(); i++) {
						builder.append("0");
					}
					entity.setDistrictAdcd(builder.toString());

					name = properties.getString("adnm");
					entity.setDistrictAdnm(name);

					adcd = properties.getString("city_code").trim();
					builder.setLength(0);
					builder.append(adcd);
					for (int i = 0; i < BusinessConstant.REGION_NM_ADCODE.length() - adcd.length(); i++) {
						builder.append("0");
					}
					entity.setCityAdcd(builder.toString());

					name = properties.getString("city_name");
					entity.setCityAdnm(name);

					EtlAdCdEntity dto = new EtlAdCdEntity();
					dto.setAdcd(entity.getAdcd());
					List<EtlAdCdEntity> etlAdCdEntityList = etlAdCdService.selectList(dto);
					if (null != etlAdCdEntityList && etlAdCdEntityList.size()>0){
						entity.setParentAdcd(etlAdCdEntityList.get(0).getSuperioradcd());
					}

				}

				JSONObject geometry = feature.getJSONObject("geometry");
				JSONArray coordinates = geometry.getJSONArray("coordinates");
				JSONArray locationList = coordinates.getJSONArray(0).getJSONArray(0);
				List<MapRegionPointEntity> pointEntityList = new ArrayList<>();
				for (int i = 0; i < locationList.size(); i++) {
					JSONArray location = locationList.getJSONArray(i);
					MapRegionPointEntity pointEntity = new MapRegionPointEntity();
					pointEntity.setPointLng(location.getDoubleValue(0));
					pointEntity.setPointLat(location.getDoubleValue(1));
					pointEntityList.add(pointEntity);
				}

				if (adType == 1 || adType == 4) {
					MapRegionPointEntity centerPoint = getCenterPoint(pointEntityList);
					entity.setCenterPointLat(centerPoint.getPointLat());
					entity.setCenterPointLng(centerPoint.getPointLng());
				}
				LambdaQueryWrapper<MapRegionEntity> wrapper = Wrappers.<MapRegionEntity>query().lambda();
				wrapper.eq(MapRegionEntity::getAdcd, entity.getAdcd());
				MapRegionEntity regionEntity = regionService.getOne(wrapper);
				if (null == regionEntity) {
					regionEntity = new MapRegionEntity();
				}
				regionEntity.setAdcd(entity.getAdcd());
				regionEntity.setAdnm(entity.getAdnm());
				regionEntity.setCenterPointLng(entity.getCenterPointLng());
				regionEntity.setCenterPointLat(entity.getCenterPointLat());
				regionEntity.setCityAdcd(entity.getCityAdcd());
				regionEntity.setCityAdnm(entity.getCityAdnm());
				regionEntity.setDistrictAdcd(entity.getDistrictAdcd());
				regionEntity.setDistrictAdnm(entity.getDistrictAdnm());
				regionEntity.setParentAdcd(entity.getParentAdcd());

				if (regionService.saveOrUpdate(regionEntity)) {
					for (MapRegionPointEntity pointEntity : pointEntityList) {
						pointEntity.setRegionId(regionEntity.getId());

					}

					regionPointService.saveBatch(pointEntityList);
				}
			}


			recordEntity.setImportStatus(1L);
			regionImportService.saveOrUpdate(recordEntity);
		} catch (Exception e) {
			e.printStackTrace();
			log.error("导入任务异常 {}", e.getMessage());
			try {
				recordEntity.setImportStatus(2L);
				regionImportService.saveOrUpdate(recordEntity);
			} catch (Exception e1) {
				e1.printStackTrace();
			}
		}
		return 0;
	}


	private MapRegionPointEntity getCenterPoint(List<MapRegionPointEntity> pointEntityList) {
		int total = pointEntityList.size();
		double X = 0.0;
		double Y = 0.0;
		double Z = 0.0;
		for (MapRegionPointEntity pointEntity : pointEntityList) {
			double lat = pointEntity.getPointLat() * Math.PI / 180.0;
			double lon = pointEntity.getPointLng() * Math.PI / 180.0;
			X += Math.cos(lat) * Math.cos(lon);
			Y += Math.cos(lat) * Math.sin(lon);
			Z += Math.sin(lat);
		}

		X = X / total;
		Y = Y / total;
		Z = Z / total;
		double lon2 = Math.atan2(Y, X);
		double hyp = Math.sqrt(X * X + Y * Y);
		double lat2 = Math.atan2(Z, hyp);
		MapRegionPointEntity centerPoint = new MapRegionPointEntity();

		centerPoint.setPointLng(lon2 * 180 / Math.PI);
		centerPoint.setPointLat(lat2 * 180 / Math.PI);

		return centerPoint;
	}
}
