/**
 * 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.core.oss.model.BladeFile;
import org.springblade.modules.map.entity.DangerAreaImportRecordEntity;
import org.springblade.modules.map.entity.DangerAreaEntity;
import org.springblade.modules.map.entity.DangerAreaPointEntity;
import org.springblade.modules.map.service.IDangerAreaImportServcie;
import org.springblade.modules.map.service.IDangerAreaPointService;
import org.springblade.modules.map.service.IDangerAreaService;

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 DangerAreaImportTask implements Callable<Integer> {

	private BladeFile bladeFile;
	private DangerAreaImportRecordEntity recordEntity;
	private IDangerAreaService dangerAreaService;
	private IDangerAreaImportServcie danagerAreaImportServcie;
	private IDangerAreaPointService pointService;


	public DangerAreaImportTask(BladeFile bladeFile, DangerAreaImportRecordEntity recordEntity, IDangerAreaService dangerAreaService, IDangerAreaPointService pointService, IDangerAreaImportServcie danagerAreaImportServcie) {
		this.bladeFile = bladeFile;
		this.recordEntity = recordEntity;
		this.dangerAreaService = dangerAreaService;
		this.danagerAreaImportServcie = danagerAreaImportServcie;
		this.pointService = pointService;
	}

	@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);
				danagerAreaImportServcie.saveOrUpdate(recordEntity);
				return 0;
			}

			JSONObject jsonObject = JSONObject.parseObject(inputStream, JSONObject.class);
			JSONArray featureList = jsonObject.getJSONArray("features");
			for (int j = 0; j < featureList.size(); j++) {
				DangerAreaEntity entity = new DangerAreaEntity();
				JSONObject feature = featureList.getJSONObject(j);
				JSONObject properties = feature.getJSONObject("properties");
				String pid = properties.getString("pid");
				String name = properties.getString("name");
				String adcd = properties.getString("ADCD");
				String stCode = properties.getString("st_code");
				String status = properties.getString("status");
				entity.setDangerAreaPid(pid);
				entity.setDangerAreaName(name);
				entity.setAdcd(adcd);
				entity.setDangerStatus(status);
				if (null != stCode && stCode.length()>0){
					stCode=stCode.replace("、",",");
					entity.setStCode(stCode);
				}

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

				}

				DangerAreaPointEntity centerPoint = getCenterPoint(pointEntityList);
				entity.setCenterPointLat(centerPoint.getPointLat());
				entity.setCenterPointLng(centerPoint.getPointLng());

				LambdaQueryWrapper<DangerAreaEntity> wrapper = Wrappers.<DangerAreaEntity>query().lambda();
				wrapper.eq(DangerAreaEntity::getDangerAreaPid, entity.getDangerAreaPid());
				DangerAreaEntity dangerAreaEntity=dangerAreaService.getOne(wrapper);
				if (null == dangerAreaEntity){
					dangerAreaEntity = new DangerAreaEntity();
					dangerAreaEntity.setDangerAreaPid(entity.getDangerAreaPid());
				}
				dangerAreaEntity.setDangerAreaName(entity.getDangerAreaName());
				dangerAreaEntity.setCenterPointLng(entity.getCenterPointLng());
				dangerAreaEntity.setCenterPointLat(entity.getCenterPointLat());
				dangerAreaEntity.setStCode(entity.getStCode());
				dangerAreaEntity.setAdcd(entity.getAdcd());
				dangerAreaEntity.setDangerStatus(entity.getDangerStatus());

				if (dangerAreaService.saveOrUpdate(dangerAreaEntity)) {
					for (DangerAreaPointEntity pointEntity : pointEntityList) {
						pointEntity.setDangerAreaId(dangerAreaEntity.getId());
						pointService.save(pointEntity);
					}
				}
			}


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


	private DangerAreaPointEntity getCenterPoint(List<DangerAreaPointEntity> pointEntityList) {
		int total = pointEntityList.size();
		double X = 0.0;
		double Y = 0.0;
		double Z = 0.0;
		for (DangerAreaPointEntity 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);
		DangerAreaPointEntity centerPoint = new DangerAreaPointEntity();

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

		return centerPoint;
	}
}
