package com.chaozhanggui.system.lkl.service;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.chaozhanggui.common.system.config.MsgException;
import com.chaozhanggui.common.system.util.DateUtils;
import com.chaozhanggui.system.lkl.config.LakalaConfig;
import com.chaozhanggui.system.lkl.model.*;
import com.chaozhanggui.system.lkl.util.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.DecimalFormat;
import java.util.HashMap;
import java.util.Map;

@Service
@Slf4j
public class OrderPayService {


    @Autowired
    LakalaConfig lakalaConfig;

    private static long changeY2F(double price) {
        DecimalFormat df = new DecimalFormat("#.00");
        price = Double.valueOf(df.format(price));
        long money = (long)(price * 100);
        return money;
    }


    /**
     * 被扫
     * @param orderVO
     * @param statusVO
     * @param baseInfoVO
     * @param merchantBackLklVO
     * @return
     */
    public JSONObject tradePay(MerchantOrderVO orderVO, MerchantChannelStatusVO statusVO, MerchantBaseInfoVO baseInfoVO, MerchantBackLklVO merchantBackLklVO){

        MsgException.checkNull(orderVO, "订单信息为空");
        MsgException.checkNull(statusVO, "进件信息为空");
        MsgException.checkNull(baseInfoVO, "商户基本信息为空");
        MsgException.checkNull(merchantBackLklVO, "拉卡拉渠道信息为空");
        String account_type = "WECHAT";
        if (ObjectUtil.isNotEmpty(orderVO.getScanType()) && "01".equals(orderVO.getScanType())) {
            account_type = "wechatPay".equals(orderVO.getPaytypecode()) ? "WECHAT" : "aliPay".equals(orderVO.getPaytypecode()) ? "ALIPAY" : "UQRCODEPAY";
        } else {
            account_type = "wechatPay".equals(orderVO.getPaytypecode()) ? "WECHAT" : "aliPay".equals(orderVO.getPaytypecode()) ? "ALIPAY" : "UQRCODEPAY";
        }
        String transType = account_type.equals("WECHAT") ? "71" : account_type.equals("ALIPAY") ? "41" : "51";



        String req_time = DateUtils.getSdfTimes();

        Long order_amt = changeY2F(orderVO.getConsumefee());
        String body = null;
        if (account_type.equals("WECHAT")) {
            body="{\n" +
                    "\t\"out_org_code\": \""+lakalaConfig.getAppid()+"\",\n" +
                    "\t\"req_data\": {\n" +
                    "\t\t\"acc_busi_fields\": {\n" +
                    "\t\t\t\"user_id\": \""+orderVO.getMercuserid()+"\",\n" +
                    "\t\t\t\"sub_appid\": \""+lakalaConfig.getAppletsAppid()+"\"\n" +
                    "\t\t},\n" +
                    "\t\t\"account_type\": \""+account_type+"\",\n" +
                    "\t\t\"location_info\": {\n" +
                    "\t\t\t\"request_ip\": \""+orderVO.getIp()+"\"\n" +
                    "\t\t},\n" +
                    "\t\t\"merchant_no\": \""+merchantBackLklVO.getExternalCustomerNo()+"\",\n" +
                    "\t\t\"notify_url\": \""+lakalaConfig.getCallBackUrl()+"\",\n" +
                    "\t\t\"out_trade_no\": \""+orderVO.getOrdernumber()+"\",\n" +
                    "\t\t\"term_no\": \""+merchantBackLklVO.getTermNos()+"\",\n" +
                    "\t\t\"total_amount\": \""+order_amt+"\",\n" +
                    "\t\t\"trans_type\": \""+transType+"\"\n" +
                    "\t},\n" +
                    "\t\"req_time\": \""+req_time+"\",\n" +
                    "\t\"version\": \"3.0\"\n" +
                    "}";

        }

        if (account_type.equals("ALIPAY")) {
            body = "{\n" +
                    "\t\"out_org_code\": \"" + lakalaConfig.getAppid() + "\",\n" +
                    "\t\"req_data\": {\n" +
                    "\t\t\"account_type\": \"" + account_type + "\",\n" +
                    "\t\t\"location_info\": {\n" +
                    "\t\t\t\"request_ip\": \"" + orderVO.getIp() + "\"\n" +
                    "\t\t},\n" +
                    "\t\t\"merchant_no\": \"" + merchantBackLklVO.getExternalCustomerNo() + "\",\n" +
                    "\t\t\"notify_url\": \"" + lakalaConfig.getCallBackUrl() + "\",\n" +
                    "\t\t\"out_trade_no\": \"" + orderVO.getOrdernumber() + "\",\n" +
                    "\t\t\"term_no\": \"" + merchantBackLklVO.getTermNos() + "\",\n" +
                    "\t\t\"total_amount\": \"" + order_amt + "\",\n" +
                    "\t\t\"trans_type\": \"" + transType + "\"\n" +
                    "\t},\n" +
                    "\t\"req_time\": \"" + req_time + "\",\n" +
                    "\t\"version\": \"3.0\"\n" +
                    "}";
        }


        String response = lakalaConfig.request(body, "api/v3/labs/trans/preorder");


        JSONObject resp = new JSONObject();
        if (ObjectUtil.isNotEmpty(response)) {
            JSONObject payData = new JSONObject();
            JSONObject object = JSONObject.parseObject(response);

            if (object.containsKey("code") && "BBS00000".equals(object.getString("code"))) {
                if (!(ObjectUtil.isNotEmpty(orderVO.getScanType()) && "01".equals(orderVO.getScanType()))) {
                    JSONObject acc_resp_fields = object.getJSONObject("resp_data").getJSONObject("acc_resp_fields");
                    if (Constant.PAY_TYPE_ALIPAY.equals(orderVO.getPaytypecode())) {
                        payData.put("source", acc_resp_fields.getString("code"));
                    } else if (Constant.PAY_TYPE_WECHAT.equals(orderVO.getPaytypecode())) {

                        payData.put("payAppId", acc_resp_fields.getString("app_id"));
                        payData.put("payTimeStamp", acc_resp_fields.getString("time_stamp"));
                        payData.put("paynonceStr", acc_resp_fields.getString("nonce_str"));
                        payData.put("payPackage", acc_resp_fields.getString("package"));
                        payData.put("paySignType", acc_resp_fields.getString("sign_type"));
                        payData.put("paySign", acc_resp_fields.getString("pay_sign"));
                    } else {
                        payData.put("redirectUrl", acc_resp_fields.containsKey("redirect_url") ? acc_resp_fields.getString("redirect_url") : null);
                    }

                } else {
                    payData.put("payUrl", object.get("code"));
                    payData.put("orderNumber", orderVO.getOrdernumber());
                    payData.put("mercOrderNo", orderVO.getMercorderno());
                }
                resp.put("code", 200);
                payData.put("channel", statusVO.getChannel());
                payData.put("transNo",(object.getJSONObject("resp_data").containsKey("log_no") && ObjectUtil.isNotEmpty(object.getJSONObject("resp_data").getString("log_no"))) ? object.getString("log_no") : "");
                resp.put("payData", payData);
                return resp;

            } else if (object.containsKey("code") && "BBS16270".equals(object.getString("code"))) {
                resp.put("code", 400);
                resp.put("msg", object.getString("msg"));
                return resp;
            }
        }


        resp.put("code", 400);
        resp.put("msg", "失败");
        return resp;

    }


