package com.palmnest.service.wechat.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.palmnest.application.Constants;
import com.palmnest.application.core.util.*;
import com.palmnest.dao.estateserve.AppUserDao;
import com.palmnest.dao.estateserve.PublicNoDao;
import com.palmnest.dao.estateserve.ScWxuserDao;
import com.palmnest.dao.estateserve.ServicePackDao;
import com.palmnest.dao.wechat.RechargeDao;
import com.palmnest.dao.wechat.ReplayContentDao;
import com.palmnest.model.estateserve.*;
import com.palmnest.service.AsynchronousDataService;
import com.palmnest.service.estateserve.RechargeWebManager;
import com.palmnest.service.impl.GenericManagerImpl;
import com.palmnest.service.wechat.RechargeManager;
import com.palmnest.service.wechat.WeChatApiManager;
import com.palmnest.service.ws.PhoneClient;
import com.palmnest.webapp.controller.wechat.RechargeController;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 签约管理微信端实现类
 *
 * @author xiemin
 * @date 2017-05-18
 */
@Slf4j
@Component("rechargeManager")
public class RechargeManagerImpl extends GenericManagerImpl<Recharge, Integer> implements RechargeManager {


	private RechargeDao rechargetDao;

	@Autowired
	public void setRechargetDao(RechargeDao rechargetDao) {
		this.rechargetDao = rechargetDao;
		this.dao = rechargetDao;
	}

	@Autowired
	private ReplayContentDao        replayContentDao;
	@Autowired
	private AsynchronousDataService asynchronousWorkService;
	@Autowired
	private WeChatApiManager        weChatApiManager;
	@Autowired
	private RechargeWebManager      rechargeWebManager;
	@Autowired
	private AppUserDao              appUserDao;
	@Autowired
	private PublicNoDao             publicNoDao;
	@Autowired
	private ServicePackDao          servicePackDao;
	@Autowired
	private ScWxuserDao             scWxuserDao;

	public static String webUrl = PropertiesKit.readPropertiesValue("callbackWebUrl", "wechat.properties");

	/**
	 * 流量充值返回url
	 */
	public static String callbackUrl = webUrl + "/wechat/recharge/callbackUrl";


	@Override
	public List<Product> findProduct(String province, String carrieroperator,
									 String type, String isEnabled) {
		try {
			return rechargetDao.findProduct(province, carrieroperator, type, isEnabled);
		} catch (Exception e) {
			log.error("findProduct occur error." + LogExceptionStackUtil.LogExceptionStack(e));
		}
		return null;
	}

	@Override
	public int addRecharge(Map<String, String> map) {
		try {
			int result = rechargetDao.addRecharge(map);
			return result;
		} catch (Exception e) {
			log.error("addRecharge occur error."
					+ LogExceptionStackUtil.LogExceptionStack(e));
		}
		return -1;
	}

