package com.palmnest.service.estateserve.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.ui.ModelMap;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.palmnest.application.Constants;
import com.palmnest.application.ElementConstant;
import com.palmnest.application.bean.Pagenation;
import com.palmnest.application.core.util.DateUtils;
import com.palmnest.application.core.util.HttpKit;
import com.palmnest.application.core.util.LogExceptionStackUtil;
import com.palmnest.application.core.util.PropertiesKit;
import com.palmnest.application.core.util.StringUtil;
import com.palmnest.dao.estateserve.RechargeWebDao;
import com.palmnest.dao.estateserve.ServicePackDao;
import com.palmnest.dao.wechat.RechargeDao;
import com.palmnest.dao.wechat.ReplayContentDao;
import com.palmnest.model.estateserve.Product;
import com.palmnest.model.estateserve.ProductCategories;
import com.palmnest.model.estateserve.Recharge;
import com.palmnest.model.estateserve.WxPublicno;
import com.palmnest.service.AsynchronousDataService;
import com.palmnest.service.estateserve.PublicNoManager;
import com.palmnest.service.estateserve.RechargeWebManager;
import com.palmnest.service.impl.GenericManagerImpl;
import com.palmnest.service.wechat.RechargeManager;
import com.palmnest.service.wechat.WeChatApiManager;

/**
 * 充值后台管理业务实现类
 *
 * @author xiemin
 * @date 2017-06-15
 */
@Component("rechargeWebManager")
public class RechargeWebManagerImpl extends GenericManagerImpl<Recharge, Integer> implements RechargeWebManager {

	private static Logger LOG = LoggerFactory.getLogger(RechargeWebManagerImpl.class);

	@Autowired
	private RechargeWebDao          rechargetWebDao;
	@Autowired
	private RechargeDao             rechargetDao;
	@Autowired
	private RechargeManager         rechargeManager;
	@Autowired
	private AsynchronousDataService asynchronousWorkService;
	@Autowired
	private ReplayContentDao        replayContentDao;
	@Autowired
	private WeChatApiManager        weChatApiManager;
	@Autowired
	private PublicNoManager         publicNoManager;
	@Autowired
	private ServicePackDao          servicePackDao;

	public static String webUrl     = PropertiesKit.readPropertiesValue("webUrl", "wechat.properties");
	public static String palmpay    = PropertiesKit.readPropertiesValue("palmpay", "wechat.properties");
	public static String checkPrice = PropertiesKit.readPropertiesValue("checkPrice", "phone_config.properties");

	/**
	 * 充值返回url
	 */
	public static String callbackUrl = webUrl + "/wechat/recharge/callbackUrl";
	/**
	 * 支付api的密钥
	 */
	public static String appKey      = PropertiesKit.readPropertiesValue("ClientAppKey", "wechat.properties");

	@Override
	public Pagenation<Map<String, String>> queryRechargeList(ModelMap modelMap) {
		try {
			return rechargetWebDao.queryRechargeList(modelMap);
		} catch (Exception e) {
			LOG.error("queryRechargeList occur error." + LogExceptionStackUtil.LogExceptionStack(e));
		}
		return null;
	}

	@Override
	public Pagenation<Map<String, String>> queryProductList(ModelMap modelMap) {
		try {
			modelMap.put("pageSize", "10");
			return rechargetWebDao.queryProductList(modelMap);
		} catch (Exception e) {
			LOG.error("queryProductList occur error." + LogExceptionStackUtil.LogExceptionStack(e));
		}
		return null;
	}