    /**
     * 主扫
     * @param orderVO
     * @param baseInfoVO
     * @param merchantBackLklVO
     * @return
     */
    public JSONObject tradePay(MerchantOrderVO orderVO,  MerchantBaseInfoVO baseInfoVO, MerchantBackLklVO merchantBackLklVO){

        MsgException.checkNull(orderVO, "订单信息为空");
        MsgException.checkNull(baseInfoVO, "商户基本信息为空");
        MsgException.checkNull(merchantBackLklVO, "拉卡拉渠道信息为空");

        JSONObject obj = new JSONObject(6);

        String req_time = DateUtils.getSdfTimes();
        Long order_amt = changeY2F(orderVO.getConsumefee());

        String body = "{\n" +
                "\t\"req_data\": {\n" +
                "\t\t\"merchant_no\": \"" + merchantBackLklVO.getExternalCustomerNo() + "\",\n" +
                "\t\t\"term_no\": \"" + merchantBackLklVO.getTermNos() + "\",\n" +
                "\t\t\"out_trade_no\": \"" + orderVO.getOrdernumber() + "\",\n" +
                "\t\t\"total_amount\": \"" + order_amt + "\",\n" +
                "\t\t\"subject\": \"" + baseInfoVO.getMccname() + "\",\n" +
                "\t\t\"acc_busi_fields\": {},\n" +
                "\t\t\"notify_url\": \"" + lakalaConfig.getCallBackUrl() + "\",\n" +
                "\t\t\"location_info\": {\n" +
                "\t\t\t\"request_ip\": \"" + orderVO.getIp() + "\"\n" +
                "\t\t},\n" +
                "\t\t\"auth_code\": \"" + orderVO.getAuthCode() + "\"\n" +
                "\t},\n" +
                "\t\"out_org_code\": \"" + lakalaConfig.getAppid() + "\",\n" +
                "\t\"version\": \"3.0\",\n" +
                "\t\"req_time\": " + req_time + "\n" +
                "}";


        String response = lakalaConfig.request(body, "api/v3/labs/trans/micropay");
        if (ObjectUtil.isNotEmpty(response)) {
            JSONObject object = JSON.parseObject(response);
            if (object.containsKey("code") && "BBS10000".equals(object.get("code"))) {
                obj.put("code", 202);
                obj.put("msg", "用户支付中");
                obj.put("channelOrderNo", object.getJSONObject("resp_data").get("trade_no"));
                obj.put("transNo", object.getJSONObject("resp_data").get("log_no"));
                obj.put("payStatus", "7");
                return obj;
            } else if (object.containsKey("code") && "BBS00000".equals(object.get("code"))) {
                obj.put("code", 200);
                obj.put("msg", "成功");
                obj.put("channelOrderNo", object.getJSONObject("resp_data").get("trade_no"));
                obj.put("transNo", object.getJSONObject("resp_data").get("log_no"));
                obj.put("payStatus", "1");
                obj.put("payTime", DateUtils.convertDate(object.getJSONObject("resp_data").getString("trade_time")));
                return obj;
            } else {
                obj.put("code", 400);
                obj.put("msg", object.get("msg"));
                return obj;
            }
        }
        obj.put("code", 400);
        obj.put("msg", "失败");
        return obj;
    }


