package com.gree.mall.manager.logic;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.gson.Gson;
import com.gree.mall.manager.enums.OrderStatusEnum;
import com.gree.mall.manager.exception.RemoteServiceException;
import com.gree.mall.manager.logic.common.kuaidi100.api.Subscribe;
import com.gree.mall.manager.logic.common.kuaidi100.request.SubscribeReq;
import com.gree.mall.manager.logic.common.kuaidi100.response.SubscribePushData;
import com.gree.mall.manager.logic.common.kuaidi100.response.SubscribePushParamResp;
import com.gree.mall.manager.logic.common.kuaidi100.response.SubscribeResp;
import com.gree.mall.manager.logic.order.OrderLogic;
import com.gree.mall.manager.plus.entity.ExpressCompany;
import com.gree.mall.manager.plus.entity.ExpressInfo;
import com.gree.mall.manager.plus.entity.OrderInfo;
import com.gree.mall.manager.plus.entity.OrderShare;
import com.gree.mall.manager.plus.service.ExpressCompanyService;
import com.gree.mall.manager.plus.service.ExpressInfoService;

import com.gree.mall.manager.plus.service.OrderInfoService;
import com.gree.mall.manager.plus.service.OrderShareService;
import com.gree.mall.manager.utils.DateUtils;
import com.gree.mall.manager.utils.HttpUtils;
import com.gree.mall.manager.utils.MD5Utils;
import jodd.util.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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


/**
 * 快递物流
 * created by lijh
 * 2019-07-23
 */
@Service
@Slf4j
public class ExpressLogic {

    private final static String expressQueryUrl = "https://poll.kuaidi100.com/poll/query.do";
    private final static String expressPollUrl = "https://poll.kuaidi100.com/poll";
    //    private final static String callBackUrl = "http://121.43.111.127:9003/common/express/callback";
    private final static String customer = "4A7813B781DCAB6D1975A79DF86B96ED";
    private final static String key = "yzXRZXXI1802";
    @Value("${express.callback}")
    private String callBackUrl;
    @Autowired
    ExpressInfoService expressInfoService;
    @Autowired
    private Subscribe subscribe;
    @Autowired
    OrderLogic orderLogic;
    @Autowired
    ExpressCompanyService expressCompanyService;


    public static void main(String[] args) throws RemoteServiceException {
        //new ExpressLogic().queryKuaidi100("SF6090936089645");
        //new ExpressService().subscribeKuaidi100("71698005085320");
        //new ExpressService().subscribeKuaidi100("3718371072077");
        //System.out.print(DateUtils.dateToWeek("2019-07-25 20:44:39"));
    }

    /**
     * 查询所有物流公司
     */
    public List<ExpressCompany> expressCompanyList() {
        return expressCompanyService.list();
    }

    /**
     * 根据code查询公司
     */
    public String expressCompanyName(String code) {
        return expressCompanyService.lambdaQuery().eq(ExpressCompany::getCode, code).one().getName();
    }

    /**
     * 根据name查询公司
     */
    public ExpressCompany expressCompany(String name) {
        return expressCompanyService.lambdaQuery().eq(ExpressCompany::getName, name).one();
    }


