package com.palmnest.service.wechat.impl;

import com.palmnest.application.WxPayConstant;
import com.palmnest.application.core.util.wxpay.HttpUtil;
import com.palmnest.application.core.util.wxpay.PayUtils;
import com.palmnest.application.dto.output.wechat.MerchantDetailDto;
import com.palmnest.model.wxpay.MerchantDetail;
import com.palmnest.model.wxpay.PaySendData;
import com.palmnest.service.wechat.MerchantDetailManager;
import com.palmnest.service.wechat.PayService;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.lang.reflect.Field;
import java.util.*;


@Service("payService")
public class PayServiceImpl implements PayService {

	@Autowired
	private MerchantDetailManager merchantDetailManager;

	/**
	 * 获取对应的商户信息
	 */
	public List<MerchantDetailDto> findBy(Map<String, String> params) {

		List<MerchantDetailDto> dtos = new ArrayList<MerchantDetailDto>();

		List<MerchantDetail> details = merchantDetailManager.findBy(params);

		for (MerchantDetail detail : details) {
			dtos.add(new MerchantDetailDto(detail.getId(), detail.getOrgId(), detail.getModuleCode(),
					detail.getName(), detail.getAppId(), detail.getAppSecret(), detail.getMchId(),
					detail.getWxApiKey(), detail.getSslcertPath(), detail.getSslcertPassword()));
		}

		return dtos;
	}

	/**
	 * 微信支付统一下单
	 **/
	public String unifiedOrder(PaySendData paySendData) {

		Map<String, String> resultMap = null;
		// 统一下单返回的预支付id
		String prepayId = null;
		System.out.println("sign:" + paySendData.getSign());
		// 将请求参数对象转换成xml
		String reqXml = PayUtils.sendDataToXml(paySendData);
		System.out.println("xml:" + reqXml);
		try {
			// 发送请求
			CloseableHttpResponse response = HttpUtil.Post(WxPayConstant.UNIFIED_ORDER_URL, reqXml, false);
			try {
				resultMap = PayUtils.parseXml(response.getEntity().getContent());
				// 关闭流
				EntityUtils.consume(response.getEntity());
			} finally {
				response.close();
			}
		} catch (Exception e) {
			System.out.println("微信支付统一下单异常：");
			e.printStackTrace();
		}
		String return_code = resultMap.get("return_code");
		String result_code = resultMap.get("result_code");
		String return_msg  = resultMap.get("return_msg");
		System.out.println("return_code:" + return_code);
		System.out.println("result_code:" + result_code);
		System.out.println("return_msg:" + return_msg);
		if (WxPayConstant.RETURN_SUCCESS.equals(return_code) && WxPayConstant.RETURN_SUCCESS.equals(result_code)) {
			// return_code=通信标识
			// result_code=交易标识
			// 只有当returnCode与resultCode均返回“success”，才代表微信支付统一下单成功
			prepayId = "prepay_id=" + resultMap.get("prepay_id");
		}
		return prepayId;
	}

	public String refund() {
		PaySendData paySendData = new PaySendData();
		// 构建微信支付请求参数集合
		paySendData.setAppId(WxPayConstant.APP_ID);
		paySendData.setMch_id(WxPayConstant.MCH_ID);
		paySendData.setNonce_str(PayUtils.getRandomStr(32));
		// paySendData.setTransaction_id(WeChatUtils.getRandomStr(32));
		// Out_trade_no与Transaction_id二选一
		paySendData.setOut_trade_no("jtVFcgbM");
		paySendData.setOut_refund_no("jtVFcgbM");
		paySendData.setTotal_fee(1);
		paySendData.setRefund_fee(1);
		paySendData.setOp_user_id(WxPayConstant.MCH_ID);
		// 将参数拼成map,生产签名
		paySendData.setSign(PayUtils.getSign(buildParamMap(paySendData)));
		// 将请求参数对象转换成xml
		String reqXml = PayUtils.sendDataToXml(paySendData);
		try {
			// 发送请求
			CloseableHttpResponse response = HttpUtil.Post(WxPayConstant.UNIFIED_ORDER_URL, reqXml, true);
			try {
				// 关闭流
				EntityUtils.consume(response.getEntity());
			} finally {
				response.close();
			}
		} catch (Exception e) {
			System.out.println("微信退款异常");
		}
		return null;
	}

	/**
	 * 构建统一下单参数map 用于生成签名
	 *
	 * @param data
	 * @return SortedMap<String, Object>
	 */
	private SortedMap<String, Object> buildParamMap(PaySendData data) {
		SortedMap<String, Object> paramters = new TreeMap<String, Object>();
		Field[]                   fields    = data.getClass().getDeclaredFields();
		try {
			for (Field field : fields) {
				field.setAccessible(true);
				if (null != field.get(data)) {
					paramters.put(field.getName().toLowerCase(), field.get(data).toString());
				}
			}
		} catch (Exception e) {
			System.out.print("构建签名map错误: ");
			e.printStackTrace();
		}

		return paramters;
	}

}
