package com.yeejoin.amos.boot.module.tzs.biz.controller;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yeejoin.amos.boot.biz.common.controller.BaseController;
import com.yeejoin.amos.boot.biz.common.utils.DateUtils;
import com.yeejoin.amos.boot.biz.common.utils.RedisUtils;
import com.yeejoin.amos.boot.module.tzs.api.dto.WechatAccessDto;
import com.yeejoin.amos.boot.module.tzs.api.dto.WechatMyTaskDto;
import com.yeejoin.amos.boot.module.tzs.api.dto.WechatMyTaskListDto;
import com.yeejoin.amos.boot.module.tzs.api.entity.AlertFormValue;
import com.yeejoin.amos.boot.module.tzs.api.entity.WechatRelation;
import com.yeejoin.amos.boot.module.tzs.api.enums.AlertStageEnums;
import com.yeejoin.amos.boot.module.tzs.api.service.IDispatchTaskService;
import com.yeejoin.amos.boot.module.tzs.api.service.IWechatService;
import com.yeejoin.amos.boot.module.tzs.biz.service.impl.AlertFormValueServiceImpl;
import com.yeejoin.amos.boot.module.tzs.biz.service.impl.WechatRelationServiceImpl;
import com.yeejoin.amos.component.feign.model.FeignClientResult;
import com.yeejoin.amos.feign.systemctl.Systemctl;
import com.yeejoin.amos.feign.systemctl.model.SmsRecordModel;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.typroject.tyboot.core.foundation.enumeration.UserType;
import org.typroject.tyboot.core.foundation.utils.ValidationUtil;
import org.typroject.tyboot.core.restful.doc.TycloudOperation;
import org.typroject.tyboot.core.restful.exception.instance.BadRequest;
import org.typroject.tyboot.core.restful.utils.ResponseHelper;
import org.typroject.tyboot.core.restful.utils.ResponseModel;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import javax.servlet.http.HttpServletResponse;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

/**
 * 微信公众号controller
 */
@RestController
@Api(tags = "微信公众号Api")
@RequestMapping(value = "/wechatBack")
public class WechatController extends BaseController {

	private long time = 600l;

	private final String token = "yeejoin_2021";

	@Autowired
	RedisUtils redisUtils;

	@Autowired
	private IWechatService wechatService;

	@Autowired
	WechatRelationServiceImpl wechatRelationServiceImpl;

	@Autowired
	IDispatchTaskService dispatchTaskService;

	@Autowired
	private AlertFormValueServiceImpl iAlertFormValueService;



	/**
	 * 获取微信回调信息返回验证是否通过
	 * @param signature
	 * @param timestamp
	 * @param nonce
	 * @param echostr
	 * @return
	 */
	@TycloudOperation(ApiLevel = UserType.ANONYMOUS , needAuth = false)
	@GetMapping(value = "/getInfo")
	@ApiOperation(httpMethod = "GET", value = "获取微信传回的get信息", notes = "获取微信传回的get信息")
	public String getWechatInfo(@RequestParam String signature,@RequestParam String timestamp,@RequestParam String nonce,@RequestParam String echostr) {
		List<String> params = new ArrayList<String>();
		params.add(token);
		params.add(timestamp);
		params.add(nonce);
		Collections.sort(params);
		String tokenStr = StringUtils.join(params,"");
		tokenStr = DigestUtils.sha1Hex(tokenStr);
		if(tokenStr.equals(signature)) {
			return echostr;
		} else {
			return "";
		}
	}

	/**
	 * 获取微信推送的操作通知
	 * @param xml
	 * @param resp
	 * @return
	 */
	@TycloudOperation(ApiLevel = UserType.ANONYMOUS , needAuth = false)
	@PostMapping(value = "/getInfo")
	@ApiOperation(httpMethod = "POST", value = "获取微信传回的post信息", notes = "获取微信传回的post信息")
	public String getWechatInfoPost(@RequestBody String xml, HttpServletResponse resp) {
		Map<String, String> requtstMap = xmlToMap(xml);
		return "1";
	}