	@Override
	@Transactional(propagation = Propagation.REQUIRED)
	public JSONObject importProduct(List<Map<String, String>> list, String userName) {
		JSONObject json = new JSONObject();
		int row = 1;
		int col = 1;
		try {
			if (null == list || list.size() <= 0) {
				json.put("code", -1);
				json.put("msg", "上传失败，请检查数据");
				return json;
			}
			for (Map<String, String> map : list) {
				row++;
				Product pro = new Product();
				Set<Map.Entry<String, String>> entry = map.entrySet();
				// 通过迭代器取出map中的键值关系，迭代器接收的泛型参数应和Set接收的一致
				Iterator<Map.Entry<String, String>> it = entry.iterator();
				while (it.hasNext()) {
					// 将键值关系取出存入Map.Entry这个映射关系集合接口中
					Map.Entry<String, String> me = it.next();
					// 使用Map.Entry中的方法获取键和值
					String key = me.getKey();
					String value = me.getValue();
					if (key.equals("var1")) {
						col = 2;
						pro.setCarrieroperator(value);
						if (!value.equals("全国")) {
							pro.setProvince(value.substring(0, value.length() - 2));
						} else {
							pro.setProvince(value);
						}
					}
					if (key.equals("var2")) {//产品
						col = 3;
						pro.setProductName(value);
					}
					if (key.equals("var3")) {//产品价格
						col = 4;
						pro.setProductPrice(BigDecimal.valueOf(Double.valueOf(value)));
					}
					if (key.equals("var4")) {//折扣
						col = 5;
						if (null == value || value.equals("")) {
							value = "0";
						}
						pro.setDiscount(BigDecimal.valueOf(Double.valueOf(value)));
					}
					if (key.equals("var5")) {//上浮折扣
						col = 6;
						if (null == value || value.equals("")) {
							value = "0";
						}
						pro.setUpDiscount(BigDecimal.valueOf(Double.valueOf(value)));
					}
					if (key.equals("var6")) {//限价折扣
						col = 7;
						if (null == value || value.equals("")) {
							value = "0";
						}
						//是否是数字
						Pattern pattern = Pattern.compile("^-?(?:\\d+|\\d{1,3}(?:,\\d{3})+)(?:\\.\\d+)?$");
						Matcher m = pattern.matcher(value);
						if (m.matches()) {
							pro.setCheckPrice(BigDecimal.valueOf(Double.valueOf(value)));
						} else {
							pro.setCheckPrice(BigDecimal.valueOf(0));
						}
					}
					if (key.equals("var9")) {//编码
						col = 10;
						pro.setCode(value);
					}
					if (key.equals("var11")) {
						col = 12;
						pro.setType(value);
					}
					if (key.equals("var12")) {
						col = 13;
						if (value.contains("维护")) {
							pro.setIsEnabled(ElementConstant.YESORNO_0);
						} else {
							pro.setIsEnabled(ElementConstant.YESORNO_1);
						}
					}

				}

				pro.setCreateTime(DateUtils.getDate(DateUtils.YYYY_MM_DD_MM_HH_SS));
				pro.setCreator(userName);
				BigDecimal discount = pro.getUpDiscount().add(pro.getDiscount());

				if (checkPrice.equals("on")) {
					if (discount.compareTo(pro.getCheckPrice()) == -1 && (pro.getCheckPrice().equals("1") || pro.getCheckPrice().equals("1.00"))) {
						json.put("code", -1);
						json.put("msg", "上传失败，第" + row + "行，第6列上浮折扣+供货折扣低于运营商限价");
						return json;
					}
				}
				BigDecimal realPrice = pro.getProductPrice().multiply(discount);
				pro.setRealPrice(realPrice);
				rechargetWebDao.addProduct(pro);
			}
			json.put("code", 0);
			json.put("msg", "上传成功");
			return json;
		} catch (Exception e) {
			json.put("code", -1);
			json.put("msg", "上传失败，第" + row + "行，第" + col + "列数据异常");
			LOG.error("importProduct occur error." + LogExceptionStackUtil.LogExceptionStack(e));
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
		}
		return json;
	}