    /**
     * 默认使用顺丰
     *
     * @param logisticsNo
     * @throws RemoteServiceException
     */
    public List<ExpressInfo> queryKuaidi100(String logisticsNo, String company) throws RemoteServiceException {

        if (StringUtils.isEmpty(logisticsNo)) {
            return new ArrayList<>();
        }

        //先查询本地数据库是否有已签收数据
        List<ExpressInfo> list = expressInfoService.lambdaQuery().eq(ExpressInfo::getLogisticsNo, logisticsNo).eq(ExpressInfo::getState, 3).list();
        if (CollectionUtils.isNotEmpty(list)) {
            return list;
        }

        if (StringUtils.isEmpty(company)) {
            company = "shunfeng";
        }

        Map<String, Object> param = new HashMap<>();
        param.put("com", company);
        param.put("num", logisticsNo);

        String sign = MD5Utils.md5(JSONObject.toJSONString(param) + key + customer).toUpperCase();

        Map<String, String> map = new HashMap<>();
        map.put("customer", customer);
        map.put("sign", sign);
        map.put("param", JSONObject.toJSONString(param));
        log.info("【快递100实时查询】request:" + JSONObject.toJSONString(map));
        String s = HttpUtils.requestPostForm(expressQueryUrl, map, null);
        log.info("【快递100实时查询】response:" + s);

        JSONObject lastResult = JSONObject.parseObject(s);
        if (!StringUtils.equals(lastResult.getString("status"), "200")) {
            throw new RemoteServiceException(1100, lastResult.getString("message"));
        }
        String com = lastResult.get("com").toString();
        String state = lastResult.get("state").toString();
        List<ExpressInfo> datas = JSONArray.parseArray(lastResult.get("data").toString(), ExpressInfo.class);
        for (ExpressInfo data : datas) {
            data.setCreateTime(new Date());
            data.setCom(com);
            data.setComName(this.expressCompanyName(com));
            data.setLogisticsNo(logisticsNo);
            data.setState(Integer.parseInt(state));
            data.setWeek(DateUtils.dateToWeek(data.getTime()));
        }
        //先删后存
        expressInfoService.lambdaUpdate().eq(ExpressInfo::getLogisticsNo, logisticsNo).remove();
        expressInfoService.saveBatch(datas);
        return datas;
    }

    public List<ExpressInfo> queryExpress(String logisticsNo, String company) {

        if (StringUtils.isEmpty(logisticsNo)) {
            return new ArrayList<>();
        }

        //先查询本地数据库是否有已签收数据
        List<ExpressInfo> list = expressInfoService.lambdaQuery()
                .eq(ExpressInfo::getLogisticsNo, logisticsNo)
                .eq(StringUtils.isNotEmpty(company),ExpressInfo::getCom, company)
                .list();
        if (CollectionUtils.isNotEmpty(list)) {
            return list;
        } else {
//            subscribeExpress(logisticsNo, company);
            return null;
        }
    }

    //@Async
    public void subscribeExpress(String logisticsNo, String company,String phone) {
        if (StringUtils.isEmpty(logisticsNo) ||"123456".equals(logisticsNo)|| "qita".equals(company)) {
            return;
        }

        Map<String, Object> param = new HashMap<>();
        param.put("company", company);
        param.put("number", logisticsNo);
        param.put("key", key);
        Map<String, Object> callback = new HashMap<>();
        callback.put("phone",phone);
        callback.put("callbackurl", callBackUrl);
        param.put("parameters", callback);
        param.put("resultv2", "1");

        SubscribeReq subscribeReq = new SubscribeReq();
        subscribeReq.setSchema("json");
        subscribeReq.setParam(new Gson().toJson(param));
        try {
            subscribe.subscribe(subscribeReq);
        } catch (Exception e) {
            log.info("快递100订阅失败{}",e.getMessage());
        }

    }


