package com.cweb.controller;

import com.alibaba.fastjson.JSONObject;
import com.cweb.config.SysConst;
import com.hfkj.channel.weixin.entity.WeChatPayReqInfo;
import com.hfkj.channel.weixin.utils.IOUtil;
import com.hfkj.channel.weixin.utils.MD5Util;
import com.hfkj.channel.weixin.utils.WechatPayUtil;
import com.hfkj.channel.weixin.utils.XmlUtil;
import com.hfkj.common.WeChatMerNo;
import com.hfkj.common.exception.ErrorCode;
import com.hfkj.common.exception.ErrorHelp;
import com.hfkj.common.exception.SysCode;
import com.hfkj.common.security.UserCenter;
import com.hfkj.common.utils.MathUtils;
import com.hfkj.common.utils.ResponseMsgUtil;
import com.hfkj.config.CommonSysConfig;
import com.hfkj.config.CommonSysConst;
import com.hfkj.entity.BsDeviceOrder;
import com.hfkj.entity.BsTradeOrder;
import com.hfkj.entity.BsTradeOrderMsg;
import com.hfkj.model.ResponseData;
import com.hfkj.model.UserInfoModel;
import com.hfkj.service.BsDeviceOrderService;
import com.hfkj.service.BsDeviceService;
import com.hfkj.sysenum.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedOutputStream;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.SortedMap;
import java.util.concurrent.ThreadLocalRandom;

@Controller
@Api(value = "设备管理")
@RequestMapping(value = "/deviceOrderPay")
public class BsDeviceOrderPayController {

    private static Logger log = LoggerFactory.getLogger(BsDeviceOrderPayController.class);

    @Resource
    private BsDeviceOrderService deviceOrderService;

    @Resource
    private WechatPayUtil wechatPayUtil;

    @Resource
    private UserCenter userCenter;

    @RequestMapping(value="/payOrder",method = RequestMethod.POST)
    @ResponseBody
    @ApiOperation(value = "支付订单")
    public ResponseData payOrder(@RequestBody JSONObject body) {
        try {
            UserInfoModel userInfoModel = userCenter.getSessionModel(UserInfoModel.class);
            if (userInfoModel.getStore() == null) {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMPETENCE_INSUFFICIENT, "");
            }
            if (StringUtils.isBlank(body.getString("orderNo"))
                    || StringUtils.isBlank(body.getString("openId"))) {
                log.error("BsDeviceOrderPayController -> payOrder error!","参数校验失败");
                throw ErrorHelp.genException(SysCode.System, ErrorCode.REQ_PARAMS_ERROR, "");
            }
            Integer openIdType = body.getInteger("openIdType");

            // 设备订单
            BsDeviceOrder order = deviceOrderService.getDetailOrder(body.getString("orderNo"));
            if (order == null) {
                log.error("BsDeviceOrderPayController -> payOrder error!","未知的订单号");
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未知的订单号");
            }
            if (!order.getStatus().equals(DeviceOrderStatusEnum.status1.getNumber())) {
                log.error("BsDeviceOrderPayController -> payOrder error!","订单不处于待支付状态");
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "订单不处于待支付状态");
            }

            Map<String,Object> map = new HashMap<>();
            map.put("orderNo", order.getOrderNo());
            map.put("payPrice", order.getPayPrice());
            map.put("body", DeviceTypeEnum.getDataByNumber(order.getDeviceType()).getName());
            map.put("subject", DeviceTypeEnum.getDataByNumber(order.getDeviceType()).getName());

