package com.platform.yijia.controller;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.parser.Feature;
import com.google.gson.Gson;
import com.platform.yijia.param.request.*;
import com.platform.yijia.pojo.AppUserInfo;
import com.platform.yijia.pojo.PayOrder;
import com.platform.yijia.service.AppUserInfoService;
import com.platform.yijia.service.PayOrderService;
import com.platform.yijia.utils.*;
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.util.*;

@Controller
@RequestMapping("/api")
public class PayController {
    private static Logger logger =(Logger) LoggerFactory.getLogger(PayController.class);
    @Resource
    private PayOrderService payOrderService;
    @Resource
    private AppUserInfoService appUserInfoService;

    /***
     * 微信子商户支付接口
     * @param weChatPaySetRequest
     * @return
     */
    @RequestMapping(value = "/weChatPaySet", consumes = "application/json", method = RequestMethod.POST)
    @ResponseBody
    public  String weChatPaySet(@RequestBody WeChatPaySetRequest weChatPaySetRequest){
        Gson gson = new Gson();
        ResultData resultData = null;    //返回结果
        try {
            String type = weChatPaySetRequest.getType();    //获取配置类型
            JSONObject reqData = new JSONObject();          //微信子商户支付参数配置
            reqData.put("mno", weChatPaySetRequest.getMno());                           //商编
            reqData.put("subMchIdsubMchId", weChatPaySetRequest.getSubMchIdsubMchId()); //获取微信子商号
            if(type != null  && type !=""){
                reqData.put("type", type);
                //根据类型设置必传参数
                switch (type){
                    case "01":  //支付Appid
                        reqData.put("accountType", weChatPaySetRequest.getAccountType());   // 支付Appid类型  配置类型为01时必传
                        reqData.put("subAppid", weChatPaySetRequest.getSubAppid());         // 支付Appid      配置类型为01，02时必传
                        break;
                    case "02":  //关注Appid
                        reqData.put("subAppid", weChatPaySetRequest.getSubAppid());         // 支付Appid      配置类型为01，02时必传
                        reqData.put("subscribeAppid", weChatPaySetRequest.getSubscribeAppid());  // 推荐关注公众号Appid 配置类型为02时与推荐关注  小程序Appid二选一
                        reqData.put("receiptAppid", weChatPaySetRequest.getReceiptAppid());     // 推荐关注小程序Appid 配置类型为02时与推荐关注 公众号Appid二选一
                        break;
                    case "03":  //jsapi授权目录
                        reqData.put("jsapiPath", weChatPaySetRequest.getJsapiPath());       // jsapi授权目录 配置类型为03时必传
                        break;
                }
            }

            String sxfPay = SXFPaySign.getSXFPay(reqData);      //封装传参信息，增加公共信息，增加业务信息
            logger.debug("参数信息："+ sxfPay);
            System.out.println("req:" + sxfPay);
            //此处不要改变reqData里面值的顺序用LinkedHashMap
            HashMap reqMap = JSON.parseObject(sxfPay, LinkedHashMap.class, Feature.OrderedField);
            //组装加密串
            String signContent = RSASignature.getOrderContent(reqMap);
            System.out.println("拼接后的参数：" + signContent);
            logger.debug("拼接后的参数："+signContent);
            //sign
            String sign = RSASignature.encryptBASE64(RSASignature.sign(signContent, SXFPaySign.privateKey));
            reqMap.put("sign", sign);
            String reqStr = JSON.toJSONString(reqMap);
            System.out.println("请求参数:" + reqMap);
            System.out.println("请求参数:" + reqStr);

            //String url = "https://openapi-test.tianquetech.com/merchant/weChatPaySet/addConf";    //测试环境
            String url = "https://openapi.tianquetech.com/merchant/weChatPaySet/addConf";       //生产环境
            //访问第三方接口
            String resultJson = HttpUtils.connectPostUrl(url, reqStr);
            System.out.println("返回信息：" + resultJson);
            //   logger.debug("返回信息："+resultJson);
            //不要对reqData排序 所以用LinkedHashMap
            HashMap<String, Object> result = JSON.parseObject(resultJson, LinkedHashMap.class, Feature.OrderedField);
            if ("0000".equals(result.get("code"))) {
                //验签
                String signResult = result.get("sign").toString();
                result.remove("sign");
                String resultStr = RSASignature.getOrderContent(result);
                System.out.println(resultStr);
                //sign
                String resultSign = RSASignature.encryptBASE64(RSASignature.sign(signContent, SXFPaySign.privateKey));
                System.out.println("resultSign:" + resultSign);
                //组装加密串

                if (RSASignature.doCheck(resultStr, signResult, SXFPaySign.sxfPublic)) {
                    System.out.println("===================验签成功==============");
                }
            }
            resultData=ResultData.success(result);
        } catch (Exception e) {
            resultData=ResultData.error(CodeMsg.YEWU_FAIL,"支付失败");
            e.printStackTrace();
        }
        return  gson.toJson(resultData);
    }