	@Override
	public JSONObject updaterecharge(String type, String ids) {
		JSONObject json = new JSONObject();
		if (StringUtils.isEmpty(ids)) {
			json.put("code", -1);
			json.put("msg", "请选择订单号再试");
			return null;
		}
		try {
			String idArray[] = ids.toString().split(",");
			for (String id : idArray) {
				//查询充值订单号是否存在，存在则直接
				Recharge re = rechargetDao.findRechargeByOrdId(id);
				if (null == re) {
					json.put("code", -1);
					json.put("msg", "充值订单不存在，请稍后再试");
					return json;
				}
				if (re.getType().equals("1")) {
					json = updateRechargePhone(re.getId());
//					return json;
					continue;
				}
				String productId = re.getProductId() + "";

				//根据订单号查询充值信息
				String jsonStr = StringUtil.getRecharge(re.getOutTradeNo(), "1");
				JSONObject jsonObject = JSON.parseObject(StringUtil.xmlToJSON(jsonStr));
				if (null == jsonObject) {
					json.put("code", -1);
					json.put("msg", "充值订单不存在，请稍后再试");
					return json;
				}
				JSONObject bodyJson = jsonObject.getJSONObject("body");
				JSONObject resultJson = bodyJson.getJSONObject("result");
				if (!resultJson.getString("rechargeStatus").equals("0")) {
					json.put("code", -1);
					json.put("msg", resultJson.getString("rechargeDesc"));
					return json;
				}
				//充值成功
				if (resultJson.getString("rechargeStatu").equals("0")) {
					int result = rechargetDao.updateRecharge(re.getId(), 1);
					if (result > 0) {
						json.put("code", -1);
						json.put("msg", "操作失败");
						return json;
					}
					json.put("code", 0);
					json.put("msg", "操作成功");
					return json;
				}
				//充值中
				if (json.getString("rechargeStatu").equals("2") && !re.getStatus().equals("0") && re.getPayStatus().equals("0")) {
					int result = rechargetDao.updateRecharge(re.getId(), 0);
					if (result < 0) {
						json.put("code", 0);
						json.put("msg", "充值中，请稍后，系统更新状态失败，请重试");
						return json;
					}
					json.put("code", 0);
					json.put("msg", "充值中，请稍后");
					return json;
				}
				//充值中
				if (json.getString("rechargeStatu").equals("2") && re.getStatus().equals("0") && re.getPayStatus().equals("0")) {
					json.put("code", 0);
					json.put("msg", "充值中，请稍后");
					return json;
				}
				//20分钟订单不存在,再进行充值
				if (json.getString("rechargeStatu").equals("3") && DateUtils.calculateTime(json.getString("time"), DateUtils.formatDate(new Date())) > 25) {
					//根据产品id查询产品信息
					Map<String, String> mapPt = rechargetDao.findProductById(Integer.valueOf(productId));
					if (null != mapPt && null != re) {
						String timestamp = DateUtils.getTime(new Date(), "");
						StringBuffer sbf = new StringBuffer();

						String timestamps = DateUtils.getTime(new Date(), "");
						String sign = StringUtil.commonParameters(timestamps);
						String body = sbf.append("<body><message><flow>").append(mapPt.get("productName")).append("</flow><order><mobile>")
								.append(re.getMobile()).append("</mobile><orderid>").append(re.getId()).append("</orderid></order></message></body>").toString();
						LOG.info("===body====" + body);
						Map<String, String> map = new HashMap<String, String>();
						map.put("name", Constants.NAME);
						map.put("timestamp", timestamp);
						map.put("sign", sign);
						map.put("version", Constants.VERSION);
						map.put("body", body);
						map.put("callbackUrl", callbackUrl);
						json = new JSONObject();
						String jsonS = HttpKit.httpRecharge(Constants.ASK_URL + "Order", map, Constants.POST);
						json = JSON.parseObject(StringUtil.xmlToJSON(jsonS));
						jsonObject = new JSONObject();
						jsonObject = json.getJSONObject("result");
						json.put("code", jsonObject.getString("code"));
						json.put("msg", jsonObject.getString("message"));
					}
					return json;
				}
			}
		} catch (Exception e) {
			LOG.error("importProduct occur error." + LogExceptionStackUtil.LogExceptionStack(e));
			json.put("code", -1);
			json.put("msg", "操作失败");
			return json;
		}
		json.put("code", 0);
		json.put("msg", "操作成功");
		return json;
	}