	@Override
	public String updateRechargeStatus(Map<String, String> map) {
		String jsonString = "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";
		try {
			//聚点充值
			String out_trade_no  = map.get("outTradeNo"); // 商户订单号
			String transactionId = map.get("transactionId"); // 微信返回id
			String mchId         = map.get("mchId"); // 微信商户号
			// 根据订单号查询充值信息
			Recharge re = rechargetDao.findRechargeByOrdId(out_trade_no);
			// 支付成功返回
			if (re.getPayStatus().equals("0")) {
				return jsonString;
			}
			String jsonStr = "";
			//话费流量处理
			if (map.get("type").equals("0") || map.get("type").equals("1")) {

				String type      = re.getType();
				int    productId = re.getProductId();
				// 根据产品id查询产品信息
				Map<String, String> mapPt       = rechargetDao.findProductById(productId);
				String              openId      = re.getOpenId();
				String              title       = "支付成功，2个工作日到账，请留意微信通知\\n";
				String              price       = re.getPrice() + "元";
				String              developId   = re.getDevelopId();
				String              productName = mapPt.get("productName") + "元手机话费";
				String              remark      = "如有问题请微信留言，小超将第一时间为您服务！";
				if (re.getType().equals("0")) {
					title = "支付成功，10分钟内到账，请留意微信通知\\n";
					productName = mapPt.get("productName") + "手机流量";
				}

				String mobile = re.getMobile();
				re.setStatus("0"); // 充值中
				re.setPayStatus("0"); // 支付成功
				re.setTransactionId(transactionId);
				re.setWxUserId(mchId);
				rechargetDao.updateRecharge(re);

				if (null != mapPt && type.equals("0")) {
					StringBuffer        sbf         = new StringBuffer();
					Map<String, String> mapRecharge = new HashMap<String, String>();

					String timestamp = DateUtils.getTime(new Date(), "");
					String sign      = StringUtil.commonParameters(timestamp);
					String body = sbf.append("<body><message><flow>")
							.append(mapPt.get("productName"))
							.append("</flow><type>").append("ROAM_PACKAGE")
							.append("</type><order><mobile>").append(mobile)
							.append("</mobile><orderid>").append(out_trade_no)
							.append("</orderid></order></message></body>")
							.toString();
					mapRecharge.put("name", Constants.NAME);
					mapRecharge.put("timestamp", timestamp);
					mapRecharge.put("sign", sign);
					mapRecharge.put("version", Constants.VERSION);
					mapRecharge.put("body", body);
					mapRecharge.put("callbackURL", callbackUrl);
					jsonStr = HttpKit.httpRecharge(Constants.ASK_URL + "Order", mapRecharge, Constants.POST);

					log.info("jsonStr" + jsonStr);
				}

				// 调用支付成功微信通知
				Map<String, String> paramMap = new HashMap<String, String>();
				List<Map<String, Object>> templateList = replayContentDao
						.getWxTemplate("6", 0);
				if (templateList != null) {
					String webUrl = PropertiesKit.readPropertiesValue("callbackWebUrl", "wechat.properties");
					String url    = webUrl + "/wechat/recharge/getRechareRecordInfo?id=" + re.getId() + "&developId=" + re.getDevelopId() + "&operationType=" + mapPt.get("type") + "&openId=" + re.getOpenId() + "&channelCode=" + re.getChannelCode();
					String templateId = (String) templateList.get(0)
							.get("templateId");
					paramMap.put("templateId", templateId);
					paramMap.put("developId", developId);
					paramMap.put("openId", openId);
					paramMap.put("title", title);
					paramMap.put("price", price);
					paramMap.put("productName", productName);
					paramMap.put("remark", remark);
					paramMap.put("orderNo", out_trade_no);//新加的订单号
					paramMap.put("url", url);
					paramMap.put("createTime", re.getModifyTime());
					log.info("=========paramMap=======" + paramMap);
					weChatApiManager.sendTemplateMsg06(paramMap);
				}

				if (StringUtils.isNotEmpty(jsonStr)) {
					JSONObject jsonObject = JSON.parseObject(StringUtil.xmlToJSON(jsonStr));
					JSONObject bodyBack   = jsonObject.getJSONObject("body");
					log.info("bodyBack" + bodyBack);
					//产品未开通
					if (null != bodyBack.getString("code") && !bodyBack.getString("code").equals("") && bodyBack.getString("code").equals("-9")) {
						String rechargeDesc = "暂无";
						if (null != bodyBack.getString("message") && !bodyBack.getString("message").equals("")) {
							rechargeDesc = bodyBack.getString("rechargeDesc");
						}
						re.setRecharTime(DateUtils.formatDate(new Date()));
						re.setRechargeDesc(rechargeDesc);
						re.setStatus("2");

						rechargetDao.updateRecharge(re);
						bodyBack = rechargeWebManager.updateDrawback(out_trade_no);
						log.info("bodyBack退款后：" + bodyBack);
					}
				}
			}
			//加油卡处理	
			else if ("SINOPEC".equals(map.get("type")) || "CNPC".equals(map.get("type"))) {
				re.setStatus("0");        // 充值中
				re.setPayStatus("0");    // 支付成功
				re.setPayTime(DateUtils.getDate("yyyy-MM-dd HH:mm:ss"));
				re.setTransactionId(transactionId);
				re.setWxUserId(mchId);
				rechargetDao.updateObj(re);

				assignfuelCardCharge(re);
			}
			//影视会员
			else {
				re.setStatus("0");        // 充值中
				re.setPayStatus("0");    // 支付成功
				re.setTransactionId(transactionId);
				re.setWxUserId(mchId);
				rechargetDao.updateRecharge(re);
				assignfilmVipCharge(re);
			}
		} catch (Exception e) {
			jsonString = "<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[updateTradeOrderPayStatus occur error.]]></return_msg></xml>";
			log.error("updateRechargeStatus occur error.{}", e, e.getMessage());
		}
		return jsonString;
	}