    /**
     * 支付接口，前台上传支付信息，支付数据落地生产订单，调用随行付支付接口
     * @param
     * @return
     */
    @RequestMapping(value = "/getJhPayInfo", consumes = "application/json", method = RequestMethod.POST)
    @ResponseBody
    public String getJhPayInfo(@RequestBody PayInfoRequest payInfoRequest){
        Gson gson =new Gson();
        ResultData resultData =null;
        String token=payInfoRequest.getToken();//token
        String userType=payInfoRequest.getUserType();//用户登录类型 1 公众号。2 小程序
        String mno=payInfoRequest.getMno();//获取商户号
        Integer orderId =payInfoRequest.getOrderId();
        //根据token 和登录类型 身份验证
        AppUserInfo appUserInfo =new AppUserInfo();
        //订单类型 是小程序还是公众号
        appUserInfo.setUserType(userType);
        if(userType.equals("1")){
            //1 是公众号
            appUserInfo.setBlogOpenid(token);
        }else if(userType.equals("2")){
            //2是小程序
            appUserInfo.setMinaOpenid(token);
        }
        List<AppUserInfo> appUserInfoList =appUserInfoService.Authentication(appUserInfo);

        if(appUserInfoList!=null&&appUserInfoList.size()==1){
            //调用聚合支付
            try{
                //根据订单号查询订单信息
                PayOrder payOrder=payOrderService.searchPayOrder(orderId);
                if(payOrder!=null){
                    //将业务参数存放在 JSON 对象中
                    JSONObject reqData = new JSONObject();

                    reqData.put("ordNo", payOrder.getOrderNo()); //商户订单号
                    reqData.put("mno", mno); //商户编号
                    //reqData.put("subMechId", ""); //子商户号
                    //reqData.put("amt", payOrder.getAmt()); //订单总金额
                    reqData.put("amt", "0.01");
                    //reqData.put("discountAmt", ""); //参与优惠金额
                    //reqData.put("unDiscountAmt", ""); //不参与优惠金额
                    reqData.put("payType", "WECHAT"); //支付渠道
                    if(userType.equals("1")){
                        //1 是公众号
                        reqData.put("payWay", "02"); //支付方式  02 公众号/服 务窗/js支付 03 小程序
                        reqData.put("userId", appUserInfoList.get(0).getBlogOpenid()); //用户号 微信：openid； 支付宝：userid；银联：userid；微信&支付宝必传，银联js为非必传
                    }else if(userType.equals("2")){
                        //2是小程序
                        reqData.put("payWay", "03"); //支付方式  02 公众号/服 务窗/js支付 03 小程序
                        reqData.put("userId", appUserInfoList.get(0).getMinaOpenid()); //用户号 微信：openid； 支付宝：userid；银联：userid；微信&支付宝必传，银联js为非必传
                    }
                    //reqData.put("timeExpire", "10"); //订单失效时间, 以分钟为单位
                    //reqData.put("limitPay", "00"); //限制卡类型: 00-全部 01-限定不能使 用信用卡支付 默认值 00
                    reqData.put("subject", "聚合支付测试"); //订单标题
                    //reqData.put("hbFqNum", "6"); //花呗分期数,仅可上送 6 或 12
                    reqData.put("tradeSource", "01"); //交易来源 01服务商，02收银台，03硬件
                    reqData.put("trmIp", "172.16.2.1");//商家ip地址
                    // reqData.put("customerIp", ""); //持卡人ip地址，银联js支付时必传
                      //reqData.put("subAppid", "wx24210004370ec43b"); //微信子公众号
                    //reqData.put("outFrontUrl", ""); //js 支付，前台 成功通知地址
                    //reqData.put("outFrontFailUrl", ""); //js 支付，前台 事变通知地址
                    reqData.put("notifyUrl", "http://www.huiyj.com/yijia-pay/api/getCallback"); //回调地址
                    //reqData.put("needReceipt", "00"); //电子发票功能 微信开具电子 发票使用
                    //reqData.put("ledgerAccountFlag", "00"); //是否做分账 分账交易使 用；00：做； 01：不做；不传默认为不做分账
                    //reqData.put("ledgerAccountEffectTime", "00"); //分账有效时间 单位为天；是 否做分账选择 00 时该字段必传
                    // reqData.put("ruleId", "00"); //同 步 分 账 规 则 id
                    // reqData.put("fusruleId", "00"); //同步分账规则
                    //reqData.put("ylTrmNo", ""); //银联终端号
                    //reqData.put("terminalId", ""); //TQ机具编号
                    //reqData.put("deviceNo ", "1111"); //设备号
                  //  reqData.put("identityFlag", ""); //是否是实名支付
//                reqData.put("buyerIdType", "IDCARD"); //证件类型
//                reqData.put("buyerIdNo", "410523198701054018"); //证件号
                   // reqData.put("buyerName", "张三"); //买家姓名
                   // reqData.put("mobileNum", ""); //手机号
                   // reqData.put("extend", ""); //备用
                    String req= SXFPaySign.getSXFPay(reqData);
                     logger.debug("参数信息："+req);
                    System.out.println("req:" + req);
                    //此处不要改变reqData里面值的顺序用LinkedHashMap
                    HashMap reqMap = JSON.parseObject(req, LinkedHashMap.class, Feature.OrderedField);
                    //组装加密串
                    String signContent = RSASignature.getOrderContent(reqMap);
                    System.out.println("拼接后的参数：" + signContent);
                       logger.debug("拼接后的参数："+signContent);
                    //sign
                    String sign = RSASignature.encryptBASE64(RSASignature.sign(signContent, SXFPaySign.privateKey));
                    System.out.println("============签名:" + sign);
                    reqMap.put("sign", sign);
                    String reqStr = JSON.toJSONString(reqMap);
                    System.out.println("请求参数:" + reqMap);
                    System.out.println("请求参数:" + reqStr);
                    //调用第三方接口地址
                    //String url = "https://openapi-test.tianquetech.com/order/jsapiScan";//测试地址
                    String url = "https://openapi.suixingpay.com/order/jsapiScan";//生产地址
                    String resultJson = HttpUtils.connectPostUrl(url, reqStr);
                    System.out.println("返回信息：" + resultJson);
                    //   logger.debug("返回信息："+resultJson);
                    //不要对reqData排序 所以用LinkedHashMap
                    HashMap<String, Object> result = JSON.parseObject(resultJson, LinkedHashMap.class, Feature.OrderedField);
                    if ("0000".equals(result.get("code"))) {
                        //验签
                        String signResult = result.get("sign").toString();
                        result.remove("sign");
                        String resultStr = RSASignature.getOrderContent(result);
                        System.out.println(resultStr);
                        //sign
                        String resultSign = RSASignature.encryptBASE64(RSASignature.sign(signContent, SXFPaySign.privateKey));
                        System.out.println("resultSign:" + resultSign);
                        //组装加密串
                        if (RSASignature.doCheck(resultStr, signResult, SXFPaySign.sxfPublic)) {
                            System.out.println("===================验签成功==============");
                        }
                    }
                    resultData=ResultData.success(result);
                }else {
                    resultData=ResultData.error(CodeMsg.YEWU_FAIL,"未查询到订单");
                }
            }catch (Exception e){
                resultData=ResultData.error(CodeMsg.YEWU_FAIL,"订单支付失败");
                e.printStackTrace();
            }
        }else{
            //返回失败支付失败信息
            resultData=ResultData.error(CodeMsg.USER_NOT_EXSIST);
        }
        return gson.toJson(resultData);
    }

