package com.chinacreator.video.restful.controller;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.chinacreator.video.annotation.Log;
import com.chinacreator.video.bean.OrderInfo;
import com.chinacreator.video.exception.BussinessException;
import com.chinacreator.video.restful.bean.RechargeOrder;
import com.chinacreator.video.restful.dao.HuaweiWalletDao;
import com.chinacreator.video.restful.service.HuaweiWalletService;
import com.chinacreator.video.util.RsaUtil;
import com.chinacreator.video.util.URLUtil;
import com.chinacreator.video.validate.BusiValidate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 华为钱包CAP短信订购
 * @author xinlong.liu
 * @date 20220629
 */
@RestController
public class HuaweiWalletController {

    @Autowired
    private HuaweiWalletService huaweiWalletService;

    @Autowired
    private BusiValidate busiValidate;

    @Autowired
    private HuaweiWalletDao huaweiWalletDao;

    //测试环境  我方提供的私钥用于解密，会提供配套的公钥给对方加密
    @Value("${univideo.privateKey}")
    String privateKey;

    ////测试环境   华为方提供的公钥，用于给返回数据加密与验证签名
    //测试环境  我方提供的私钥用于解密，会提供配套的公钥给对方加密
    @Value("${univideo.publicKey}")
    String publicKey;

    //测试环境我方公钥 提供给华为钱包  可用于我方测试
//    String publicKey = "MIIBITANBgkqhkiG9w0BAQEFAAOCAQ4AMIIBCQKCAQBTKK9bNrwIsY5ApEkYH3+3" +
//            "x0yoqHWoImtZl9ZULn6V9LlFfLL2EWVYi93K4g0nm6nT1BAdq5wTTmdGUJQH32bT" +
//            "wMo07QXWqTg5bm4p2ZNeprAehKa2Uh6Ey1nAqlGPV8w32PmekiHKApslqiJ0Q0FQ" +
//            "bWdvhcPuZUhRqsYx+S55d3kO4Haez4hDoYloVEypkfU4kPe2DwkpB7hT199lAewd" +
//            "NrRS9oQo0V/+SG6blzplyLnIaXAUlKzngP11bZGz6xAKZqauMjCxUX1UPLmhJ/nN" +
//            "k+CW5D0SY/0MuZv6UY9rBwQN/IQScGcbUTrCYpIbPJuR2/NiU24EWQ/qxcKELCFh" +
//            "AgMBAAE=";


    private Logger logger = LoggerFactory.getLogger("huaweiwallet");

    /**
     * 短信下发
     * @param params
     * @param request
     * @return
     * @throws Exception
     */
    @PostMapping("/v1/recharge/sms/get")
    @ResponseBody
    public Map<String, String> huaweiSendCapSmsCode(@RequestBody String params, HttpServletRequest request) throws Exception {
        Map<String,Object> logmap = new HashMap<String,Object>();
        OrderInfo orderInfo = new OrderInfo();
        logmap.put("invoke", "huaweiSendCapSmsCode");
        logmap.put("reqData", params);
        logmap.put("requestId",request.getHeader("requestId"));
        logmap.put("signType",request.getHeader("signType"));
        logmap.put("signVersion",request.getHeader("signVersion"));
        String returnCode = "0";
        String returnDesc = "success";
        String signType = "SHA256WithRSA/PSS";
        String sign = "";
        Map<String, String> respMap = new HashMap<>();
        long startTime = System.currentTimeMillis();
        try {
            JSONObject object = JSON.parseObject(params);
            orderInfo.setInvokeface("huaweiSendCapSmsCode");
            try{
                String userid = RsaUtil.decrypt(object.getString("phoneNumber"), privateKey);
                orderInfo.setUserid(userid);
            }catch (Exception ee){
                throw new BussinessException("1", "手机号解密失败");
            }
            orderInfo.setSpid(object.getString("productCode"));
            orderInfo.setChannel("200000000037");
            orderInfo.setTimestamp(object.getString("timestamp"));
            orderInfo.setCpid("0");
            huaweiWalletService.paramValidate(orderInfo,object);
            busiValidate.valiCpSp(orderInfo);
            huaweiWalletService.check(orderInfo,params,object.getString("sign"));
            huaweiWalletService.process(orderInfo);
        } catch (Exception e) {
            if (e instanceof BussinessException) {
                returnCode = ((BussinessException) e).getCode();
                returnDesc = e.getMessage();
            } else {
                e.printStackTrace();
                returnCode = "2007";
                returnDesc = "系统异常,请稍后再试!";
                logger.info("出现异常，"+e.getMessage(),e);
                logmap.put("errorinfo","出现异常，"+e.getMessage());
            }
        } finally {
            logmap.put("returnCode",returnCode);
            if(logmap.get("returnDesc") == null){
                logmap.put("returnDesc",returnDesc);
            }
            logmap.put("times", System.currentTimeMillis()-startTime);
            logger.info(JSON.toJSONString(logmap));

            respMap.put("returnCode", returnCode);
            respMap.put("returnDesc", returnDesc);
            respMap.put("signType",signType);
            sign = "returnCode="+returnCode+"&returnDesc="+returnDesc;
            respMap.put("sign",RsaUtil.signByRSA(sign,privateKey));
            logger.info("短信下发接口返回respData: " + JSON.toJSONString(respMap));
        }
        return respMap;
    }