	@Override
	public JSONObject updateDrawback(String ids) {
		JSONObject json = new JSONObject();
		Map<String, String> map = new HashMap<String, String>();
		if (StringUtils.isEmpty(ids)) {
			json.put("code", "-1");
			json.put("msg", "请选择需要退款的订单");
			return json;
		}
		String timeStamp = DateUtils.getTime("");
		//api接口参数
		map.put("timeStamp", timeStamp);
		map.put("IMEI", "0");
		map.put("SIGN", StringUtil.getSgin("0", appKey, timeStamp));

		//退款接口参数
		map.put("payWay", "wxpay");
		map.put("outRefundNo", timeStamp);//商户退款单号
		map.put("outTradeNo", "");//微信订单号outTradeNo和tradeNo二选一
		try {
			String idArray[] = ids.toString().split(",");
			for (String id : idArray) {
				Recharge re = rechargetDao.findRechargeByOrdId(id);
				if (re == null) {
					json.put("code", "-1");
					json.put("msg", "充值订单号：" + id + "不存在，请查证后再试");
					return json;
				}
				if (re.getStatus().equals("0") && !re.getType().equals("1")) {
					json.put("code", "-1");
					json.put("msg", "充值订单号：" + id + "正在充值中，请稍后再退款");
					return json;
				}
				String refPrice = re.getPrice() + "";
				WxPublicno wx = publicNoManager.getByDevelopId(re.getDevelopId());
				map.put("appId", wx.getAppId());//APPID
				map.put("tradeNo", re.getTransactionId());//微信支付订单号，微信返回
				String price = re.getPrice().multiply(BigDecimal.valueOf(100)) + "";
				price = price.substring(0, price.indexOf("."));
				map.put("refundFee", price);//支付金额
				LOG.info("==退款金额==" + price);
				String jsonStr = HttpKit.httpRecharge(palmpay + "/refund", map, "POST");
				if (StringUtils.isEmpty(jsonStr)) {
					json.put("code", "-1");
					json.put("msg", "系统异常，退款失败");
					return json;
				}
				json = JSON.parseObject(jsonStr);
				if (json.getString("resultCode").equals("200")) {
					re.setOutRefundNo(timeStamp);
					re.setRefundStatus("1");
					re.setStatus("2");//退款成功，充值失败
					re.setRefundTime(DateUtils.formatDate(new Date()));
					rechargetDao.updateRecharge(re);

//    				Product pr = rechargeManager.findProductById(re.getProductId());
					String openId = re.getOpenId();
					String title = "您好，由于运营商优惠资格限制，您的话费充值未成功，非常抱歉！将为您原路退款，银行处理预计1个工作日内到账。";
					String refund = refPrice + "元";
					String reason = "话费充值失败";
					String remark = "如有问题请微信留言，小超将第一时间为您服务！";
					if (re.getType().equals("0")) {
						reason = "流量充值失败";
						title = "您好，由于网络异常，您的流量充值未成功，请稍后重试，非常抱歉！本次支付金额将为您原路退款，银行处理预计1个工作日内到账。";
					}
					Map<String, String> mapPt = new HashMap<String, String>();
					if (!re.getType().equals("0") && !re.getType().equals("1")) {
						ProductCategories productCategories = servicePackDao.querProductCategoriesByServiceCode(re.getType());
						mapPt = rechargetDao.findProductById(re.getProductId());
						title = "您好，由于网络异常，您的" + productCategories.getName() + "-" + mapPt.get("productName") + "未充值成功，请稍后重试，非常抱歉！本次支付金额将为您原路退款，银行处理预计1个工作日内到账。";
						reason = productCategories.getName() + "-" + mapPt.get("productName") + "充值失败";
					}
					Map<String, String> paramMap = new HashMap<String, String>();
					List<Map<String, Object>> templateList = replayContentDao.getWxTemplate("8", 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", re.getDevelopId());
						paramMap.put("openId", openId);
						paramMap.put("reason", reason);
						paramMap.put("price", refund);
						paramMap.put("title", title);
						paramMap.put("url", url);
						paramMap.put("remark", remark);
						weChatApiManager.sendTemplateMsg08(paramMap);
					}
					json.put("code", "-1");
					json.put("msg", "退款成功");
					return json;
				}
				//多次退款
				if (json.getString("resultCode").equals("ERROR")) {
					re.setOutRefundNo(timeStamp);
					re.setRefundStatus("1");
					re.setStatus("2");//退款成功，充值失败
					re.setRefundTime(DateUtils.formatDate(new Date()));
					rechargetDao.updateRecharge(re);
					json.put("code", "-1");
					json.put("msg", json.getString("resultDesc"));
					return json;
				}
				if (json.getString("resultCode") == "505") {
					re.setOutRefundNo(timeStamp);
					re.setRefundStatus("2");
					rechargetDao.updateRecharge(re);
					json.put("code", "-1");
					json.put("msg", "系统异常");
					return json;
				}
			}

		} catch (Exception e) {
			LOG.error("drawback occur error." + LogExceptionStackUtil.LogExceptionStack(e));
			json.put("code", "-1");
			json.put("msg", "系统异常");
			return json;
		}
		return json;
	}