	@Override
	public Recharge findRecharge(String id) {
		try {
			Recharge re = rechargetDao.findRecharge(id);
			return re;
		} catch (Exception e) {
			log.error("findRecharge occur error.{}", e, e.getMessage());
		}
		return null;
	}

	@Override
	public Map<String, String> findProductById(int productId) {
		Map<String, String> map = new HashMap<String, String>();
		try {
			map = rechargetDao.findProductById(productId);
			return map;
		} catch (Exception e) {
			log.error("findRecharge occur error.{}", e, e.getMessage());
		}
		return null;
	}

	@Override
	public Recharge findRechargeByOrdId(String ordId) {
		try {
			Recharge re = rechargetDao.findRechargeByOrdId(ordId);
			return re;
		} catch (Exception e) {
			log.error("findRechargeByOrdId occur error.{}", e, e.getMessage());
		}
		return null;
	}

	@Override
	public int updateRecharge(Recharge re) {
		try {
			return rechargetDao.updateRecharge(re);
		} catch (Exception e) {
			log.error("updateRecharge occur error.{}", e, e.getMessage());
		}
		return -1;
	}

	@Override
	public int updateRecharge(Integer id, int ststus) {
		try {
			return rechargetDao.updateRecharge(id, ststus);
		} catch (Exception e) {
			log.error("updateRecharge occur error.{}", e, e.getMessage());
		}
		return -1;
	}

	@Override
	public List<Map<String, Object>> getRechargeRecode(String openId) {
		try {
			String dateTime = DateUtils.getPreMonthDates(new Date(), -3);
			String endTime  = DateUtils.getPreMonthDates(new Date(), 0);
			List<Map<String, Object>> list = rechargetDao
					.getRechareByCreateTime(openId, dateTime, endTime);
			if (list != null && list.size() > 0) {
				for (int i = 0; i < list.size(); i++) {
					Map<String, Object> map = list.get(i);
					if (map.get("createTime") != null) {
						String createTimes = map.get("createTime") + "";
						String moth        = DateUtils.formatDate(DateUtils.StrToDate(createTimes, "yyyy-MM"), "yyyy-MM");
						String nowMoth     = DateUtils.formatDate(new Date(), "yyyy-MM");
						if (moth.equals(nowMoth)) {
							map.put("weeMoth", "本月");
						} else {
							map.put("weeMoth", DateUtils.formatDate(DateUtils.StrToDate(createTimes, "yyyy-MM"), "yyyy年MM月"));
						}
						List<Map<String, Object>> recordList = rechargetDao
								.getRechareRecordList(createTimes, openId);
						if (recordList != null && recordList.size() > 0) {
							for (int j = 0; j < recordList.size(); j++) {
								Map<String, Object> recordMap = recordList
										.get(j);
								if (recordMap.get("createTime") != null) {
									String createTime = recordMap.get("createTime") + "";
									String week       = DateUtils.getWeekOfDate(DateUtils.StrToDate(createTime, "yyyy-MM-dd"));
									recordMap.put("week", week);
								}
								if (recordMap.get("carrieroperator") != null) {
									String type = recordMap.get("type") + "";
									if ("0".equals(type) || "1".equals(type)) {
										String carrieroperator = recordMap.get("carrieroperator") + "";
										recordMap.put("carrieroperator", carrieroperator.substring(carrieroperator.length() - 2, carrieroperator.length()));
									}
								}
								recordList.set(j, recordMap);
							}
						}
						map.put("recordOrderList", recordList);
					}
					list.set(i, map);
				}
			}
			return list;
		} catch (Exception e) {
			log.error("getRechargeRecode occur error.{}", e, e.getMessage());
		}
		return null;
	}