    public void expressCallBack(HttpServletRequest request) throws Exception {
        SubscribePushParamResp subscribePushParamResp = subscribe.callBackUrl(request);
        if (subscribePushParamResp == null) {
            return;
        }
        String logisticsNo = "";
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        List<ExpressInfo> expressInfoList = new ArrayList<>();
        for (SubscribePushData data : subscribePushParamResp.getLastResult().getData()) {
            ExpressInfo expressInfo = new ExpressInfo();
            expressInfo.setCreateTime(new Date());
            try {
                expressInfo.setTime(sdf.parse(data.getTime()));
            } catch (ParseException e) {
                e.printStackTrace();
            }
            expressInfo.setCom(subscribePushParamResp.getLastResult().getCom());
            expressInfo.setComName(this.expressCompanyName(subscribePushParamResp.getLastResult().getCom()));
            logisticsNo = subscribePushParamResp.getLastResult().getNu();
            expressInfo.setLogisticsNo(subscribePushParamResp.getLastResult().getNu());
            expressInfo.setState(Integer.parseInt(subscribePushParamResp.getLastResult().getState()));
            expressInfo.setContext(data.getContext());
            try {
                expressInfo.setWeek(DateUtils.dateToWeek(data.getTime()));
            } catch (ParseException e) {
                expressInfo.setWeek("");
            }
            expressInfoList.add(expressInfo);
        }
        //先删后存
        expressInfoService.lambdaUpdate().eq(ExpressInfo::getLogisticsNo, logisticsNo).remove();
        expressInfoService.saveBatch(expressInfoList);
        //更新订单已签收
        orderLogic.overOrder(subscribePushParamResp);
    }

//
//    /**
//     * 保存订阅过的快递记录
//     */
//    public void saveExpressSub(String logisticsNo){
//        ExpressSub expressSub = new ExpressSub();
//        expressSub.setCreateTime(new Date());
//        expressSub.setId(commonService.getPKID());
//        expressSub.setLogisticsNo(logisticsNo);
//        expressSubMapper.insertSelective(expressSub);
//    }
//
//    /**
//     * 订阅快递100
//     * @param logisticsNo
//     */
//    public  void subscribeKuaidi100(String logisticsNo) throws CommonException {
//
//        Map<String,String> param = kuaidi100Param(logisticsNo);
//
//        log.info("【订阅快递100,request】:"+param);
//        //String result = HttpUtil.sendPost(expressPollUrl,param);
//        String result = HttpUtils.requestPostForm(expressPollUrl, param, null);
//        log.info("【订阅快递100,response】:"+result);
//
//        JSONObject jsonObject = JSONObject.parseObject(result);
//        String resultCode = jsonObject.get("returnCode").toString();
//        if( ! StringUtils.equals(resultCode,"200")){
//            throw  new CommonException(resultCode + "&" +jsonObject.get("message").toString());
//        }
//    }
//
//    /**
//     * 订阅回调
//     * @param param
//     * @param callbackid
//     * @return 订阅回调
//     */
//    public String expressCall(String param,String callbackid){
//
//        log.info("【快递100回调】callbackid:"+callbackid+",param:"+param);
//        JSONObject jsonObject = JSONObject.parseObject(param);
//        Map<String, Object> lastResult = JSONObject.parseObject(jsonObject.get("lastResult").toString(),Map.class);
//        String status = lastResult.get("status").toString();
//        String message = lastResult.get("message").toString();
//        if( ! StringUtils.equals(status,"200")){
//            log.error("快递100回调失败,"+message);
//            return "";
//        }
//        String com = lastResult.get("com").toString();
//        String state =lastResult.get("state").toString();
//        List<ExpressInfo> datas = JSONArray.parseArray(lastResult.get("data").toString(), ExpressInfo.class);
//        for(ExpressInfo data:datas){
//            data.setCreateTime(new Date());
//            data.setExpressId(commonService.getPKID());
//            data.setCom(com);
//            data.setComName(ExpressCompanyEnum.valueOf(com).getName());
//            data.setLogisticsNo(callbackid);
//            data.setState(Integer.parseInt(state));
//            data.setWeek(DateUtils.dateToWeek(data.getTime()));
//            expressInfoMapper.insertSelective(data);
//        }
//
//        return ExpressCompanyEnum.valueOf(com).getName();
//    }


//
//    private  Map<String,String> kuaidi100Param(String number){
//
//        callbackUrl += number;
//
//        Map<String,Object> parameters = new HashMap<>();
//        parameters.put("callbackurl",callbackUrl);
//        parameters.put("autoCom","1");
//
//        Map<String,Object> param = new HashMap<>();
//        param.put("company","");
//        param.put("number",number);
//        param.put("key",key);
//        param.put("parameters",parameters);
//
//
//        Map<String,String> map = new HashMap<>();
//        map.put("schema","json");
//        map.put("param",JSONObject.toJSONString(param));
//
//        return map;
//
//    }


}