	@Override
	public JSONObject updateRechargePhone(int id) {
		JSONObject json = new JSONObject();
		try {
			Recharge re = rechargeManager.findRecharge(id + "");
//			int result = rechargetDao.updateRecharge(id,1);
			re.setRecharTime(DateUtils.formatDate(new Date()));
			re.setStatus("1");
			int result = rechargetDao.updateRecharge(re);
			if (result < 0) {
				json.put("code", -1);
				json.put("msg", "操作失败");
				return json;
			}
			json.put("code", 0);
			json.put("msg", "操作成功");

			Map<String, String> map = rechargeManager.findProductById(re.getProductId());

			String openId = re.getOpenId();
			String title = "您的话费已充值成功，请留意到账短信通知";
			String price = String.valueOf(map.get("productPrice")) + "元";
			String remark = "如有问题请微信留言，小超将第一时间为您服务！";
			// 调用支付成功微信通知
			Map<String, String> paramMap = new HashMap<String, String>();
			List<Map<String, Object>> templateList = replayContentDao
					.getWxTemplate("7", 0);
			if (templateList != null && templateList.size() > 0) {
				String webUrl = PropertiesKit.readPropertiesValue("callbackWebUrl", "wechat.properties");
				String url = webUrl + "/wechat/recharge/getRechareRecordInfo?id=" + id + "&developId=" + re.getDevelopId() + "&operationType=1&oepnId=" + re.getOpenId();
				String templateId = (String) templateList.get(0).get("templateId");
				title += "手机号码:" + re.getMobile() + "\\n";
				paramMap.put("developId", re.getDevelopId());
				paramMap.put("templateId", templateId);
				paramMap.put("openId", openId);
				paramMap.put("url", url);
				paramMap.put("title", title);
				paramMap.put("mobile", re.getMobile());
				paramMap.put("price", price);
				paramMap.put("statusName", "话费");
				paramMap.put("remark", remark);
				paramMap.put("createTime", re.getRecharTime());
				weChatApiManager.sendTemplateMsg07(paramMap);
			}
			return json;

		} catch (Exception e) {
			json.put("code", -1);
			json.put("msg", "操作失败");
		}
		return json;
	}