            // 微信支付
            String nonce_str = MD5Util.MD5Encode(String.valueOf(ThreadLocalRandom.current().nextInt(10000)), "UTF-8");
            int total_fee = MathUtils.objectConvertBigDecimal(map.get("payPrice")).multiply(new BigDecimal("100")).intValue();
            WeChatPayReqInfo weChatPayReqInfo = new WeChatPayReqInfo();
            weChatPayReqInfo.setAppid(SysConst.getSysConfig().getWxMchAppId());                                // 公众号id
            weChatPayReqInfo.setMch_id(SysConst.getSysConfig().getWxMchId());                               // 商户号
            if (openIdType == null || openIdType.equals(1)) {
                weChatPayReqInfo.setSub_appid("wxa075e8509802f826"); // 商户号公众号
            } else {
                // weChatPayReqInfo.setSub_appid(SysConst.getSysConfig().getWxSubAppId());//商户号
            }
            //子商户号
            weChatPayReqInfo.setSub_mch_id(WeChatMerNo.MCH_ID_1614670195);
            // weChatPayReqInfo.setOpenid(openId);
            weChatPayReqInfo.setSub_openid(body.getString("openId"));
            weChatPayReqInfo.setNonce_str(nonce_str);                                                     // 随机字符串
            weChatPayReqInfo.setBody(map.get("body").toString());                                         // 商品描述
            weChatPayReqInfo.setOut_trade_no(map.get("orderNo").toString());                			  // 商户订单号
            weChatPayReqInfo.setTotal_fee(total_fee);                                                     // 总金额
            weChatPayReqInfo.setSpbill_create_ip("122.9.135.148");                                        // 终端ip
            weChatPayReqInfo.setNotify_url(CommonSysConst.getSysConfig().getDomainName()+"/crest/deviceOrderPay/orderNotify");                       // 通知url
            weChatPayReqInfo.setTrade_type("JSAPI");                                                      // 交易类型
            weChatPayReqInfo.setProfit_sharing("N");

            //附加数据，区分订单类型
            Map<String,String> payMap = new HashMap<>();
            payMap.put("app_id", weChatPayReqInfo.getSub_appid());
            payMap.put("api_key",SysConst.getSysConfig().getWxApiKey());
            payMap.put("unified_order_url",SysConst.getSysConfig().getWxUnifiedOrderUrl());
            SortedMap<Object, Object> sortedMap = wechatPayUtil.goWechatPay(weChatPayReqInfo,payMap);

            order.setEntryPlatformMerNo(weChatPayReqInfo.getSub_mch_id());
            deviceOrderService.editData(order);
            return ResponseMsgUtil.success(sortedMap);

        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return ResponseMsgUtil.exception(e);
        }
    }

    @RequestMapping(value="/orderNotify",method = RequestMethod.POST)
    @ResponseBody
    @ApiOperation(value = "订单通知")
    public void orderNotify(HttpServletRequest request, HttpServletResponse response) {
        try {
            log.info("微信支付 -> 异步通知：处理开始");
            String resXml = "<xml> <return_code><![CDATA[SUCCESS]]></return_code>" +
                    " <return_msg><![CDATA[OK]]></return_msg> </xml> ";
            String notifyXml = IOUtil.inputStreamToString(request.getInputStream(), "UTF-8");
            log.info("微信支付 -> 异步通知数据：", notifyXml);

            SortedMap<String, String> map = XmlUtil.parseXmlToTreeMap(notifyXml, "UTF-8");
            if ("SUCCESS".equals(map.get("return_code")) && "SUCCESS".equals(map.get("result_code"))) {
                // 查询订单
                BsDeviceOrder order = deviceOrderService.getDetailOrder(map.get("out_trade_no"));
                if (order != null) {
                    order.setPaySerialNo(map.get("transaction_id")); // 支付流水号
                    order.setPayType(1);
                    order.setPayTime(new Date());
                    order.setStatus(DeviceOrderStatusEnum.status2.getNumber());
                    deviceOrderService.paySuccess(order);
                }
            }
            BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
            out.write(resXml.getBytes());
            out.flush();
            out.close();
            log.info("微信支付 -> 异步通知：处理完成");
        } catch (Exception e) {
            log.error("login error!",e);
        }
    }

}
