package com.prolog.cs.biz.outbound.service.impl.faceorder;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.prolog.cs.basic.common.model.BaseCommonDict;
import com.prolog.cs.biz.outbound.dao.FaceorderErrorLogMapper;
import com.prolog.cs.biz.outbound.dao.WmsFaceOrderMapper;
import com.prolog.cs.biz.outbound.model.OmsDoBillHDO;
import com.prolog.cs.biz.outbound.model.dto.faceorder.SfFaceOrderAddDTO;
import com.prolog.cs.biz.outbound.model.dto.faceorder.SfFaceOrderCdDTO;
import com.prolog.cs.biz.outbound.model.entity.FaceorderErrorLog;
import com.prolog.cs.biz.outbound.model.entity.WaveBillDDO;
import com.prolog.cs.biz.outbound.model.entity.WmsFaceOrder;
import com.prolog.cs.biz.outbound.model.vo.faceorder.FaceOrderAddVO;
import com.prolog.cs.biz.outbound.model.vo.faceorder.SfFaceOrderCdVO;
import com.prolog.cs.biz.outbound.resource.CommonClient;
import com.prolog.cs.biz.outbound.utils.HttpClientUtils;
import com.prolog.framework.common.message.RestMessage;
import com.prolog.framework.core.exception.BizException;
import com.prolog.framework.utils.MapUtils;
import com.prolog.framework.utils.UUIDUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.conn.ConnectTimeoutException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Component
public class SfFaceorderCdHandler extends BaseFaceOrderHandler{

    @Autowired
    private CommonClient commonClient;
    @Autowired
    private WmsFaceOrderMapper wmsFaceOrderMapper;
    @Autowired
    private FaceorderErrorLogMapper faceorderErrorLogMapper;

    @Override
    String getUrl() {
        BaseCommonDict baseCommonDict = getRequestUrls().stream().filter(item -> "SFCD".equals(item.getDictCode())).findFirst().orElse(null);
        if(baseCommonDict == null){
            throw new BizException("请配置顺丰快递创建面单请求地址！");
        }
        return baseCommonDict.getDictName();
    }

    @Override
    public List<WmsFaceOrder> convertResult(JSONObject result) {
        return null;
    }

    private SfFaceOrderCdVO generatearam(OmsDoBillHDO omsDoBillHDO, Integer count){
        SfFaceOrderCdVO sfFaceOrderCdVO = new SfFaceOrderCdVO();
        sfFaceOrderCdVO.setCarrierCode("SF");
        SfFaceOrderCdVO.ParamsBean paramsBean = new SfFaceOrderCdVO.ParamsBean();
        paramsBean.setOrderId(omsDoBillHDO.getBillno());
        paramsBean.setParcelQty(count);
        sfFaceOrderCdVO.setParams(paramsBean);
        return sfFaceOrderCdVO;
    }

    /**
     * 请求接口平台
     * @return
     */
    public JSONObject send(SfFaceOrderCdVO vo){
        String url = getUrl();
        log.info("请求创建面单url：{}", JSON.toJSONString(url));
        String param = JSON.toJSONString(vo);
        log.info("请求创建面单param：{}", param);
        JSONObject result = null;
        try {
            result = HttpClientUtils.postByJson(url, param);
        }catch (Exception e){
            //如果是链接超时，则再重新请求一次
            if(e.getClass().isInstance(ConnectTimeoutException.class)){
                //重试次数
                int times ;
                RestMessage<List<BaseCommonDict>> restMessage = commonClient.getDictBasicListByCodes("face_order_retry_times", null);
                if(restMessage == null || !restMessage.isSuccess() || restMessage.getData() == null || restMessage.getData().size() <= 0){
                    times = 1;
                }else {
                    times = Integer.parseInt(restMessage.getData().get(0).getAttr1());
                }
                for (int i = 0; i < times; i++) {
                    try {
                        result = HttpClientUtils.postByJson(url, param);
                        break;
                    }catch (Exception e2){
                        e2.printStackTrace();
                        result = new JSONObject();
                        result.put("success",false);
                        result.put("msg",false);
                    }
                }

            }
        }

        //判断错误码是否需要重试
        RestMessage<List<BaseCommonDict>> restMessage = commonClient.getDictBasicListByCodes("face_order_error_code", null);
        if(restMessage == null || !restMessage.isSuccess() || restMessage.getData() == null || restMessage.getData().size() <= 0){
            return result;
        }
        List<BaseCommonDict> baseCommonDicts = restMessage.getData();
        BaseCommonDict baseCommonDict = baseCommonDicts.stream().filter(item -> item.getDictCode().equals(vo.getCarrierCode())).findFirst().orElse(null);
        if(baseCommonDict == null){
            return result;
        }
        Object code = result.get("code");
        String errorCode = String.valueOf(code);
        if(Arrays.asList(baseCommonDict.getAttr1().split(",")).contains(errorCode)){
            //重试次数
            int times ;
            RestMessage<List<BaseCommonDict>> retryTimes = commonClient.getDictBasicListByCodes("face_order_retry_times", null);
            if(retryTimes == null || !retryTimes.isSuccess() || retryTimes.getData() == null || retryTimes.getData().size() <= 0){
                times = 1;
            }else {
                times = Integer.parseInt(retryTimes.getData().get(0).getAttr1());
            }
            for (int i = 0; i < times; i++) {
                try {
                    result = HttpClientUtils.postByJson(url, param);
                    break;
                }catch (Exception e2){
                    e2.printStackTrace();
                    result = new JSONObject();
                    result.put("success",false);
                    result.put("msg",false);
                }
            }
        }
        log.info("请求创建面单返回结果：{}",JSON.toJSONString(result));
//        return JSON.parseObject(result.toJSONString(), RestMessage.class);
        JSONObject apiResultData = result.getJSONObject("apiResultData");
        boolean success = apiResultData.getBoolean("success");
        String result_str = JSON.toJSONString(result);
        if(!success){
            new Thread(()-> {

                log.error("获取面单失败：{}");
                this.saveErrorlog(url,vo.getParams().getOrderId(),JSON.toJSONString(vo),result_str,vo.getLastFlag());
            }).start();
        }
        return result;
    }