    /**
     * 服务可用检查
     * @return
     */
    @RequestMapping("/v1/query/health/check")
    public Map<String, String> checkHealth (){
        Map<String, String> respMap = new HashMap<>();
        respMap.put("returnCode", "0");
        respMap.put("returnDesc", "success");
        respMap.put("healthStatus", "0");
        return respMap;
    }

    /**
     * 短信验证与订购下单
     * @param params
     * @param request
     * @return
     * @throws Exception
     */
    @Log
    @PostMapping("/v1/recharge/product/request")
    @ResponseBody
    public Map<String, String> huaweiCheckCapSmsCode(@RequestBody String params, HttpServletRequest request) throws Exception {
        Map<String, Object> logmap = new HashMap<String, Object>();
        OrderInfo orderInfo = new OrderInfo();
        logmap.put("invoke", "huaweiCheckCapSmsCode");
        logmap.put("reqData", params);
        logmap.put("requestId", request.getHeader("requestId"));
        logmap.put("signType", request.getHeader("signType"));
        logmap.put("signVersion", request.getHeader("signVersion"));
        String returnCode = "0";
        String returnDesc = "success";
        String signType = "SHA256WithRSA/PSS";
        String sign = "";
        Map<String, String> respMap = new HashMap<>();
        long startTime = System.currentTimeMillis();
        String orderNo = "";
        try {
            JSONObject object = JSON.parseObject(params);
            orderInfo.setInvokeface("huaweiCheckCapSmsCode");
            orderNo = object.getString("orderNo");
            try{
                String userid = RsaUtil.decrypt(object.getString("phoneNumber"), privateKey);
                orderInfo.setUserid(userid);
            }catch (Exception ee){
                throw new BussinessException("1", "手机号解密失败");
            }
            orderInfo.setSpid(object.getString("productCode"));
            orderInfo.setChannel("200000000037");
            orderInfo.setTimestamp(object.getString("timestamp"));
            orderInfo.setVcode(object.getString("smsCode"));
            orderInfo.setType("0");
            logmap.put("type",orderInfo.getType());
            logmap.put("sign", object.getString("sign"));
            logmap.put("userid",orderInfo.getUserid());
            logmap.put("channel",orderInfo.getChannel());
            logmap.put("vcode",orderInfo.getVcode());
            logmap.put("spid",orderInfo.getSpid());
            orderInfo.setCpid("0");
            huaweiWalletService.paramValidate(orderInfo,object);
            busiValidate.valiCpSp(orderInfo);
            logmap.put("cpid",orderInfo.getCpid());
            huaweiWalletService.check(orderInfo,params,object.getString("sign"));
            huaweiWalletService.process(orderInfo);
            huaweiWalletService.addHuaweiOrderRec(orderInfo,object);
        } catch (Exception e) {
            if (e instanceof BussinessException) {
                returnCode = ((BussinessException) e).getCode();
                returnDesc = e.getMessage();
            } else {
                e.printStackTrace();
                returnCode = "2007";
                returnDesc = "系统异常,请稍后再试!";
                logger.info("出现异常，"+e.getMessage(),e);
                logmap.put("returnDesc","出现异常，"+e.getMessage());
            }
//            throw e;
        } finally {
            logmap.put("returnCode",returnCode);
            if(logmap.get("returnDesc") == null){
                logmap.put("returnDesc",returnDesc);
            }
            logmap.put("times", System.currentTimeMillis()-startTime);
            logger.info(JSON.toJSONString(logmap));

            respMap.put("returnCode", returnCode);
            respMap.put("returnDesc", returnDesc);
            respMap.put("orderNo",orderNo);
            Date date2 = new Date();
            SimpleDateFormat formatter2 = new SimpleDateFormat("yyyyMMddHHmmss");
            respMap.put("timestamp",formatter2.format(date2));
            String spOrderNo = huaweiWalletDao.getSpOrderNo(orderNo);
            respMap.put("spOrderNo",spOrderNo);
            if ("0".equals(returnCode)){
                respMap.put("status", "0");
                Date date = new Date();
                SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                respMap.put("spOrderTime",formatter.format(date));
                sign = "orderNo="+orderNo+"&returnCode="+returnCode+"&returnDesc="+returnDesc+"&spOrderNo="+spOrderNo+"&spOrderTime="+formatter.format(date)+"&status="+"0"+"&timestamp="+formatter2.format(date2);
            }else {
                respMap.put("status", "0");
                sign = "orderNo="+orderNo+"&returnCode="+returnCode+"&returnDesc="+returnDesc+"&status="+"0"+"&timestamp="+formatter2.format(date2);
            }
            respMap.put("signType",signType);
            respMap.put("sign",RsaUtil.signByRSA(sign,privateKey));
            logger.info("短信验证接口返回respData: " + JSON.toJSONString(respMap));
            huaweiWalletDao.addHuaweiSmsorderLog(logmap);
        }
        return respMap;
    }

