package com.sqx.map;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.sqx.common.utils.SpringContextUtils;
import com.sqx.modules.common.entity.CommonInfo;
import com.sqx.modules.common.service.CommonInfoService;
import com.sqx.modules.utils.HttpClientUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;

import java.util.HashMap;
import java.util.Map;

//获取各种清空的地图api
@Slf4j
public class CommonMapUtils {

	private static final CommonInfoService commonInfoService = SpringContextUtils.getBean(CommonInfoService.class);

	/**
	 * 地图枚举
	 */
	public enum MapEnum {
		TX/*腾讯地图*/, TDT/*天地图*/, GD/*高德地图*/, DEF/*默认值*/
	}

	/**
	 * 从数据库里获取当前生效的地图接口
	 * @return { @link com.sqx.map.CommonMapUtils.MapEnum }
	 */
	public static MapEnum getMapType(){
		String mapType = commonInfoService.findOne(414).getValue();
		switch (mapType){
			case "1": {
				return MapEnum.TX;
			}
			case "2": {
				return MapEnum.TDT;
			}
			case "3": {
				return MapEnum.GD;
			}
			default: {
				return MapEnum.DEF;
			}
		}
	}

	//一个通用的接口请求器

	/**
	 * 使用Get方式请求数据并转成json对象
	 * @param url URL地址
	 * @param params 参数
	 * @return { @link com.alibaba.fastjson.JSONObject } 对象的map
	 */
	public static JSONObject getHtmlToJson(String url, Map<String, String> params){
		String data = HttpClientUtil.doGet(url, params);
		return JSON.parseObject(data);
	}


	/**
	 * 获取【逆地理编码】接口
	 * @param mapType
	 * @param longitude
	 * @param latitude
	 * @return
	 */
	public static JSONObject getReverseGeocoding(MapEnum mapType, String longitude, String latitude){
		JSONObject result = null;
		switch (mapType){
			case TX: {
				//腾讯地图API
				CommonInfo oneData = commonInfoService.findOne(217);
				String url = "https://apis.map.qq.com/ws/geocoder/v1/";
				Map<String, String> params = new HashMap<>();
				params.put("location", latitude + "," + longitude);
				params.put("key", oneData.getValue());
				JSONObject jsonObject = getHtmlToJson(url, params);
				String status = jsonObject.getString("status");
				if ("0".equals(status)) {
					result = jsonObject.getJSONObject("result");
				} else {
					log.error("返回值：{}",jsonObject.toJSONString());
					log.error("转换失败！！！原因:" + jsonObject.getString("message"));
				}
				break;
			}
			case GD: {
				//高德API
				CommonInfo oneData = commonInfoService.findOne(427);
				String url = "https://restapi.amap.com/v3/geocode/regeo";
				Map<String, String> params = new HashMap<>();
				params.put("location", longitude + "," + latitude);
				params.put("key", oneData.getValue());
				JSONObject jsonObject = getHtmlToJson(url, params);
				String status = jsonObject.getString("status");
				if ("1".equals(status)) {
					result = jsonObject.getJSONObject("regeocode");
				}else {
					log.error("返回值：{}",jsonObject.toJSONString());
					log.error("转换失败！！！原因:" + jsonObject.getString("info"));
				}
				break;
			}
			case TDT: {
				//天地图API
				String value = commonInfoService.findOne(415).getValue();
				String url="http://api.tianditu.gov.cn/geocoder";
				Map<String,String> params = new HashMap<>();
				JSONObject postStr=new JSONObject();
				postStr.put("lon",longitude);
				postStr.put("lat",latitude);
				postStr.put("ver","1");
				params.put("postStr",postStr.toJSONString());
				params.put("type","geocode");
				params.put("tk",value);
				JSONObject jsonObject = getHtmlToJson(url, params);
				String status = jsonObject.getString("status");
				if("0".equals(status)){
					result = jsonObject.getJSONObject("result");
				}else {
					log.error("返回值：{}",jsonObject.toJSONString());
					log.error("转换失败！！！原因:" + jsonObject.getString("msg"));
				}
				break;
			}
			default: break;
		}
		return result;
	}

