package com.palmnest.webapp.controller.api;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.github.wxpay.sdk.WXPayUtil;
import com.palmnest.application.AppConstants;
import com.palmnest.application.Constants;
import com.palmnest.application.bean.AppResultDto;
import com.palmnest.application.bean.AppTokResultDto;
import com.palmnest.application.bean.ReturnObject;
import com.palmnest.application.core.util.AppResultUtil;
import com.palmnest.model.estateserve.AppUser;
import com.palmnest.model.estateserve.WxUser;
import com.palmnest.model.property.TbOrganization;
import com.palmnest.model.property.VirtualArchitecture;
import com.palmnest.model.repair.RepairBill;
import com.palmnest.model.repair.WeixinNotifyInfo;
import com.palmnest.service.estateserve.AppUserManager;
import com.palmnest.service.estateserve.ScWxuserManager;
import com.palmnest.service.property.PropertyManager;
import com.palmnest.service.repair.RepairBillManager;
import com.palmnest.service.repair.RepairBillService;
import com.palmnest.service.repair.WeixinNotifyInfoManager;
import com.palmnest.service.wechat.WeChatApiManager;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Slf4j
@Controller
@RequestMapping(value = "/wechat")
public class AppWeiXinPayController {


	@Autowired
	private WeixinNotifyInfoManager weixinNotifyInfoManager;
	@Autowired
	private RepairBillManager       repairBillManager;
	@Autowired
	private RepairBillService       repairBillService;
	@Autowired
	private PropertyManager         propertyManager;
	@Autowired
	private AppUserManager          appUserManager;
	@Autowired
	private WeChatApiManager        weChatApiManager;
	@Autowired
	private ScWxuserManager         scWxuserManager;

	@RequestMapping("/auth")
	@ResponseBody
	public AppTokResultDto auth(String developId) {
		if (StringUtils.isEmpty(developId)) {
			return AppResultUtil.createTokErrorDto("", "请传入正确的developId");
		}
		try {
			String accessToken = weChatApiManager.getAccessToken(developId);
			if (StringUtils.isNotEmpty(accessToken)) {
				return AppResultUtil.createTokSuccessDto(accessToken);
			}
			return AppResultUtil.createTokErrorDto("");
		} catch (Exception e) {
			e.printStackTrace();
			return AppResultUtil.createTokErrorDto("");
		}
	}

	/**
	 * 获取公众号token
	 *
	 * @param developId
	 * @return
	 */
	@RequestMapping("/authToken")
	@ResponseBody
	public AppResultDto authToken(String developId) {

		if (StringUtils.isEmpty(developId)) {
			return AppResultUtil.createErrorDto(AppConstants.DEVELOPID_NULL, "请传入正确的developId");
		}

		try {

			String accessToken = weChatApiManager.getAccessToken(developId);

			if (StringUtils.isNotEmpty(accessToken)) {
				return AppResultUtil.createSuccesDto(accessToken);
			}

			return AppResultUtil.createErrorDto(AppConstants.TOKEN_EXCEPTION, "获取公众号token异常");
		} catch (Exception e) {
			e.printStackTrace();
			return AppResultUtil.createErrorDto(AppConstants.TOKEN_EXCEPTION, "获取公众号token异常");
		}
	}

	/**
	 * 航电对接，根据openId
	 *
	 * @param developId
	 * @return
	 */
	@RequestMapping("/sendCustomMessage")
	@ResponseBody
	public AppResultDto sendCustomMessage(String openId, String content) {

		if (StringUtils.isEmpty(openId)) {
			return AppResultUtil.createErrorDto(AppConstants.OPEN_ID_ERROR, "请传入正确的openId");
		}

		if (StringUtils.isEmpty(content)) {
			return AppResultUtil.createErrorDto(AppConstants.CONTENT_ERROR, "请传入正确的content");
		}

		try {
			String msg = weChatApiManager.sendCustomMsgWithOpenId(openId, content);

			if (StringUtils.isNotEmpty(msg) && msg.equals("success")) {
				return AppResultUtil.createSuccesDto();
			}

			if (StringUtils.isNotEmpty(msg) && msg.contains("45015")) {
				return AppResultUtil.createErrorDto(AppConstants.SEND_MSG_ERROR, "用户超48小时未与公众号交互");
			}

			return AppResultUtil.createErrorDto(AppConstants.SEND_MSG_ERROR, "发送客服消息失败");
		} catch (Exception e) {
			e.printStackTrace();
			return AppResultUtil.createErrorDto(AppConstants.SEND_MSG_ERROR, "发送客服消息失败");
		}
	}

