package com.chaozhanggui.system.order.service;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.chaozhanggui.common.system.config.MsgException;
import com.chaozhanggui.common.system.myEnum.SettleTypeEnum;
import com.chaozhanggui.common.system.util.MD5Util;
import com.chaozhanggui.common.system.util.SignUtils;
import com.chaozhanggui.dao.system.dao.*;
import com.chaozhanggui.dao.system.entity.*;
import com.github.pagehelper.util.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Optional;

@Service
@Slf4j
public class OrderParamCheck {


    private static final String KEY = "4c8d277b0f274604af68e590cc0b3e6b";


    @Autowired
    private TbPlussMerchantStoreMapper tbPlussMerchantStoreMapper;

    @Autowired
    private TbPlussMerchantBaseInfoMapper tbPlussMerchantBaseInfoMapper;

    @Autowired
    private TbPlussUserInfoMapper tbPlussUserInfoMapper;

    @Autowired
    private TbPlussMerchantOrderMapper tbPlussMerchantOrderMapper;

    @Autowired
    private TbPlussMerchantChannelStatusMapper tbPlussMerchantChannelStatusMapper;




    public String currencyParamsCheck(JSONObject jsonObject){
        Optional.ofNullable(jsonObject.getString("method")).orElseThrow(() -> new MsgException("接口方法参数不能为空"));
        String mercOrderNo = jsonObject.getString("mercOrderNo");
        Optional.ofNullable(mercOrderNo).orElseThrow(() -> new MsgException("商户订单号不能为空"));
        if (mercOrderNo.length() < 10 || mercOrderNo.length() > 50) {
            throw new MsgException("商户订单号长度格式有误，长度介于10到50之间!");
        }
        Optional.ofNullable(jsonObject.getString("sign")).orElseThrow(() -> new MsgException("缺失签名sign参数！"));
        if("trans_pay".equals(jsonObject.getString("method")) ||
                "trans_wap_pay".equals(jsonObject.getString("method")) ||
                "trans_scan_pay".equals(jsonObject.getString("method"))){
            TbPlussMerchantStore store = null;
            if("trans_pay".equals(jsonObject.getString("method"))){
                checSign(jsonObject,jsonObject.getString("merchantCode"));
                store = checkTransPayParams(jsonObject,jsonObject.getString("merchantCode"));
            }else{
                Optional.ofNullable(jsonObject.getString("merchantCode")).orElseThrow(() -> new MsgException("商户编号不能为空！"));
                checSign(jsonObject,jsonObject.getString("merchantCode"));
                store = checkTransPayParams(jsonObject,jsonObject.getString("merchantCode"));
            }
            String payData = checkMercOrder(store, jsonObject);
            if(StringUtil.isNotEmpty(payData)){
                return payData;
            }


            TbPlussMerchantBaseInfo baseInfo = tbPlussMerchantBaseInfoMapper.selectByMerchantcode(store.getMerchantcode());
            Optional.ofNullable(baseInfo).orElseThrow(() -> new MsgException("当前商户暂未完成商户认证功能！"));
            // 全局电子围栏和单商户电子围栏判定
            //TODO 先关闭异地支付
//            if (!commonSwitchService.allowEcdemicPay() && !store.allowEcdemicPay()) {
//                // 不允许异地支付的时候需要校验ip和商户所在城市
//                try {
//                    merchantService.checkPayLocation(jsonObject.getString("ip"), baseInfo, jsonObject.getString("province"));
//                } catch (PayRiskException e) {
//                    throw new MsgException(e.getMessage());
//                }
//            }
            TbPlussMerchantChannelStatus channel = null;
            if("trans_wap_pay".equals(jsonObject.getString("method"))){
                channel = tbPlussMerchantChannelStatusMapper.getByMerchantCode(baseInfo.getMerchantcode(),"4");
            }else{
                channel = tbPlussMerchantChannelStatusMapper.getValidData(baseInfo.getMerchantcode());
            }
            MsgException.checkNull(channel,"无进件信息，请先提交商户信息进行审核");
            if("4".equals(channel.getChannel()) && StringUtil.isNotEmpty(jsonObject.getString("settleType"))){
                SettleTypeEnum.checkValues(jsonObject.getString("settleType"));
                channel.setSettlementtype(jsonObject.getString("settleType"));
            }
            MsgException.check("7".equals(channel.getStatus()),"快付审核中");
            MsgException.check(!channel.isPayment(),"进件未通过请耐心等待或联系客服");
            jsonObject.put("channel", channel);
            jsonObject.put("merchant", baseInfo);
            jsonObject.put("store", store);
        }
        return null;
    }