	/**
	 * 根据经纬度获取实际地址
	 * @param longitude 经度 125.294234
	 * @param latitude 纬度 43.887282
	 * @return 经纬度所对应的文字地址 如【北京市东城区东华门街道天安门-城楼】以行政区划+道路+门牌号等信息组成的标准格式化地址
	 */
	public static String getLocationToAddress(String longitude, String latitude){
		String address = "";
		MapEnum mapType = getMapType();
		JSONObject result = getReverseGeocoding(mapType, longitude, latitude);
		if(result != null) {
			switch (mapType){
				case TX: {
					//腾讯地图API
					address = result.getString("address");
					break;
				}
				case GD: case TDT: {
					//高德API/天地图
					address = result.getString("formatted_address");
					break;
				}
				default: break;
			}
		}
		return address;
	}

	/**
	 * 按坐标获取行政区划信息
	 * @param longitude 经度 125.294234
	 * @param latitude 纬度 43.887282
	 * @return province：省/直辖市，city：市/地级区 及同级行政区划，如果当前城市为省直辖县级区划，city与district字段均会返回此城市，district：区/县级市 及同级行政区划，address：经纬度所对应的文字地址 如【北京市东城区东华门街道天安门-城楼】以行政区划+道路+门牌号等信息组成的标准格式化地址
	 */

	public static JSONObject getLocationToAdInfo(String longitude, String latitude){
		MapEnum mapType = getMapType();
		JSONObject result = getReverseGeocoding(mapType, longitude, latitude);
		JSONObject resObject = null;
		try {
			if (result != null) {
				switch (mapType) {
					case TX: {
						//腾讯地图API
						resObject = result.getJSONObject("ad_info");//行政区划信息
						String address = result.getString("address");
						resObject.put("address", address);
						log.info("最终返回的地址对象：{}", resObject);
						break;
					}
					case GD:
					case TDT: {
						//高德API/天地图
						JSONObject addressComponent = result.getJSONObject("addressComponent");
						String province = addressComponent.getString("province");
						String city = addressComponent.getString("city");
						String adcode = addressComponent.getString("adcode");

						if (StringUtils.equals("[]", city)) {
							city = "";
						}

						String district = "";
						if (mapType == MapEnum.GD) {
							district = addressComponent.getString("district");
						} else {
							district = addressComponent.getString("county");
						}
						String address = result.getString("formatted_address");
						resObject = new JSONObject();
						resObject.put("province", province);//省 / 直辖市
						resObject.put("city", city);//市 / 地级区 及同级行政区划，如果当前城市为省直辖县级区划，city与district字段均会返回此城市
						resObject.put("adcode", adcode);//市代码
						resObject.put("district", district);//区 / 县级市 及同级行政区划
						resObject.put("address", address);//经纬度所对应的文字地址 如【北京市东城区东华门街道天安门-城楼】以行政区划+道路+门牌号等信息组成的标准格式化地址
						log.info("最终返回的地址对象：{}", resObject);
						break;
					}
					default:
						break;
				}
			}
		}catch(Exception e){
			e.printStackTrace();
		}
		return resObject;
	}


	/**
	 * 根据开始位置和结束位置根据出行方式获取米
	 * @param mapType
	 * @param tripWay （2：驾车/出租，其他值：公交）
	 * @param longitude 经度 125.294234
	 * @param latitude 纬度 43.887282
	 * @param toLongitude 经度 125.294234
	 * @param toLatitude 纬度 43.887282
	 * @return
	 */
	public static JSONObject calcTaxiMoney(MapEnum mapType,Integer tripWay, String longitude, String latitude, String toLongitude, String toLatitude, String city, String cityCode){
		JSONObject result = null;
		if(tripWay == null) tripWay = 1;
		if(tripWay != 1 && tripWay != 2) return null;
		switch (mapType){
			case TX: {
				//腾讯地图API
				CommonInfo oneData = commonInfoService.findOne(217);
				String url = "https://apis.map.qq.com/ws/direction/v1/transit/?";//公交（transit）路线规划
				if(tripWay == 2){
					url="https://apis.map.qq.com/ws/direction/v1/driving/?";//驾车（driving）路线规划
				}
				Map<String, String> params = new HashMap<>();
				params.put("from", latitude + "," + longitude);
				params.put("to", toLatitude + "," + toLongitude);
				if(tripWay == 2){
					params.put("no_step", "1");
				}
				params.put("key", oneData.getValue());
				JSONObject jsonObject = getHtmlToJson(url, params);
				String status = jsonObject.getString("status");
				if ("0".equals(status)) {
					result = jsonObject.getJSONObject("result");
				} else {
					log.error("返回值：{}",jsonObject.toJSONString());
					log.error("{}路线计算失败: {}",tripWay == 1?"公交":"驾车" , jsonObject.getString("message"));
				}
				break;
			}
			case GD: {
				//高德API
				CommonInfo oneData = commonInfoService.findOne(427);
				String url = "https://restapi.amap.com/v5/direction/transit/integrated";//公交
				if(tripWay == 2){
					url="https://restapi.amap.com/v5/direction/driving";//驾车
				}
				Map<String, String> params = new HashMap<>();
				params.put("origin", longitude + "," + latitude);
				params.put("destination", toLongitude + "," + toLatitude);
				params.put("key", oneData.getValue());
				//默认是公交，需要加城市
				if(tripWay != 2){
					//城市
					params.put("city1", cityCode);
					params.put("city2", cityCode);
				}

				JSONObject jsonObject = getHtmlToJson(url, params);
				String status = jsonObject.getString("status");
				if ("1".equals(status)) {
					result = jsonObject.getJSONObject("route");
				}else {
					log.error("返回值：{}",jsonObject.toJSONString());
					log.error("{}路线计算失败: {}",tripWay == 1?"公交":"驾车" , jsonObject.getString("message"));
				}
				break;
			}
			case TDT: {
				break;
			}
			default: break;
		}
		return result;
	}