    private List<WmsFaceOrder> convertResult(JSONObject result,String billNo) {

        if(result == null ){
            throw new BizException("请求面单失败!");
        }
        String apiResultData = result.getString("apiResultData");
        apiResultData.replaceAll("/","");
        SfFaceOrderCdDTO sfFaceOrderCdDTO = JSON.parseObject(apiResultData, SfFaceOrderCdDTO.class);

        if(!sfFaceOrderCdDTO.isSuccess()){
            throw new BizException("请求面单失败!");
        }

        List<WmsFaceOrder> faceOrders = wmsFaceOrderMapper.findByMap(MapUtils.put("billNo", billNo).getMap(), WmsFaceOrder.class);
        if(faceOrders == null || faceOrders.size() <= 0){
            throw new BizException("查询已获取面单失败!");
        }
        List<WmsFaceOrder> wmsFaceOrders = new ArrayList<>();

        List<SfFaceOrderCdDTO.MsgDataBean.WaybillNoInfoListBean> waybillNoInfoList = sfFaceOrderCdDTO.getMsgData().getWaybillNoInfoList();
        SfFaceOrderCdDTO.MsgDataBean.WaybillNoInfoListBean parentBean = waybillNoInfoList.stream().filter(item -> item.getWaybillType() == 1).findFirst().get();
        waybillNoInfoList = waybillNoInfoList.stream().filter(item -> item.getWaybillType() == 2).collect(Collectors.toList());
        for (SfFaceOrderCdDTO.MsgDataBean.WaybillNoInfoListBean bean : waybillNoInfoList) {

            WmsFaceOrder wmsFaceOrder = faceOrders.get(0);

            WmsFaceOrder faceOrder = new WmsFaceOrder();
            faceOrder.setId(UUIDUtils.generateWithoutSeperator());
            faceOrder.setBillNo(billNo);
            faceOrder.setParentWaybillCode(parentBean.getWaybillNo());
            faceOrder.setWaybillCode(bean.getWaybillNo());
            faceOrder.setProCode(wmsFaceOrder.getProCode());
            faceOrder.setPosition(wmsFaceOrder.getPosition());
            faceOrder.setPositionNo(wmsFaceOrder.getPositionNo());
            faceOrder.setQrCode(wmsFaceOrder.getQrCode());

            faceOrder.setSenderName(wmsFaceOrder.getSenderName());
            faceOrder.setSenderAddress(wmsFaceOrder.getSenderAddress());
            faceOrder.setSenderMobile(wmsFaceOrder.getSenderMobile());
            faceOrder.setReceiverName(wmsFaceOrder.getReceiverName());
            faceOrder.setReceiverAddress(wmsFaceOrder.getReceiverAddress());
            faceOrder.setReceiverMobile(wmsFaceOrder.getReceiverMobile());

            wmsFaceOrders.add(faceOrder);
        }

        return wmsFaceOrders;
    }

    /**
     * 获取面单
     * @param omsDoBillHDO
     * @param waveBillDDOS
     * @return
     */
    @Override
    public List<String> getFaceOrderNo(OmsDoBillHDO omsDoBillHDO, List<WaveBillDDO> waveBillDDOS, Integer count){
        SfFaceOrderCdVO vo = generatearam(omsDoBillHDO, count);
        JSONObject result  = send(vo);

        List<WmsFaceOrder> wmsFaceOrders = this.convertResult(result,omsDoBillHDO.getBillno());

        saveWmsFaceOrder(wmsFaceOrders);
        return wmsFaceOrders.stream().map(WmsFaceOrder :: getWaybillCode).collect(Collectors.toList());
    }


    private void saveErrorlog(String url,String billno,String param,String result,String lastFlag){
        FaceorderErrorLog faceorderErrorLog = new FaceorderErrorLog();
        faceorderErrorLog.setId(UUIDUtils.generateWithoutSeperator());
        faceorderErrorLog.setBillno(billno);
        faceorderErrorLog.setCarrierCode("SF");
        faceorderErrorLog.setRequestUrl(url);
        faceorderErrorLog.setRequestParam(param);
        faceorderErrorLog.setRequestResult(result);
        faceorderErrorLog.setAttrStr1(lastFlag);

        faceorderErrorLog.setCreator("SYS");
        faceorderErrorLog.setGmtCreate(new Date());
        faceorderErrorLogMapper.save(faceorderErrorLog);
    }
}