	@Override
	public Map<String, Object> getRechareRecordInfo(Integer id) {
		List<Map<String, Object>> list = rechargetDao.getRechareRecordInfo(id);
		if (list != null && list.size() > 0) {
			Map<String, Object> resultMap       = list.get(0);
			String              carrieroperator = resultMap.get("carrieroperator") + "";
			String              status          = resultMap.get("status") + "";
			resultMap.put("msg", "");
			if ("2".equals(status)) {
				resultMap.put("statusName", "充值失败");
				resultMap.put("msg", "运营商产品正在维护");
			}
			if ("1".equals(status)) {
				resultMap.put("statusName", "充值成功");
			}
			if ("0".equals(status)) {
				resultMap.put("statusName", "充值中");
			}
			String type = resultMap.get("type") + "";
			if ("0".equals(type) || "1".equals(type)) {
				carrieroperator = carrieroperator.substring(carrieroperator.length() - 2, carrieroperator.length());
				resultMap.put("carrieroperator", carrieroperator);
			}
			return resultMap;
		}
		return null;
	}

	@Override
	public Map<String, String> createOrder(Map<String, String> reqParams)
			throws Exception {
		try {
			log.info("==createOrder==");
			log.info("openId:" + reqParams.get("openId"));
			WxUser wxUser = scWxuserDao.getScWxuserByOpenId(reqParams.get("openId"));
//			AppUser appUser = appUserDao.getAppUserByOpenId(reqParams.get("developId"), reqParams.get("openId"));
			AppUser appUser = appUserDao.getAppUserByWxUserAndOrg(wxUser.getId(), wxUser.getOrganizationId());
			if (appUser != null) {
				log.info("appUser's id:" + appUser.getId());
				if (appUser.getOrganizationId() != null) {
					log.info("organizationId:" + appUser.getOrganizationId());
					reqParams.put("organizationId", appUser.getOrganizationId() + "");
				}
				if (appUser.getVirtualArchId() != null) {
					log.info("virtualArchitectureId:" + appUser.getVirtualArchId());
					reqParams.put("virtualArchitectureId", appUser.getVirtualArchId() + "");
				}
			} else {
//				WxUser wxUser=scWxuserDao.getScWxuserByOpenId(reqParams.get("openId"));
				if (wxUser != null && wxUser.getOrganizationId() != null) {
					log.info("wxUser's id:" + wxUser.getId());
					log.info("organizationId:" + wxUser.getOrganizationId());
					reqParams.put("organizationId", wxUser.getOrganizationId() + "");
				}
			}
			int result = rechargetDao.addRecharge(reqParams);
			if (result < -1) {
				reqParams = new HashMap<String, String>();
				reqParams.put("code", "-1");
				reqParams.put("msg", "系统异常，请稍后再试");
				reqParams.put("wxPayMap", "");
				return reqParams;
			}
			reqParams.put("code", "0");
			reqParams.put("rechargeId", result + "");
			WxPublicno wx = publicNoDao.getByDevelopId(reqParams.get("developId"));
			reqParams.put("appId", wx.getAppId());
			reqParams.put("subject", "subject");
			reqParams.put("palmpay", RechargeController.palmpay + "/unifiedorder");
			reqParams.put("totalFee", new BigDecimal(reqParams.get("totalFee")).multiply(new BigDecimal(100)).intValue() + "");
			String rechargePayStr = StringUtil.rechargePay(reqParams);
			if (StringUtils.isEmpty(rechargePayStr)) {
				reqParams = new HashMap<String, String>();
				reqParams.put("code", "-1");
				reqParams.put("msg", "支付失败");
				return reqParams;
			}
			JSONObject jsonObject = JSONObject.parseObject(rechargePayStr);
			if (jsonObject.getString("resultCode").equals("500")) {
				reqParams = new HashMap<String, String>();
				reqParams.put("code", "-1");
				reqParams.put("msg", jsonObject.getString("resultDesc"));
				return reqParams;
			}
			reqParams = new HashMap<String, String>();
			reqParams.put("code", jsonObject.getString("resultCode"));
			reqParams.put("rechargePayStr", JSONObject.parse(rechargePayStr).toString());
			return reqParams;
		} catch (Exception e) {
			log.error("service create order error info{}" + LogExceptionStackUtil.LogExceptionStack(e));
		}
		return null;
	}