    private void checSign(JSONObject jsonObject,String merchantCode) {
        String sign = jsonObject.getString("sign");
        jsonObject.remove("sign");
        String md5Key = KEY;
        Integer storeId = jsonObject.getInteger("storeId");
        if(ObjectUtil.isNotEmpty(storeId)){
            TbPlussMerchantStore store = tbPlussMerchantStoreMapper.selectByPrimaryKey(storeId);
            MsgException.checkNull(store,"门店信息异常");
            merchantCode = store.getMerchantcode();
        }
        String phone = jsonObject.getString("phone");
        Integer sId = null;
        if(StringUtil.isNotEmpty(merchantCode)){
            TbPlussMerchantBaseInfo baseInfo = tbPlussMerchantBaseInfoMapper.selectByMerchantcode(merchantCode);
            MsgException.checkNull(baseInfo,"商户号不存在");
            if(baseInfo != null && StringUtil.isNotEmpty(baseInfo.getMd5key())){
                md5Key = baseInfo.getMd5key();
            }
        }else if(StringUtil.isNotEmpty(phone)){
            TbPlussUserInfo userInfo = tbPlussUserInfoMapper.selectByLoginName(phone);
            MsgException.checkNull(userInfo,"手机号有误！");
            TbPlussMerchantBaseInfo lists = tbPlussMerchantBaseInfoMapper.selectByUserId(userInfo.getId().toString());
            if(ObjectUtil.isEmpty(lists)){
                MsgException.throwException("商户信息异常！");
            }
            merchantCode = lists.getMerchantcode();
            TbPlussMerchantStore store = tbPlussMerchantStoreMapper.getStoreByMerchantCode(merchantCode);
            MsgException.checkNull(store,"门店信息异常！");
            sId = store.getId();
        }
        String signContent = SignUtils.getSignContent(jsonObject) + "&key=" + md5Key;
        log.info("============>签名源串:{}<==============", signContent);
        String ckeckSign = MD5Util.MD5Encode(signContent, "UTF-8");
        if (!sign.equalsIgnoreCase(ckeckSign)) {
            log.info("============>签名校验失败,我方生成签名串:{}，下游签名串：{}", ckeckSign, sign);
            throw new MsgException("签名校验失败!");
        }
        if(ObjectUtil.isNotEmpty(sId)){
            jsonObject.put("storeId",sId);
        }
    }



    private TbPlussMerchantStore checkTransPayParams(JSONObject jsonObject,String merchantCode) {
        Integer id = jsonObject.getInteger("storeId");
        TbPlussMerchantStore store = new TbPlussMerchantStore();
        if(StringUtil.isNotEmpty(merchantCode)){
            store.setMerchantcode(merchantCode);
        }else{
            store.setId(id);
        }
        if(StringUtil.isEmpty(merchantCode) && id == null){
            MsgException.throwException("缺失商户编号[merchantCode]参数！");
        }
        TbPlussMerchantStore storeInfo = tbPlussMerchantStoreMapper.selectByIdOrMerchantCode(store.getId(),store.getMerchantcode());
        Optional.ofNullable(storeInfo).orElseThrow(() -> new MsgException("店铺数据异常！"));
        String payAmt = jsonObject.getString("payAmt");
        Optional.ofNullable(payAmt).orElseThrow(() -> new MsgException("付款金额不能为空！"));
        if(StringUtil.isEmpty(storeInfo.getPayecdemicswitch()) || "0".equals(storeInfo.getPayecdemicswitch())){
            String ip = jsonObject.getString("ip");
            Optional.ofNullable(ip).orElseThrow(() -> new MsgException("付款人ip地址不能为空!"));
        }
        if (!ObjectUtil.isValidIfNumber(payAmt)) {
            throw new MsgException("交易金额格式不正确，单位(元)!");
        }
        if (Double.parseDouble(payAmt) < 0.01d) {
            throw new MsgException("交易金额最少为0.01!");
        }
        Optional.ofNullable(jsonObject.getString("notifyUrl"))
                .orElseThrow(() -> new MsgException("异步通知地址不能为空！"));
        String method = jsonObject.getString("method");
        if(!"trans_scan_pay".equals(method)){
            Optional.ofNullable(jsonObject.getString("payWay"))
                    .orElseThrow(() -> new MsgException("支付渠道不能为空！"));
        }
        if(StringUtil.isEmpty(merchantCode)){
            Optional.ofNullable(jsonObject.getString("payType"))
                    .orElseThrow(() -> new MsgException("支付方式不能为空！"));
            Optional.ofNullable(jsonObject.getString("userId"))
                    .orElseThrow(() -> new MsgException("付款用户不能为空！"));
        }
        Optional.ofNullable(jsonObject.getString("subject"))
                .orElseThrow(() -> new MsgException("订单标题不能为空！"));

        return storeInfo;
    }



    private String checkMercOrder(TbPlussMerchantStore store, JSONObject jsonObject) {

        List<TbPlussMerchantOrder> list = tbPlussMerchantOrderMapper.selectByMercorderno(jsonObject.getString("mercOrderNo"));
        if (ObjectUtil.isNotEmpty(list)&&list.size()>0) {
            TbPlussMerchantOrder order = list.get(0);
            if(StringUtil.isNotEmpty(order.getPaydata())){
                StringBuilder payData = new StringBuilder(order.getPaydata());
                payData.insert(payData.length()-1,",\"orderNumber\":"+"\""+order.getOrdernumber()+"\"");
                return payData.toString();
            }
            throw new MsgException("订单号重复!");
        }
        if ("0".equals(store.getStatus())) {
            throw new MsgException("店铺已经打烊!");
        }
        if ("2".equals(store.getStatus())) {
            throw new MsgException("店铺已被禁用!");
        }
        return null;
    }


}