	/**
	 * 返回超级前台服务号access_token
	 *
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "access_token", produces = "application/json")
	public @ResponseBody
	String access_token(HttpServletRequest request,
						HttpServletResponse response) {

		ReturnObject rt        = new ReturnObject();
		String       developId = request.getParameter("developId");

		//超级前台服务号 developId
		if (StringUtils.isEmpty(developId)) {
			developId = "gh_5e42b7c7c069";
		}

		if (StringUtils.isNotBlank(developId)) {

			try {
				String              accessToken = weChatApiManager.getAccessToken(developId);
				Map<String, String> resultMap   = new HashMap<String, String>();
				resultMap.put("accessToken", accessToken);

				rt.setResult(Constants.RESULT_SUCC);
				rt.setResultCode(Constants.RESULTCODE_SUCC);
				rt.setReturnDTO(resultMap);

			} catch (Exception e) {
				rt.setResult(Constants.RESULT_FIAL);
				rt.setResultCode(Constants.RESULTCODE_EXCEPTION);
				rt.setResultDesc("服务器异常");
			}

		} else {
			rt.setResult(Constants.RESULT_FIAL);
			rt.setResultCode(Constants.RESULTCODE_PARAMINVALID);
			rt.setResultDesc("请检查参数");
		}
		String str = JSONObject.toJSONString(rt, SerializerFeature.WriteMapNullValue);
		if (StringUtils.isNotBlank(request.getParameter("callback"))) {
			return request.getParameter("callback") + "(" + str + ")";
		}
		return str;
	}

	/**
	 * 用户资料信息获取接口
	 *
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "/userInfo", method = {RequestMethod.POST}, produces = "application/json;charset=utf-8")
	public @ResponseBody
	String userInfo(HttpServletRequest request) {

		ReturnObject rt     = new ReturnObject();
		String       userId = request.getParameter("userId");
		log.info("userId:" + userId);

		if (StringUtils.isNotBlank(userId)) {

			AppUser appUser = appUserManager.get(Integer.parseInt(userId));
			if (appUser != null) {
				Map<String, String> data = new HashMap<String, String>();
				data.put("userName", appUser.getUserName());
				data.put("userMobile", appUser.getUserMobile());
				data.put("userPhotoUrl", appUser.getUserPhotoUrl());
				data.put("status", appUser.getStatus());

				//返回openid 用于商城发模板消息
				if (appUser.getWxUserId() != null) {
					WxUser wxUser = scWxuserManager.get(appUser.getWxUserId());
					if (null != wxUser && StringUtils.isNotEmpty(wxUser.getOpenId())) {
						data.put("openId", wxUser.getOpenId());
					} else {
						data.put("openId", "");
					}
				}

				//项目信息组装
				if (appUser.getOrganizationId() != null) {
					TbOrganization organization = propertyManager.getTbOrganizationById(appUser.getOrganizationId());
					data.put("organizationName", organization.getName());
					data.put("organizationCode", organization.getCode());
				} else {
					data.put("organizationName", "");
					data.put("organizationCode", "");
				}
				//企业信息组装
				if (appUser.getVirtualArchId() != null) {
					VirtualArchitecture virtual = propertyManager.getVirtualArchitectureById(appUser.getVirtualArchId());
					data.put("virtualName", virtual.getName());
					data.put("virtualCode", virtual.getCodeNumber());
				} else {
					data.put("virtualName", "");
					data.put("virtualCode", "");
				}
				rt.setReturnDTO(data);
				rt.setResult(Constants.RESULT_SUCC);
				rt.setResultCode(Constants.RESULTCODE_SUCC);
				rt.setResultDesc("success");
			} else {
				rt.setResult(Constants.RESULT_SUCC);
				rt.setResultCode(Constants.RESULTCODE_NODATA);
				rt.setResultDesc("暂无用户数据");
			}
		} else {
			rt.setResult(Constants.RESULT_FIAL);
			rt.setResultCode(Constants.RESULTCODE_PARAMINVALID);
			rt.setResultDesc("无效参数");
		}
		String str = JSONObject.toJSONString(rt, SerializerFeature.WriteMapNullValue);
		if (StringUtils.isNotBlank(request.getParameter("callback"))) {
			return request.getParameter("callback") + "(" + str + ")";
		}
		return str;
	}


	@RequestMapping("/pay/wxpayNotify")
	@ResponseBody
	public void wxpayNotify(HttpServletRequest request, HttpServletResponse response) {
		try {
			request.setCharacterEncoding("UTF-8");
			response.setCharacterEncoding("UTF-8");
			// 处理接收消息    
			ServletInputStream in = request.getInputStream();

			// 将流转换为字符串
			StringBuilder xmlMsg = new StringBuilder();
			byte[]        b      = new byte[4096];
			for (int n; (n = in.read(b)) != -1; ) {
				xmlMsg.append(new String(b, 0, n, "UTF-8"));
			}
			Map<String, String> tMap = WXPayUtil.xmlToMap(xmlMsg.toString());


			if (tMap.get("return_code").equals("SUCCESS")) {
				WeixinNotifyInfo weixinNotifyInfo = new WeixinNotifyInfo();
				weixinNotifyInfo.setBankType(tMap.get("bank_type"));
				weixinNotifyInfo.setCashFee(Integer.parseInt(tMap.get("cash_fee")));
				if (tMap.containsKey("err_code")) {
					weixinNotifyInfo.setErrCode(tMap.get("err_code"));
				}
				if (tMap.containsKey("err_code_des")) {
					weixinNotifyInfo.setErrCodeDes(tMap.get("err_code_des"));
				}
				if (tMap.containsKey("is_subscribe")) {
					weixinNotifyInfo.setIsSubscribe(tMap.get("is_subscribe"));
				}

				weixinNotifyInfo.setNonceStr(tMap.get("nonce_str"));
				weixinNotifyInfo.setOpenid(tMap.get("openid"));
				weixinNotifyInfo.setOutTradeNo(tMap.get("out_trade_no"));
				weixinNotifyInfo.setResultCode(tMap.get("result_code"));
				weixinNotifyInfo.setReturnCode(tMap.get("return_code"));
				weixinNotifyInfo.setReturnMsg(tMap.get("return_msg"));
				if (tMap.containsKey("settlement_total_fee")) {
					weixinNotifyInfo.setSettlementTotalFee(Integer.parseInt(tMap.get("settlement_total_fee")));
				}

				weixinNotifyInfo.setSign(tMap.get("sign"));
				if (tMap.containsKey("sign_type")) {
					weixinNotifyInfo.setSignType(tMap.get("sign_type"));
				}

				weixinNotifyInfo.setTimeEnd(tMap.get("time_end"));
				weixinNotifyInfo.setTotalFee(Integer.parseInt(tMap.get("total_fee")));
				weixinNotifyInfo.setTradeType(tMap.get("trade_type"));
				weixinNotifyInfo.setTransactionId(tMap.get("transaction_id"));
				weixinNotifyInfo.setCreateTime(new Date());
				weixinNotifyInfoManager.save(weixinNotifyInfo);

				//校验金额
				log.info("totle_fee:" + tMap.get("total_fee"));
				String code = tMap.get("out_trade_no");
				code = code.substring(0, code.lastIndexOf("-"));
				RepairBill bill = repairBillManager.findByCode(code, new BigDecimal(tMap.get("total_fee")).divide(new BigDecimal(100)));
				if (bill != null) {
					log.info("-----维修单：" + bill.getId() + "支付成功");
					bill.setHasPaid(2);
					bill.setModifyTime(new Date());
					repairBillManager.updateModel(bill);

					if (bill.getBillFrom().intValue() == 2) {
						repairBillService.pushWechatTemplateMsg(bill, 2);
					}
					//返回
					Map<String, String> dataMap = new HashMap<String, String>();
					dataMap.put("return_code", "SUCCESS");
					response.getWriter().write(WXPayUtil.mapToXml(dataMap));
				}

			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