	/**
	 * 影视会员充值业务处理
	 */
	public void assignfilmVipCharge(Recharge re) throws Exception {
		try {
			Map<String, String> map               = rechargetDao.findProductById(re.getProductId());
			ProductCategories   productCategories = servicePackDao.querProductCategoriesByServiceCode(map.get("type"));
			Map<String, String> paramMap          = new HashMap<String, String>();
			paramMap.put("ORDER_NO", re.getOutTradeNo());//订单号
			paramMap.put("BUSS_TYPE", productCategories.getServiceCode());
			paramMap.put("BUSS_TYPE_NAME", productCategories.getName());
			paramMap.put("ACCOUNT", re.getMobile());
			paramMap.put("PRODUCT_CODE", map.get("code"));
			paramMap.put("PRODUCT_NAME", map.get("productName"));
			paramMap.put("PRODUCT_AMOUNT", String.valueOf(map.get("productPrice")));
			paramMap.put("RET_URL", RechargeController.callbackVideoUrl);
			paramMap.put("QUANTITY", re.getAmount() + "");
			paramMap.put("PHONE_NO", re.getMobile());
			Map<String, String> resultMap = PhoneClient.rechargeFilmTelevision(paramMap);
			log.info("jsonStr" + net.sf.json.JSONObject.fromObject(resultMap));
			String title  = "";
			String remark = "如有问题请微信留言，小超将第一时间为您服务！";
			if ("SUCCESS".equals(resultMap.get("result"))) {
				// 调用支付成功微信通知
				title = "支付成功，请留意微信通知\\n";
				Map<String, String> templateMap = new HashMap<String, String>();
				List<Map<String, Object>> templateList = replayContentDao
						.getWxTemplate("6", 0);
				if (templateList != null) {
					String webUrl = PropertiesKit.readPropertiesValue("callbackWebUrl", "wechat.properties");
					String url    = webUrl + "/wechat/recharge/getRechareRecordInfo?id=" + re.getId() + "&developId=" + re.getDevelopId() + "&operationType=" + map.get("type") + "&openId=" + re.getOpenId() + "&channelCode=" + re.getChannelCode();
					String templateId = (String) templateList.get(0)
							.get("templateId");
					templateMap.put("templateId", templateId);
					templateMap.put("developId", re.getDevelopId());
					templateMap.put("openId", re.getOpenId());
					templateMap.put("title", title);
					templateMap.put("price", re.getPrice() + "");
					templateMap.put("productName", productCategories.getName() + "—" + map.get("productName"));
					templateMap.put("remark", remark);
					templateMap.put("url", url);
					templateMap.put("orderNo", re.getOutTradeNo());
					log.info("=========templateMap=======" + templateMap);
					weChatApiManager.sendTemplateMsg06(templateMap);
				}
			} else {
				if (null != re && !re.getStatus().equals("2")) {
					re.setRecharTime(DateUtils.formatDate(new Date()));
					re.setRechargeDesc(resultMap.get("result_desc"));
					re.setStatus("2");
					rechargetDao.updateRecharge(re);
					rechargeWebManager.updateDrawback(re.getOutTradeNo());
				}
			}
		} catch (Exception e) {
			log.error("assignfilmVipCharge occur error." + LogExceptionStackUtil.LogExceptionStack(e));
		}
	}