    /**
     * 退款
     * @param orderVO
     * @param merchantBackLklVO
     * @return
     */
    public Map<String, Object> refundPay(MerchantOrderVO orderVO,MerchantBackLklVO merchantBackLklVO){


        MsgException.checkNull(orderVO, "订单信息为空");
        MsgException.checkNull(merchantBackLklVO, "拉卡拉渠道信息为空");

        String req_time = DateUtils.getSdfTimes();
        Long order_amt = changeY2F(orderVO.getConsumefee());


        String refundNo = "LKLR" + StringUtil.getBillno();

        String body="{\n" +
                " \"req_time\":\""+req_time+"\",\n" +
                " \"version\":\"3.0\",\n" +
                " \"out_org_code\":\""+lakalaConfig.getAppid()+"\",\n" +
                " \"req_data\":{\n" +
                "  \"merchant_no\":\""+merchantBackLklVO.getExternalCustomerNo()+"\",\n" +
                "  \"term_no\":\""+merchantBackLklVO.getTermNos()+"\",\n" +
                "  \"out_trade_no\":\""+refundNo+"\",\n" +
                "  \"refund_amount\":\""+order_amt+"\",\n" +
                "  \"refund_reason\":\"退款\",\n" +
                "  \"origin_out_trade_no\":\""+orderVO.getOrdernumber()+"\",\n" +
                "  \"location_info\":{\n" +
                "   \"request_ip\":\""+orderVO.getIp()+"\",\n" +
                "   \"location\":\"+37.123456789,-121.123456789\"\n" +
                "  }\n" +
                " }\n" +
                "}\n" +
                "\n";

        Map<String, Object> result = new HashMap<>(4);
        result.put("refundNo", refundNo);
        result.put("status", "3");
        result.put("code", 400);

        String response = lakalaConfig.request(body, "api/v3/labs/relation/refund");
        if(ObjectUtil.isNotEmpty(response)){
            JSONObject object=JSONObject.parseObject(response);
            if(object.containsKey("code")&&"BBS00000".equals(object.getString("code"))){
                result.put("msg", "退款成功！");
                result.put("data", object.getJSONObject("resp_data"));
                result.put("status", "1");
                result.put("code", 200);
                return result;
            }else {
                result.put("msg", object.getString("msg"));
                return result;
            }
        }
        result.put("msg", "退款失败！");
        return result;
    }