	/**
	 * 根据开始位置和结束位置根据出行方式获取米
	 * @param tripWay （2：驾车/出租，其他值：公交）
	 * @param longitude 经度 125.294234
	 * @param latitude 纬度 43.887282
	 * @param toLongitude 经度 125.294234
	 * @param toLatitude 纬度 43.887282
	 * @return
	 */
	public static JSONObject calcTaxiMoneyInfo(Integer tripWay, String longitude, String latitude, String toLongitude, String toLatitude, String city, String cityCode){
		MapEnum mapType = getMapType();
		JSONObject result = calcTaxiMoney(mapType, tripWay, longitude, latitude, toLongitude, toLatitude, city, cityCode);
		JSONObject resObject = null;
		if(result != null) {
			switch (mapType){
				case TX: {
					//腾讯地图API
					JSONArray routes = result.getJSONArray("routes");
					if(!routes.isEmpty()){
						resObject = new JSONObject();
						String distance = routes.getJSONObject(0).getString("distance");
						resObject.put("distance",Integer.parseInt(distance));
						log.info("从n到n2距离 {} 米",distance);
					}
					break;
				}
				case GD: {
					//高德API
					if(tripWay == 2){
						//驾车
						JSONArray routes = result.getJSONArray("paths");
						if(!routes.isEmpty()){
							resObject = new JSONObject();
							String distance = routes.getJSONObject(0).getString("distance");
							resObject.put("distance",Integer.parseInt(distance));
							log.info("从n到n2距离 {} 米",distance);
						}else{
							resObject = new JSONObject();
							resObject.put("distance",0);
						}
					}else if(tripWay == 1){
						//公交
						JSONArray routes = result.getJSONArray("transits");
						if(!routes.isEmpty()){
							resObject = new JSONObject();
							String distance = routes.getJSONObject(0).getString("distance");
							resObject.put("distance",Integer.parseInt(distance));
							log.info("从n到n2距离 {} 米",distance);
						}else{
							resObject = new JSONObject();
							resObject.put("distance",0);
						}
					}
					break;
				}
				case TDT: break;
				default: break;
			}
		}
		return resObject;
	}


	/**
	 * 查询距离 （米）
	 * @param tripWay （2：驾车/出租，其他值：公交）
	 * @param longitude 经度 125.294234
	 * @param latitude 纬度 43.887282
	 * @param toLongitude 经度 43.887282
	 * @param toLatitude 纬度 43.887282
	 * @return
	 */
	public static JSONObject calcTaxiMoneyInfo(Integer tripWay, String longitude, String latitude, String toLongitude, String toLatitude) {
		JSONObject mapAdRes = CommonMapUtils.getLocationToAdInfo(longitude, latitude);
		String cityName = mapAdRes.getString("city");
		String cityCode = mapAdRes.getString("adcode");
		return calcTaxiMoneyInfo(tripWay, longitude, latitude, toLongitude, toLatitude, cityName, cityCode);
	}



}