	/**
	 * XML格式字符串转换为Map
	 *
	 * @param xml XML字符串
	 * @return XML数据转换后的Map
	 * @throws Exception
	 */
	public static Map<String, String> xmlToMap(String xml) {
		try {
			Map<String, String> data = new HashMap<>();
			DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
			DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
			InputStream stream = new ByteArrayInputStream(xml.getBytes("UTF-8"));
			org.w3c.dom.Document doc = documentBuilder.parse(stream);
			doc.getDocumentElement().normalize();
			NodeList nodeList = doc.getDocumentElement().getChildNodes();
			for (int idx = 0; idx < nodeList.getLength(); ++idx) {
				Node node = nodeList.item(idx);
				if (node.getNodeType() == Node.ELEMENT_NODE) {
					org.w3c.dom.Element element = (org.w3c.dom.Element) node;
					data.put(element.getNodeName(), element.getTextContent());
				}
			}
			stream.close();
			return data;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	/**
	 * 获取wechatToken信息
	 *
	 * @return
	 */
	@TycloudOperation(ApiLevel = UserType.AGENCY, needAuth = false)
	@GetMapping(value = "/getAccessToken")
	@ApiOperation(httpMethod = "GET", value = "获取token信息", notes = "获取token信息")
	public ResponseModel<String> getAccessToken() {
		String token = wechatService.getAccessToken();
		return ResponseHelper.buildResponse(token);
	}

	/**
	 * 根据手机号发送短信验证码
	 * @param tel
	 * @return
	 */
	@TycloudOperation(ApiLevel = UserType.AGENCY, needAuth = false)
	@GetMapping(value = "/sendSms/{tel}")
	@ApiOperation(httpMethod = "GET", value = "根据手机号发送短信验证码", notes = "根据手机号发送短信验证码")
	public ResponseModel<Boolean> sendSmsCode(@PathVariable String tel) {
		Boolean flag = false;
		String code = getrandom();
		HashMap<String, String>  params = new HashMap<>();
		params.put("smsCode","SMS_TZS_0001");
		params.put("mobile",tel);
		params.put("code",code);
		FeignClientResult<SmsRecordModel> result = Systemctl.smsClient.sendCommonSms(params);
		if(result.getStatus() == 200) {
			flag = true;
			// code 保存在redis中 设置10分钟过期时间
			redisUtils.set("tel_code_" + tel, code,time);
		}
		return ResponseHelper.buildResponse(flag);
	}


	/**
	 * 根据微信code获取openId和手机号接口
	 *
	 * @return
	 */
	@TycloudOperation(ApiLevel = UserType.AGENCY, needAuth = false)
	@GetMapping(value = "/getOpenIdTel/{code}")
	@ApiOperation(httpMethod = "GET", value = "根据微信code获取openId和手机号接口", notes = "根据微信code获取openId和手机号接口")
	public ResponseModel<WechatAccessDto> getOpenIdTel(@PathVariable String code) {
		WechatAccessDto wechatAccessDto = new WechatAccessDto();
		String openId = wechatService.getOpenId(code);
		if(StringUtils.isNotEmpty(openId)) {
			JSONObject userInfo = wechatService.getUserInfo(openId);
			wechatAccessDto.setOpenId(openId);
			if(userInfo != null && userInfo.get("nickname") != null && userInfo.get("sex") != null) {
				wechatAccessDto.setNickname(userInfo.getString("nickname"));
				wechatAccessDto.setSex(userInfo.getString("sex"));
			}
			WechatRelation temp = wechatRelationServiceImpl.getOne(new LambdaQueryWrapper<WechatRelation>().eq(WechatRelation::getOpenId,openId));
			if(temp != null ) {
				wechatAccessDto.setTel(temp.getPhone());
			}
		}
		return ResponseHelper.buildResponse(wechatAccessDto);
	}

	/**
	 * 根据任务id 经纬度 返回现在距离任务距离
	 *
	 * @return
	 */
	@TycloudOperation(ApiLevel = UserType.AGENCY, needAuth = false)
	@PostMapping(value = "/returnDistance")
	@ApiOperation(httpMethod = "POST", value = "根据任务id 经纬度 返回现在距离任务距离", notes = "根据任务id 经纬度 返回现在距离任务距离")
	public ResponseModel<String> returnDistance(@ApiParam(value = "任务id", required = true) @RequestParam(name = "taskId") Long taskId,
														 @ApiParam(value = "经度", required = true)  @RequestParam(name = "longitude")  String longitude,
														 @ApiParam(value = "纬度", required = true)  @RequestParam(name = "latitude")  String latitude) {
		if (ValidationUtil.isEmpty(taskId)
				|| ValidationUtil.isEmpty(longitude)
				|| ValidationUtil.isEmpty(latitude)){
			throw new BadRequest("参数校验失败.");
		}
		String distance = dispatchTaskService.returnDistanceByTaskId(taskId,longitude,latitude);
		return ResponseHelper.buildResponse(distance);
	}

	/**
	 * 获取任务详情
	 *
	 * @return
	 */
	@TycloudOperation(ApiLevel = UserType.AGENCY, needAuth = false)
	@GetMapping(value = "/getTaskInfo/{taskId}")
	@ApiOperation(httpMethod = "GET", value = "获取任务详情", notes = "获取任务详情")
	public ResponseModel<WechatMyTaskDto> getTaskInfo(@PathVariable Long taskId) {
		if (ValidationUtil.isEmpty(taskId)){
			throw new BadRequest("参数校验失败.");
		}
		WechatMyTaskDto temp = dispatchTaskService.getTaskInfoByTaskId(taskId);
		List<AlertFormValue> paperList = null;
		LambdaQueryWrapper<AlertFormValue> queryWrapper = new LambdaQueryWrapper<>();
		switch (temp.getTaskTypeCode()) {
			case "960" : // 困人救援
				temp.setHasDeadHurt("无");
				queryWrapper.eq(AlertFormValue::getAlertCalledId, temp.getAlertId());
				// 警情动态表单数据
				List<AlertFormValue> alertList = iAlertFormValueService.list(queryWrapper);
				alertList.stream().forEach(t -> {
					String value = t.getFieldValue();
					if("trapped_floor_num".equals(t.getFieldCode())) {
						// 被困楼层
						temp.setTrappedFloorNum(value);
					} else if("trapped_num".equals(t.getFieldCode())) {
						// 被困人数
						temp.setTrappedNum(value);
					} else if("injured_num".equals(t.getFieldCode())) {
						// 受伤人数
						if(StringUtils.isNotEmpty(value)) {
							temp.setHasDeadHurt("有");
						}
					} else if("die_num".equals(t.getFieldCode())) {
						// 死亡人数
						if(StringUtils.isNotEmpty(value)) {
							temp.setHasDeadHurt("有");
						}
					}
				});
				queryWrapper = new LambdaQueryWrapper<>();
				queryWrapper.eq(AlertFormValue::getAlertCalledId, temp.getPaperId());
				// 派遣动态表单
				paperList = iAlertFormValueService.list(queryWrapper);
				paperList.stream().forEach(t -> {
					String value = t.getFieldValue();
					if("save_time".equals(t.getFieldCode())) {
						// 救援完成时间
						if(StringUtils.isNotBlank(value)) {
							temp.setSaveTime(DateUtils.longStr2Date(value));
						}
					} else if("error_result".equals(t.getFieldCode())) {
						// 故障原因
						temp.setErrorResult(value);
					} else if("fix_result".equals(t.getFieldCode())) {
						// 维修结果
						temp.setFixResult(value);
					} else if("fix_remark".equals(t.getFieldCode())) {
						// 维修备注
						temp.setRemark(value);
					}
				});

				// 预留照片处理
				break;
			case "961" : // 故障维修
				queryWrapper = new LambdaQueryWrapper<>();
				queryWrapper.eq(AlertFormValue::getAlertCalledId, temp.getPaperId());
				// 派遣动态表单
				paperList = iAlertFormValueService.list(queryWrapper);
				paperList.stream().forEach(t -> {
					String value = t.getFieldValue();
					if("save_time".equals(t.getFieldCode())) {
						// 救援完成时间
						if(StringUtils.isNotBlank(value)) {
							temp.setSaveTime(DateUtils.longStr2Date(value));
						}
					} else if("error_result".equals(t.getFieldCode())) {
						// 故障原因
						temp.setErrorResult(value);
					} else if("fix_result".equals(t.getFieldCode())) {
						// 维修结果
						temp.setFixResult(value);
					} else if("fix_remark".equals(t.getFieldCode())) {
						// 维修备注
						temp.setRemark(value);
					} else if("feedback_result".equals(t.getFieldCode())) {
						// 反馈结果
						temp.setFeedbackResult(value);
					}
				});

				break;
			case "962" : // 投诉建议
				queryWrapper = new LambdaQueryWrapper<>();
				queryWrapper.eq(AlertFormValue::getAlertCalledId, temp.getPaperId());
				// 派遣动态表单
				paperList = iAlertFormValueService.list(queryWrapper);
				paperList.stream().forEach(t -> {
					String value = t.getFieldValue();
					if("action_result".equals(t.getFieldCode())) {
						//	处置结果
						temp.setActionResult(value);
					}
				});
				break;
		}

		return ResponseHelper.buildResponse(temp);
	}

	/**
	 * 点击到达触发事件
	 *
	 * @return
	 */
	@TycloudOperation(ApiLevel = UserType.AGENCY, needAuth = false)
	@PostMapping(value = "/taskArrive")
	@ApiOperation(httpMethod = "POST", value = "点击到达触发事件", notes = "点击到达触发事件")
	public ResponseModel<WechatMyTaskDto> taskArrive(@RequestParam Long taskId) {
		if (ValidationUtil.isEmpty(taskId)){
			throw new BadRequest("参数校验失败.");
		}
		if(dispatchTaskService.taskArrive(taskId)) {
			WechatMyTaskDto temp = dispatchTaskService.getTaskInfoByTaskId(taskId);
			List<AlertFormValue> paperList = null;
			LambdaQueryWrapper<AlertFormValue> queryWrapper = new LambdaQueryWrapper<>();
			switch (temp.getTaskTypeCode()) {
				case "960" : // 困人救援
					temp.setHasDeadHurt("无");
					queryWrapper.eq(AlertFormValue::getAlertCalledId, temp.getAlertId());
					// 警情动态表单数据
					List<AlertFormValue> alertList = iAlertFormValueService.list(queryWrapper);
					alertList.stream().forEach(t -> {
						String value = t.getFieldValue();
						if("trapped_floor_num".equals(t.getFieldCode())) {
							// 被困楼层
							temp.setTrappedFloorNum(value);
						} else if("trapped_num".equals(t.getFieldCode())) {
							// 被困人数
							temp.setTrappedNum(value);
						} else if("injured_num".equals(t.getFieldCode())) {
							// 受伤人数
							if(StringUtils.isNotEmpty(value)) {
								temp.setHasDeadHurt("有");
							}
						} else if("die_num".equals(t.getFieldCode())) {
							// 死亡人数
							if(StringUtils.isNotEmpty(value)) {
								temp.setHasDeadHurt("有");
							}
						}
					});
					queryWrapper = new LambdaQueryWrapper<>();
					queryWrapper.eq(AlertFormValue::getAlertCalledId, temp.getPaperId());
					// 派遣动态表单
					paperList = iAlertFormValueService.list(queryWrapper);
					paperList.stream().forEach(t -> {
						String value = t.getFieldValue();
						if("save_time".equals(t.getFieldCode())) {
							// 救援完成时间
							if(StringUtils.isNotBlank(value)) {
								temp.setSaveTime(DateUtils.longStr2Date(value));
							}
						} else if("error_result".equals(t.getFieldCode())) {
							// 故障原因
							temp.setErrorResult(value);
						} else if("fix_result".equals(t.getFieldCode())) {
							// 维修结果
							temp.setFixResult(value);
						} else if("fix_remark".equals(t.getFieldCode())) {
							// 维修备注
							temp.setRemark(value);
						}
					});

					// 预留照片处理
					break;
				case "961" : // 故障维修
					queryWrapper = new LambdaQueryWrapper<>();
					queryWrapper.eq(AlertFormValue::getAlertCalledId, temp.getPaperId());
					// 派遣动态表单
					paperList = iAlertFormValueService.list(queryWrapper);
					paperList.stream().forEach(t -> {
						String value = t.getFieldValue();
						if("save_time".equals(t.getFieldCode())) {
							// 救援完成时间
							if(StringUtils.isNotBlank(value)) {
								temp.setSaveTime(DateUtils.longStr2Date(value));
							}
						} else if("error_result".equals(t.getFieldCode())) {
							// 故障原因
							temp.setErrorResult(value);
						} else if("fix_result".equals(t.getFieldCode())) {
							// 维修结果
							temp.setFixResult(value);
						} else if("fix_remark".equals(t.getFieldCode())) {
							// 维修备注
							temp.setRemark(value);
						} else if("feedback_result".equals(t.getFieldCode())) {
							// 反馈结果
							temp.setFeedbackResult(value);
						}
					});

					break;
				case "962" : // 投诉建议
					queryWrapper = new LambdaQueryWrapper<>();
					queryWrapper.eq(AlertFormValue::getAlertCalledId, temp.getPaperId());
					// 派遣动态表单
					paperList = iAlertFormValueService.list(queryWrapper);
					paperList.stream().forEach(t -> {
						String value = t.getFieldValue();
						if("action_result".equals(t.getFieldCode())) {
							//	处置结果
							temp.setActionResult(value);
						}
					});
					break;
			}
			return ResponseHelper.buildResponse(temp);
		} else {
			return ResponseHelper.buildResponse(new WechatMyTaskDto());
		}
	}


	/**
	 * 点击救援完成触发事件
	 *
	 * @return
	 */
	@TycloudOperation(ApiLevel = UserType.AGENCY, needAuth = false)
	@PostMapping(value = "/saveFinish")
	@ApiOperation(httpMethod = "POST", value = "点击救援完成触发事件", notes = "点击救援完成触发事件")
	public ResponseModel<WechatMyTaskDto> saveFinish(@RequestParam Long taskId) {
		if (ValidationUtil.isEmpty(taskId)){
			throw new BadRequest("参数校验失败.");
		}
		if(dispatchTaskService.saveFinish(taskId)) {
			WechatMyTaskDto temp = dispatchTaskService.getTaskInfoByTaskId(taskId);
			List<AlertFormValue> paperList = null;
			LambdaQueryWrapper<AlertFormValue> queryWrapper = new LambdaQueryWrapper<>();
			switch (temp.getTaskTypeCode()) {
				case "960" : // 困人救援
					temp.setHasDeadHurt("无");
					queryWrapper.eq(AlertFormValue::getAlertCalledId, temp.getAlertId());
					// 警情动态表单数据
					List<AlertFormValue> alertList = iAlertFormValueService.list(queryWrapper);
					alertList.stream().forEach(t -> {
						String value = t.getFieldValue();
						if("trapped_floor_num".equals(t.getFieldCode())) {
							// 被困楼层
							temp.setTrappedFloorNum(value);
						} else if("trapped_num".equals(t.getFieldCode())) {
							// 被困人数
							temp.setTrappedNum(value);
						} else if("injured_num".equals(t.getFieldCode())) {
							// 受伤人数
							if(StringUtils.isNotEmpty(value)) {
								temp.setHasDeadHurt("有");
							}
						} else if("die_num".equals(t.getFieldCode())) {
							// 死亡人数
							if(StringUtils.isNotEmpty(value)) {
								temp.setHasDeadHurt("有");
							}
						}
					});
					queryWrapper = new LambdaQueryWrapper<>();
					queryWrapper.eq(AlertFormValue::getAlertCalledId, temp.getPaperId());
					// 派遣动态表单
					paperList = iAlertFormValueService.list(queryWrapper);
					paperList.stream().forEach(t -> {
						String value = t.getFieldValue();
						if("save_time".equals(t.getFieldCode())) {
							// 救援完成时间
							if(StringUtils.isNotBlank(value)) {
								temp.setSaveTime(DateUtils.longStr2Date(value));
							}
						} else if("error_result".equals(t.getFieldCode())) {
							// 故障原因
							temp.setErrorResult(value);
						} else if("fix_result".equals(t.getFieldCode())) {
							// 维修结果
							temp.setFixResult(value);
						} else if("fix_remark".equals(t.getFieldCode())) {
							// 维修备注
							temp.setRemark(value);
						}
					});

					// 预留照片处理
					break;
				case "961" : // 故障维修
					queryWrapper = new LambdaQueryWrapper<>();
					queryWrapper.eq(AlertFormValue::getAlertCalledId, temp.getPaperId());
					// 派遣动态表单
					paperList = iAlertFormValueService.list(queryWrapper);
					paperList.stream().forEach(t -> {
						String value = t.getFieldValue();
						if("save_time".equals(t.getFieldCode())) {
							// 救援完成时间
							if(StringUtils.isNotBlank(value)) {
								temp.setSaveTime(DateUtils.longStr2Date(value));
							}
						} else if("error_result".equals(t.getFieldCode())) {
							// 故障原因
							temp.setErrorResult(value);
						} else if("fix_result".equals(t.getFieldCode())) {
							// 维修结果
							temp.setFixResult(value);
						} else if("fix_remark".equals(t.getFieldCode())) {
							// 维修备注
							temp.setRemark(value);
						} else if("feedback_result".equals(t.getFieldCode())) {
							// 反馈结果
							temp.setFeedbackResult(value);
						}
					});

					break;
				case "962" : // 投诉建议
					queryWrapper = new LambdaQueryWrapper<>();
					queryWrapper.eq(AlertFormValue::getAlertCalledId, temp.getPaperId());
					// 派遣动态表单
					paperList = iAlertFormValueService.list(queryWrapper);
					paperList.stream().forEach(t -> {
						String value = t.getFieldValue();
						if("action_result".equals(t.getFieldCode())) {
							//	处置结果
							temp.setActionResult(value);
						}
					});
					break;
			}
			return ResponseHelper.buildResponse(temp);
		} else {
			return ResponseHelper.buildResponse(new WechatMyTaskDto());
		}
	}


	/**
	 * 创建验证码
	 * @return
	 */
	public static String getrandom(){
		String code = "";
		Random random = new Random();
		for (int i = 0; i < 6; i++) {
			int r = random.nextInt(10); //每次随机出一个数字（0-9）
			code = code + r;  //把每次随机出的数字拼在一起
		}
		return code;

	}

	/**
	 * 获取任务列表
	 *
	 * @return
	 */
	@TycloudOperation(ApiLevel = UserType.AGENCY, needAuth = false)
	@GetMapping(value = "/getTaskList")
	@ApiOperation(httpMethod = "GET", value = "根据用户手机号获取任务列表", notes = "根据用户手机号获取任务列表")
	public ResponseModel<List<WechatMyTaskListDto>> getTaskList(@ApiParam(value = "电话号码", required = true) @RequestParam String phone,
																@ApiParam(value = "任务类别", required = true) @RequestParam String taskType,
																@ApiParam(value = "当前页码", required = true) @RequestParam Long currentPage) {
		if (ValidationUtil.isEmpty(phone) ||
			ValidationUtil.isEmpty(taskType) ||
			ValidationUtil.isEmpty(currentPage)){
			throw new BadRequest("参数校验失败.");
		}
		return ResponseHelper.buildResponse(dispatchTaskService.getTaskListByPhonePager(phone, taskType, currentPage));
	}

}