    /**
     * 订单查询
     * @param orderVO
     * @param merchantBackLklVO
     * @return
     */
    public JSONObject tradeQuery(MerchantOrderVO orderVO, MerchantBackLklVO merchantBackLklVO) {

        MsgException.checkNull(orderVO, "订单信息为空");
        MsgException.checkNull(merchantBackLklVO, "拉卡拉渠道信息为空");

        String req_time = DateUtils.getSdfTimes();

        String body = "{\n" +
                "\"req_time\":\"" + req_time + "\",\n" +
                "\"version\":\"3.0\",\n" +
                "\"out_org_code\":\"" + lakalaConfig.getAppid() + "\",\n" +
                "\"req_data\":{\n" +
                "\"merchant_no\":\"" + merchantBackLklVO.getExternalCustomerNo() + "\",\n" +
                "\"term_no\":\"" + merchantBackLklVO.getTermNos() + "\",\n" +
                "\"out_trade_no\":\"" + orderVO.getOrdernumber() + "\"\n" +
                "}\n" +
                "}\n";

        JSONObject result = new JSONObject();
        String response = lakalaConfig.request(body, "api/v3/labs/query/tradequery");
        if (ObjectUtil.isNotEmpty(response)) {
            JSONObject object = JSONObject.parseObject(response);
            if (object.containsKey("code") && "BBS00000".equals(object.getString("code"))) {
                result.put("channelOrderNo", object.get("trade_no"));
                result.put("payTime", DateUtils.parse(object.getString("trade_time"), "yyyyMMddHHmmss"));
                result.put("transNo", object.get("log_no"));
                result.put("code", 200);
                result.put("payStatus", "1");
                result.put("msg", "查询成功！");
                result.put("buyerId", object.get("user_id1"));
                return result;
            } else {
                result.put("code", 400);
                result.put("msg", object.getString("msg"));
                return result;
            }
        }
        log.error("==============>【拉卡拉】交易订单查询失败<==================");
        result.put("code", 400);
        result.put("msg", "订单查询异常");
        return result;
    }


    public JSONObject refundQuery(MerchantOrderVO orderVO,MerchantBackLklVO merchantBackLklVO) {

        MsgException.checkNull(orderVO, "订单信息为空");
        MsgException.checkNull(merchantBackLklVO, "拉卡拉渠道信息为空");


        String req_time = DateUtils.getSdfTimes();

        String body="{\n" +
                " \"req_time\":\""+req_time+"\",\n" +
                " \"version\":\"3.0\",\n" +
                " \"out_org_code\":\""+lakalaConfig.getAppid()+"\",\n" +
                " \"req_data\":{\n" +
                "  \"merchant_no\":\""+merchantBackLklVO.getExternalCustomerNo()+"\",\n" +
                "  \"term_no\":\""+merchantBackLklVO.getTermNos()+"\",\n" +
                "  \"out_refund_order_no\":\""+orderVO.getRefundNo()+"\"\n" +
                " }\n" +
                "}\n" +
                "\n";

        JSONObject result = new JSONObject();
        String response = lakalaConfig.request(body, "api/v3/labs/query/idmrefundquery");
        if (ObjectUtil.isNotEmpty(response)) {
            JSONObject object = JSONObject.parseObject(response);
            if (object.containsKey("code") && "BBS00000".equals(object.getString("code"))) {
                result.put("refundTime", object.getString("trade_time"));
                result.put("code", 200);
                result.put("status", "1");
                result.put("msg", "查询成功！");
                return result;
            } else {
                result.put("code", 400);
                result.put("msg", object.getString("msg"));
                return result;
            }
        }
        log.error("==============>【拉卡拉】交易订单查询失败<==================");
        result.put("code", 400);
        result.put("msg", "退款订单查询异常");
        return result;
    }


    /**
     * 微信获取用户标识
     * @param userAuthCode
     * @param paymentApp
     * @param merchantBackLklVO
     * @return
     * @throws Exception
     */
    public Map<String, Object> getUnionInfo(String userAuthCode, String paymentApp,MerchantBackLklVO merchantBackLklVO) throws Exception {
        Map<String, Object> result = new HashMap<>();
        String req_time = DateUtils.getSdfTimes();

        MsgException.checkNull(merchantBackLklVO, "拉卡拉渠道信息为空");

        String body = "{\n" +
                "\"ver\":\"1.0.0\",\n" +
                "\"timestamp\":\"" + System.currentTimeMillis() + "\",\n" +
                "\"reqId\":\"" + req_time + "\",\n" +
                "\"reqData\":{\n" +
                "\"mercId\":\"" + merchantBackLklVO.getExternalCustomerNo() + "\",\n" +
                "\"termNo\":\"" + merchantBackLklVO.getTermNos() + "\",\n" +
                "\"authCode\":\"" + userAuthCode + "\",\n" +
                "\"tradeCode\":\"030304\"\n" +
                "}\n" +
                "}\n";
        String response = lakalaConfig.request(body, "api/v2/saas/query/wx_openid_query");
        if (ObjectUtil.isNotEmpty(response)) {
            JSONObject object = JSONObject.parseObject(response);
            if (object.containsKey("retCode") && "BBS00000".equals(object.getString("retCode"))) {

                JSONObject reqData = new JSONObject(2);
                reqData.put("data", object.getJSONObject("respData").getString("openId"));
                reqData.put("userAuthCode", userAuthCode);
                reqData.put("appUpIdentifier", paymentApp);
                result.put("data", reqData);
                result.put("code", "1");
                result.put("msg", "获取成功");
            }
        }
        result.put("code","0");
        result.put("msg", "获取失败");
        return result;
    }






}