    /**
     * 订单查询
     * @param params
     * @param request
     * @return
     * @throws Exception
     */
    @PostMapping("/v1/query/recharge/request")
    @ResponseBody
    public Map<String, Object> huaweiqueryrecharge(@RequestBody String params, HttpServletRequest request) throws Exception {
        Map<String, Object> logmap = new HashMap<String, Object>();
        OrderInfo orderInfo = new OrderInfo();
        Map<String, Object> respMap = new HashMap<>();
        long startTime = System.currentTimeMillis();
        String returnCode = "0";
        String returnDesc = "success";
        Map<String,Object> rechargeMap = null;

        RechargeOrder rechargeOrder = null;
        try{
            logmap.put("reqDate",params);
            JSONObject object = JSON.parseObject(params);
            orderInfo.setInvokeface("huaweiqueryrecharge");
            try{
                String userid = RsaUtil.decrypt(object.getString("phoneNumber"), privateKey);
                orderInfo.setUserid(userid);
            }catch (Exception ee){
                throw new BussinessException("1", "手机号解密失败");
            }
            orderInfo.setTimestamp(object.getString("timestamp"));
            orderInfo.setChannel("200000000037");
            orderInfo.setOrderid(object.getString("orderNo"));
            huaweiWalletService.check(orderInfo,params,object.getString("sign"));
            rechargeMap = huaweiWalletService.query(orderInfo);
        }catch (Exception e){
            if (e instanceof BussinessException) {
                returnCode = ((BussinessException) e).getCode();
                returnDesc = e.getMessage();
            } else {
                e.printStackTrace();
                returnCode = "2007";
                returnDesc = "系统异常,请稍后再试!";
                logger.info("出现异常，"+e.getMessage(),e);
                logmap.put("returnDesc","出现异常，"+e.getMessage());
            }
        }finally {
            logmap.put("returnCode",returnCode);
            if(logmap.get("returnDesc") == null){
                logmap.put("returnDesc",returnDesc);
            }
            logmap.put("times", System.currentTimeMillis()-startTime);
            logmap.put("rechargeOrder",rechargeMap);
            logger.info(JSON.toJSONString(logmap));

            respMap.put("returnCode", returnCode);
            respMap.put("returnDesc", returnDesc);
            String sign ="";
            if ("0".equals(returnCode)){
                if (rechargeMap == null){
                    respMap.put("orderCount",0);
                    sign = "orderCount="+0+"&returnCode="+returnCode+"&returnDesc="+returnDesc;
                    logger.info("sign1 "+sign);
                }else {
                    respMap.put("orderCount",1);
                    rechargeOrder = new RechargeOrder();
                    rechargeOrder.setSpOrderNo(rechargeMap.get("ID").toString());
                    rechargeOrder.setPhoneNumber(rechargeMap.get("USERID").toString());
                    rechargeOrder.setOrderNo(rechargeMap.get("ORDERNO").toString());
                    rechargeOrder.setSpid(rechargeMap.get("HWSPID").toString());
                    rechargeOrder.setStatus(rechargeMap.get("STATUS").toString());
                    rechargeOrder.setProductCode(rechargeMap.get("SPID").toString());
                    rechargeOrder.setProductType(rechargeMap.get("PRODUCTYPE").toString());
                    rechargeOrder.setFaceValue(rechargeMap.get("FACEVALUE").toString());
                    rechargeOrder.setCallbackParam1(rechargeMap.get("NOTIFYPARAM1")==null?null:rechargeMap.get("NOTIFYPARAM1").toString());
                    rechargeOrder.setCallbackParam2(rechargeMap.get("NOTIFYPARAM2")==null?null:rechargeMap.get("NOTIFYPARAM2").toString());
                    rechargeOrder.setCallbackParam3(rechargeMap.get("NOTIFYPARAM3")==null?null:rechargeMap.get("NOTIFYPARAM3").toString());
                    rechargeOrder.setOrderTime(rechargeMap.get("ORDERTIME").toString());
                    rechargeOrder.setRechargeTime(rechargeMap.get("RECHARGETIME").toString());
                    sign = huaweiWalletService.signByRSA(respMap,rechargeOrder);
                    logger.info("sign2 "+sign);
                }

            }else {
                sign = "orderCount="+0+"&returnCode="+returnCode+"&returnDesc="+returnDesc;
                logger.info("sign3 "+sign);
            }
            logger.info("查询接口返回签名原文signStr: "+sign);
            ArrayList<Object> list = new ArrayList<>();
            list.add(rechargeOrder);
            respMap.put("orderList",list);
            respMap.put("signType","SHA256WithRSA/PSS");
            respMap.put("sign",RsaUtil.signByRSA(sign,privateKey));
            logger.info("查询接口返回respData: " + JSON.toJSONString(respMap));
        }
        return respMap;

    }