	@Override
	@Transactional(propagation = Propagation.REQUIRED)
	public JSONObject updateProduct(Map<String, String> map) {
		List<Product> list = new ArrayList<Product>();
		JSONObject json = new JSONObject();
		try {
			//全部
			if (map.get("all").equals("1")) {
				if (map.get("type").equals("0") || map.get("type").equals("1")) {
					Map<String, String> mapPt = rechargeManager.findProductById(Integer.valueOf(map.get("id")));
					if (!map.get("carrieroperator").equals("-1") && !mapPt.get("carrieroperator").contains(map.get("carrieroperator"))) {
						json.put("code", -1);
						json.put("msg", "此省份的产品不包含：" + map.get("carrieroperator") + "运营商，请重新选择");
						return json;
					}
					String carrieroperator = "";
					if (map.get("carrieroperator").equals("-1")) {
						carrieroperator = mapPt.get("carrieroperator").substring(0, mapPt.get("carrieroperator").length() - 2);
					} else {
						carrieroperator = mapPt.get("carrieroperator");
					}
					//全部产品
					list = rechargeManager.findProduct(mapPt.get("province"), carrieroperator, mapPt.get("type"), "");
					for (Product p : list) {
						BigDecimal upDiscount = new BigDecimal(String.valueOf(map.get("upDiscount")));
						BigDecimal discount = new BigDecimal(String.valueOf(map.get("discount")));
						BigDecimal checkPrice = upDiscount.add(discount);

						if (checkPrice.equals("on")) {
							if (checkPrice.compareTo(p.getCheckPrice()) == -1 && (p.getCheckPrice().equals("1") || p.getCheckPrice().equals("1.00"))) {
								json.put("code", -1);
								json.put("msg", "上浮折扣+供货折扣低于运营商限价");
								return json;
							}
						}
						map.put("productPrice", p.getProductPrice() + "");
						map.put("id", p.getId() + "");
						int result = rechargetWebDao.updateProduct(map);
						if (result < 0) {
							json.put("code", 0);
							json.put("msg", "产品为：" + p.getProductName() + "操作失败");
							return json;
						}
					}
					json.put("code", 0);
					json.put("msg", "操作成功");
					return json;
				} else {
					//产品类型：type:2,type:3,province业务编码
					List<Map<String, String>> listMap = rechargetWebDao.findProduct(map.get("province"), map.get("type"));
					for (Map<String, String> maps : listMap) {
						BigDecimal upDiscount = new BigDecimal(String.valueOf(map.get("upDiscount")));
						BigDecimal discount = new BigDecimal(String.valueOf(map.get("discount")));
						BigDecimal checkPrice = upDiscount.add(discount);
						BigDecimal checkPrice_ = new BigDecimal(String.valueOf(maps.get("checkPrice")));

						if (checkPrice.equals("on")) {
							if (checkPrice.compareTo(checkPrice_) == -1 && (checkPrice_.equals("1") || checkPrice_.equals("1.00"))) {
								json.put("code", -1);
								json.put("msg", "上浮折扣+供货折扣低于运营商限价");
								return json;
							}
						}
						map.put("productPrice", String.valueOf(maps.get("productPrice")));
						map.put("id", String.valueOf(maps.get("id")));
						int result = rechargetWebDao.updateProduct(map);
						if (result < 0) {
							json.put("code", 0);
							json.put("msg", "产品编码为：" + map.get("code") + "操作失败");
							return json;
						}
					}
				}
				json.put("code", 0);
				json.put("msg", "操作成功");
				return json;
			} else {//单个
				int result = rechargetWebDao.updateProduct(map);
				if (result < 0) {
					json.put("code", -1);
					json.put("msg", "系统异常，操作失败");
					return json;
				}
				json.put("code", 0);
				json.put("msg", "操作成功");
				return json;
			}
		} catch (Exception e) {
			LOG.error("updateProduct occur error.{}", e, e.getMessage());
			json.put("code", -1);
			json.put("msg", "系统异常，更新失败");
		}
		return json;
	}

	@Override
	public JSONObject updateAvailable(Map<String, String> map) {
		JSONObject json = new JSONObject();
		try {
			int result = rechargetWebDao.updateAvailable(map);
			if (result < 0) {
				json.put("code", -1);
				json.put("msg", "系统异常，操作失败");
				return json;
			}
			json.put("code", 0);
			json.put("msg", "操作成功");
			return json;
		} catch (Exception e) {
			LOG.error("updateAvailable occur error.{}", e, e.getMessage());
			json.put("code", -1);
			json.put("msg", "系统异常，更新失败");
		}
		return json;
	}

	public static void main(String[] args) {
		BigDecimal di = new BigDecimal(0.15);
		BigDecimal d2 = new BigDecimal(0.51);
		BigDecimal d3 = new BigDecimal(180);
		System.out.println(d3.multiply(di.add(d2)).doubleValue());
	}

}