    /**
     * 验证商户信息查询
     */
    @RequestMapping(value = "/getJhPayMnoInfo", method = RequestMethod.GET)
    @ResponseBody
    public String getJhPayMnoInfo(@RequestParam String mno){
        try {
            JSONObject reqData = new JSONObject();
            reqData.put("mno", mno); //商户编号
            String req = SXFPaySign.getSXFPay(reqData);
            logger.debug("参数信息：" + req);
            System.out.println("req:" + req);
            //此处不要改变reqData里面值的顺序用LinkedHashMap
            HashMap reqMap = JSON.parseObject(req, LinkedHashMap.class, Feature.OrderedField);
            //组装加密串
            String signContent = RSASignature.getOrderContent(reqMap);
            System.out.println("拼接后的参数：" + signContent);
            logger.debug("拼接后的参数：" + signContent);
            //sign
            String sign = RSASignature.encryptBASE64(RSASignature.sign(signContent, SXFPaySign.privateKey));
            System.out.println("============签名:" + sign);
            reqMap.put("sign", sign);
            String reqStr = JSON.toJSONString(reqMap);
            System.out.println("请求参数:" + reqMap);
            System.out.println("请求参数:" + reqStr);
            //调用第三方接口地址
            //String url = "https://openapi-test.tianquetech.com/merchant/merchantInfoQuery";//测试地址
            String url = "https://openapi.tianquetech.com/merchant/merchantInfoQuery";//生产地址
            String resultJson = HttpUtils.connectPostUrl(url, reqStr);
            HashMap<String, Object> result = JSON.parseObject(resultJson, LinkedHashMap.class, Feature.OrderedField);
            if ("0000".equals(result.get("code"))) {
//                //验签
//                String signResult = result.get("sign").toString();
//                result.remove("sign");
//                String resultStr = RSASignature.getOrderContent(result);
//                System.out.println(resultStr);
//                //sign
//                String resultSign = RSASignature.encryptBASE64(RSASignature.sign(signContent, SXFPaySign.privateKey));
//                System.out.println("resultSign:" + resultSign);
//                //组装加密串
//                if (RSASignature.doCheck(resultStr, signResult, SXFPaySign.sxfPublic)) {
//                    System.out.println("===================验签成功==============");
//                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return "";
    }
    /**
     * 关单接口
     */
    @RequestMapping(value = "/getPayOrderClose", consumes = "application/json", method = RequestMethod.POST)
    @ResponseBody
    public String getPayOrderClose(@RequestBody PayCloseRequestParamter payCloseRequestParamter) {
        String results="";
        Gson gson =new Gson();
        String mno=payCloseRequestParamter.getMno();
        String origOrderNo=payCloseRequestParamter.getOrigOrderNo();
        String origUuid=payCloseRequestParamter.getOrigUuid();
        String token=payCloseRequestParamter.getToken();
        String userType=payCloseRequestParamter.getUserType();
        boolean flag =appUserInfoService.selectAppUserInfo(token,userType);
        ResultData resultData =null;
        if(flag){
            try {
                JSONObject reqData = new JSONObject();
                reqData.put("mno",mno); //商户编号
                reqData.put("origOrderNo",origOrderNo);//系统商户订单号
                reqData.put("origUuid", origUuid);//随行付订单号
                String req= SXFPaySign.getSXFPay(reqData);
                //此处不要改变reqData里面值的顺序用LinkedHashMap
                HashMap reqMap = JSON.parseObject(req, LinkedHashMap.class, Feature.OrderedField);
                //组装加密串
                String signContent = RSASignature.getOrderContent(reqMap);
                System.out.println("拼接后的参数：" + signContent);
                //sign
                String sign = RSASignature.encryptBASE64(RSASignature.sign(signContent, SXFPaySign.privateKey));
                System.out.println("============签名:" + sign);
                reqMap.put("sign", sign);
                String reqStr = JSON.toJSONString(reqMap);
                System.out.println("请求参数:" + reqMap);
                System.out.println("请求参数:" + reqStr);
                //调用第三方接口地址
               // String url = "https://openapi-test.tianquetech.com/query/close";//测试地址
                String url = "https://openapi.tianquetech.com/query/close";//生产地址
                String resultJson =  HttpUtils.connectPostUrl(url, reqStr);
                System.out.println("返回信息：" + resultJson);
                //不要对reqData排序 所以用LinkedHashMap
                HashMap<String, Object> result = JSON.parseObject(resultJson, LinkedHashMap.class, Feature.OrderedField);
                if ("0000".equals(result.get("code"))) {
                    //验签
                    String signResult = result.get("sign").toString();
                    result.remove("sign");
                    String resultStr = RSASignature.getOrderContent(result);
                    System.out.println(resultStr);
                    //sign
                    String resultSign = RSASignature.encryptBASE64(RSASignature.sign(signContent,SXFPaySign.privateKey));
                    System.out.println("resultSign:" + resultSign);
                    //组装加密串
                    if (RSASignature.doCheck(resultStr, signResult, SXFPaySign.sxfPublic)) {
                        System.out.println("===================验签成功==============");
                    }
                }
                resultData=ResultData.success(result);
            }catch (Exception e){
                resultData=ResultData.error(CodeMsg.YEWU_FAIL,"关闭订单失败");
                e.printStackTrace();
            }
        }else{
            resultData=ResultData.error(CodeMsg.USER_NOT_EXSIST);
        }

        return  gson.toJson(resultData);
    }
    /**
     * 异步回调通知
     */
    @RequestMapping(value = "/getCallback", consumes = "application/json", method = RequestMethod.POST)
    @ResponseBody
    public void getCallback(HttpServletRequest request,HttpServletResponse response){
        logger.info("回调返回过来的参数"+request);
        Gson gson =new Gson();
        //获取回调参数信息
        String uuid=request.getParameter("uuid");////随行付交易流水号
        String mno=request.getParameter("mno");//发起交易的商户编号
        String ordNo=request.getParameter("ordNo");//商户生成的订单号
        String origOrdNo=request.getParameter("origOrdNo");//反交易退款异步通知
        String origUuid=request.getParameter("origUuid");//token
        String scene=request.getParameter("scene");//用户登录
        String amt=request.getParameter("amt");//用户登录
        String buyerId=request.getParameter("buyerId");//用户登录
        String buyerAccount=request.getParameter("buyerAccount");//用户登录
        String transactionId=request.getParameter("transactionId");//用户登录
        String drType=request.getParameter("drType");//借贷记标识 1-借,2-贷，3-其他
        String payType=request.getParameter("payType");//对订单的描述，取值范围：WECHAT:微信,ALIPAY:支付宝,UNIONPAY:
        String payBank=request.getParameter("payBank");//付款银行银行编码，例如 ICBC
        String pointAmount=request.getParameter("pointAmount");//代金券金额
        String totalOffstAmt=request.getParameter("totalOffstAmt");//消 费 者 付 款金额
        String settleAmt=request.getParameter("settleAmt");//商家入账金额
        String realRefundAmount=request.getParameter("realRefundAmount");//商家出账金额
        String recFeeAmt=request.getParameter("recFeeAmt");//交易手续费
        String recFeeRate=request.getParameter("recFeeRate");//交易手续费率
        String timeStamp=request.getParameter("timeStamp");//响应时间
        String sign=request.getParameter("sign");//签名
        String bizCode=request.getParameter("bizCode");//业务返回码
        String bizMsg=request.getParameter("bizMsg");//业 务 返 回 信息
        String openid=request.getParameter("openid");//微 信 或 支 付宝身份id()opendid userid
        String channelId=request.getParameter("channelId");//渠道商户号
        String subMechId=request.getParameter("subMechId");//子商户号
        String refBuyerAmt=request.getParameter("refBuyerAmt");//消 费 者 到 账金额
        String extend=request.getParameter("extend");//备用
        //将业务参数存放在 JSON 对象中
        JSONObject reqData = new JSONObject();
        reqData.put("uuid",uuid);
        reqData.put("mno",mno);
        reqData.put("ordNo",ordNo);
        reqData.put("origOrdNo",origOrdNo);
        reqData.put("origUuid",origUuid);
        reqData.put("scene",scene);
        reqData.put("amt",amt);
        reqData.put("buyerId",buyerId);
        reqData.put("buyerAccount",buyerAccount);
        reqData.put("transactionId",transactionId);
        reqData.put("drType",drType);
        reqData.put("payType",payType);
        reqData.put("payBank",payBank);
        reqData.put("pointAmount",pointAmount);
        reqData.put("totalOffstAmt",totalOffstAmt);
        reqData.put("settleAmt",settleAmt);
        reqData.put("realRefundAmount",realRefundAmount);
        reqData.put("recFeeAmt",recFeeAmt);
        reqData.put("recFeeRate",recFeeRate);
        reqData.put("timeStamp",timeStamp);
        reqData.put("bizCode",bizCode);
        reqData.put("bizMsg",bizMsg);
        reqData.put("openid",openid);
        reqData.put("channelId",channelId);
        reqData.put("subMechId",subMechId);
        reqData.put("refBuyerAmt",refBuyerAmt);
        reqData.put("extend",extend);
        //根据回调信息，先进行验签，验签后修改状态
        logger.info("打印参数信息"+gson.toJson(reqData));
        //不要对reqData排序 所以用LinkedHashMap
        HashMap<String, Object> result = JSON.parseObject(gson.toJson(reqData), LinkedHashMap.class, Feature.OrderedField);
        //验签
        String resultStr = RSASignature.getOrderContent(result);
        JSONObject req = new JSONObject();
        System.out.println(resultStr);
        if (RSASignature.doCheck(resultStr, sign, SXFPaySign.sxfPublic)) {
            System.out.println("===================验签成功==============");
            logger.info("验签成功");
            //验签成功，修改订单状态
            List<PayOrder> list = payOrderService.getPayOrderList(ordNo);
            logger.info("根据订单号，查询订单"+gson.toJson(list));
            if (list != null && list.size() == 1) {
                String status = list.get(0).getStatus();
                int ordId= list.get(0).getOrderId();
                //状态为未支付 1  修改状态为已支付
                if (status.equals("1")) {
                    PayOrder payOrder = new PayOrder();
                    payOrder.setOrderId(ordId);
                    payOrder.setStatus("2");
                    //根据修改状态
                    payOrderService.getUpdatePayOrder(payOrder);
                    req.put("code","success");
                    req.put("msg","成功");
                }
            }
        }else {
            logger.info("验签失败");
            req.put("code","fail");
            req.put("msg","失败");
        }
        try {
            response.setContentType("application/json; charset=UTF-8");
            response.setCharacterEncoding("UTF-8");
            response.getWriter().print(req);
            response.getWriter().flush();
            response.getWriter().close();
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}