    @RequestMapping("/huaweinotify")
    public String huaweinotify(String signStr) throws Exception {
        return RsaUtil.signByRSA(signStr,privateKey);
    }




    public static void main(String[] args) throws Exception {
        //测试环境我方公钥 提供给华为钱包
        String publicKey = "MIIBITANBgkqhkiG9w0BAQEFAAOCAQ4AMIIBCQKCAQBTKK9bNrwIsY5ApEkYH3+3" +
                "x0yoqHWoImtZl9ZULn6V9LlFfLL2EWVYi93K4g0nm6nT1BAdq5wTTmdGUJQH32bT" +
                "wMo07QXWqTg5bm4p2ZNeprAehKa2Uh6Ey1nAqlGPV8w32PmekiHKApslqiJ0Q0FQ" +
                "bWdvhcPuZUhRqsYx+S55d3kO4Haez4hDoYloVEypkfU4kPe2DwkpB7hT199lAewd" +
                "NrRS9oQo0V/+SG6blzplyLnIaXAUlKzngP11bZGz6xAKZqauMjCxUX1UPLmhJ/nN" +
                "k+CW5D0SY/0MuZv6UY9rBwQN/IQScGcbUTrCYpIbPJuR2/NiU24EWQ/qxcKELCFh" +
                "AgMBAAE=";
        //测试环境我方私钥
        String privateKey = "MIIEoQIBAAKCAQBTKK9bNrwIsY5ApEkYH3+3x0yoqHWoImtZl9ZULn6V9LlFfLL2" +
                "EWVYi93K4g0nm6nT1BAdq5wTTmdGUJQH32bTwMo07QXWqTg5bm4p2ZNeprAehKa2" +
                "Uh6Ey1nAqlGPV8w32PmekiHKApslqiJ0Q0FQbWdvhcPuZUhRqsYx+S55d3kO4Hae" +
                "z4hDoYloVEypkfU4kPe2DwkpB7hT199lAewdNrRS9oQo0V/+SG6blzplyLnIaXAU" +
                "lKzngP11bZGz6xAKZqauMjCxUX1UPLmhJ/nNk+CW5D0SY/0MuZv6UY9rBwQN/IQS" +
                "cGcbUTrCYpIbPJuR2/NiU24EWQ/qxcKELCFhAgMBAAECggEAJPQocK0zA937K+iV" +
                "fr3IoJ9VBoHNvwiEkcyydrgukm6swh8227hBRAbraZPoaph28GYFP1oaQk4OAKYg" +
                "EhuJc0Hx2XEWrhyGmqbjF3/TSDVkgDtMZiq52yMOYFqPYdaPLqYhzwB7OWzNCwC+" +
                "zNFyPc5QL7POrKqfZ4MvDdgAegNGNYFqz4ZF/kme6eDfRWBUVDcLC6xbpc41hcsA" +
                "eb8fLzfSoyRZDcbV0t/XGYnEOG7AZbdgg0SwNAELMjeSsW2hhjvpBxOWd9CALqNA" +
                "T6avg4aG7N5DisIKAKoLVgzBkyklHrq8PlUR4ZySm+Ch6a6NfZgu8jTsAsWWBqFS" +
                "B07nDQKBgQCf4FnEF5FCR6/JFORhKE8ciYTiuTii4ddPhdrXrKuLDoj0c88JwB5T" +
                "scTz038SPf8Zer5FrUDll1/R4FN0qbxJNVWrwnI3HE1G61qt0IlHpXLknqOcHoVK" +
                "8rc6Puo1Xajn0h4CPpUKk5aKyyowSOR1ozj0ysYTb2zAFQPV5ST11wKBgQCFKDxP" +
                "oQ0ESg7xLZRIu5IaNfCeaLDjc1gTv+kXZThIIANcCmBSxbyoy5JToFQFXJUYybgn" +
                "24iGaHn+l2O3Jr+Ua8xy2xz9N74potwqd7J9gEBTlodsFmki5ICXyqUx4Zpox+rk" +
                "lgXsFmISBIARoj1c04n/uPcbqda5gpbj1YvLhwKBgFNTTdXK5rVhwXePAPy2Uo0w" +
                "C2dTW/ZguKREwmt4Hiwqliy6EyUk0WmTlG/0Qh1S3Jr+Ax8zjkhbHeC4Bycds/l/" +
                "57fOb1LT2F7nGWrP7ky+KWSIXgNnUNdgKykbU1wfBYJVW7iVv340r9iEzOc/hnrd" +
                "aDkFWjkU8Nwn18jqVdofAoGAEPrJfgn2Y/ahoyWBxCiO/+Ki9UA6VjauI46URZR1" +
                "sdTLOOBl2gg2/3s+BIXsUOa2aHvIjOSUqzcFX26km4VIZr+8SWUhdDS4fgyzcILk" +
                "8tX43e/TAvh0natvrmt71zmCfBwKGu36gVl1VgDW5+i9VGnxLffDIvbsV6mMXi8r" +
                "7V8CgYBkAWkbE0FAn6vG5ku9kROO3Nq8FDN2R2zGyiX8jSC/IBu1q3FqPA4LzO6q" +
                "z70f/+EteWYZGx9eaV4u9uDelNS7L3ME2PHOuF6WeKklnMG3RcFe7wgRnrIkMyvl" +
                "NtdWSabvr8mxBjqM892rKfsWLp+LCcyzy1J2J6z61HL9IzuNpg==";
        String aa = "18692021642";
        String sign = "CPVAYEhmjsEcb7xlj/zgibzPtV7LmTwlHhaPFHCseVAV28AExI57ISvLRi2aaFUVT0iwvFjYp3gMr3CHOAl+lE52kRAr2Gz4DmxYNLFogAH9eQTfLy6e7XmBrA1IkXrDYXQEuw2OnxToLaUYvuYZ59buFZ0Qd4pl14u1GdMpZnE=";

//        String encrypt = RsaUtil.signByRSA(aa,privateKey);
//        System.out.println(encrypt);
//        boolean b = RsaUtil.verifyRSASign(aa, publicKey, encrypt);
//        System.out.println(b);
//        String s = RsaUtil.encrypt(aa,publicKey);
//        System.out.println(s);
//        String c = RsaUtil.decrypt(s,privateKey);
//        System.out.println(c);
//
//        Date date = new Date();
//        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-mm-dd HH:mm:ss");
//        System.out.println(formatter.format(date));
        String signStr = "faceValue=10240&orderNo=935563507628642048&orderTime=2022-07-15 14:20:26&rechargeTime=2022-07-15 14:22:04&spOrderNo=20220714195626761587&spid=ChinaUnicom&status=2&timestamp=20220715144820, url=https://119.3.234.239:8463/WiseCloudVirtualCardMgmtService/partner/v2/notify/recharge/status?clientVersion=900173080";

        System.out.println(RsaUtil.signByRSA(signStr,privateKey));

        String AAA = URLUtil.get("http://testapi.mige.tv/univideo/huaweinotify?signStr="+ URLEncoder.encode(signStr));
        System.out.println(AAA);
    }




}