	/**
	 * 加油卡充值业务处理
	 */
	public void assignfuelCardCharge(Recharge re) throws Exception {
		try {
			Map<String, String> map               = rechargetDao.findProductById(re.getProductId());
			ProductCategories   productCategories = servicePackDao.querProductCategoriesByServiceCode(map.get("type"));
			Map<String, String> paramMap          = new HashMap<String, String>();
			paramMap.put("ORDER_NO", re.getOutTradeNo());    //订单号
			paramMap.put("CARD_TYPE", productCategories.getServiceCode());
			paramMap.put("CARD_TYPE_NAME", productCategories.getName());
			paramMap.put("CARD_CODE", re.getMobile());
			paramMap.put("PHONE_NO", "15019433985");
			paramMap.put("QUANTITY", "1");
			paramMap.put("RECHARGE_AMOUNT", map.get("code"));
			paramMap.put("RET_URL", RechargeController.callbackVideoUrl);
			Map<String, String> resultMap = PhoneClient.rechargeFuelCard(paramMap);

			log.info("jsonStr" + net.sf.json.JSONObject.fromObject(resultMap));
			String title  = "";
			String remark = "如有问题请微信留言，小超将第一时间为您服务！";
			if ("SUCCESS".equals(resultMap.get("result"))) {
				// 调用支付成功微信通知
				title = "支付成功，请留意微信通知\\n";
				Map<String, String>       templateMap  = new HashMap<String, String>();
				List<Map<String, Object>> templateList = replayContentDao.getWxTemplate("6", 0);
				if (templateList != null) {
					String webUrl = PropertiesKit.readPropertiesValue("callbackWebUrl", "wechat.properties");
					String url    = webUrl + "/wechat/recharge/getRechareRecordInfo?id=" + re.getId() + "&developId=" + re.getDevelopId() + "&operationType=" + map.get("type") + "&openId=" + re.getOpenId() + "&channelCode=" + re.getChannelCode();
					String templateId = (String) templateList.get(0)
							.get("templateId");
					templateMap.put("templateId", templateId);
					templateMap.put("developId", re.getDevelopId());
					templateMap.put("openId", re.getOpenId());
					templateMap.put("title", title);
					templateMap.put("price", re.getPrice() + "");
					templateMap.put("productName", productCategories.getName() + "—" + map.get("productName"));
					templateMap.put("remark", remark);
					templateMap.put("url", url);
					templateMap.put("orderNo", re.getOutTradeNo());
					log.info("=========templateMap=======" + templateMap);
					weChatApiManager.sendTemplateMsg06(templateMap);
				}
			} else {
				if (null != re && !re.getStatus().equals("2")) {
					re.setRecharTime(DateUtils.formatDate(new Date()));
					re.setRechargeDesc(resultMap.get("result_desc"));
					re.setStatus("2");
					rechargetDao.updateRecharge(re);
					rechargeWebManager.updateDrawback(re.getOutTradeNo());
				}
			}
		} catch (Exception e) {
			log.error("assignfuelCardCharge occur error." + LogExceptionStackUtil.LogExceptionStack(e));
		}
	}

	@Override
	public void assignRecoveryRecharge(String month) {
		log.info("==assignRecoveryRecharge==");
		List<Recharge> rechargeList = rechargetDao.getNoOrgRechargeList(month);
		if (!CollectionUtils.isEmpty(rechargeList)) {
			for (Recharge recharge : rechargeList) {
				WxUser wxUser = scWxuserDao.getScWxuserByOpenId(recharge.getOpenId());
				if (wxUser != null && wxUser.getOrganizationId() != null) {
					log.info("update recharge's id:" + recharge.getId() + ";organizationId:" + wxUser.getOrganizationId());
					recharge.setOrganizationId(wxUser.getOrganizationId().toString());
					rechargetDao.updateObj(recharge);
				}
			}
		}
	}

}
