package com.cftech.waybill.job;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.cftech.accounts.model.SysJob;
import com.cftech.accounts.service.JobService;
import com.cftech.core.sql.Conds;
import com.cftech.core.util.Constants;
import com.cftech.core.util.SpringContextHolder;
import com.cftech.core.util.StringUtils;
import com.cftech.core.util.SystemConfig;
import com.cftech.logistics.model.Logistics;
import com.cftech.logistics.service.LogisticsService;
import com.cftech.waybill.model.Waybill;
import com.cftech.waybill.service.WaybillService;
import com.cftech.waybill.utils.CloseableHttpEntity;
import com.cftech.waybill.utils.ExpressOrderInfoUtils;
import com.cftech.waybill.utils.FqConstants;
import com.cftech.waybill.utils.FqHttpUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.message.BasicNameValuePair;
import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 同步顺丰物流节点接口
 * Created by 16444 on 2020/11/29.
 */
@Slf4j
public class WaybillRouterJob implements Job {

    public static Map<String, String> routeCode = new HashMap<>();

    static {
        routeCode.put("30", "快件在【POINT营业点】已装车,准备发往 【CENTER集散中心】");
        routeCode.put("31", "快件到达 【CENTER集散中心】");
        routeCode.put("33", "派件异常原因");
        routeCode.put("44", "正在派送途中,请您准备签收(派件人:NAME,电话:MOBILE)");
        routeCode.put("50", "顺丰已收件");
        routeCode.put("70", "由于REASON原因 派件不成功");
        routeCode.put("80", "已签收,感谢使用顺丰,期待再次为您服务");
        routeCode.put("99", "应客户要求,快件正在转寄中");
        routeCode.put("123", "快件正送往顺丰店/站");
        routeCode.put("130", "快件到达顺丰店/站");
        routeCode.put("607", "代理收件");
        routeCode.put("648", "快件已退回/转寄,新单号为: NUMBER");
        routeCode.put("3036", "快件在ADDRESS,准备送往下一站");
        routeCode.put("8000", "在官网运单资料&签收图,可查看签收人信");
    }

    private String sendRemark(String no, String address) {
        return null;
    }

    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        boolean isCluster = Boolean.valueOf(SystemConfig.p.getProperty("quartz.isCluster"));
        if (!isCluster) {
            return;
        }

        WaybillService waybillService = SpringContextHolder.getBean(WaybillService.class);
        LogisticsService logisticsService = SpringContextHolder.getBean(LogisticsService.class);

        Conds conds = new Conds();
        conds.isNull("t.accept_express_date");
        conds.equal("t.del_flag", Constants.DEL_FLAG_0);
        List<Waybill> waybillList = waybillService.fetchSearchByPage(conds, null, 0, 0);

        for (Waybill waybill: waybillList) {
            JSONObject Waybillobj = ExpressOrderInfoUtils.generateRouteData(waybill);
            Long timestamp = System.currentTimeMillis();//时间戳
            String checkWord = SystemConfig.p.getProperty("sf.checkWord");
            String msgDigest = ExpressOrderInfoUtils.generateSfDigest(Waybillobj.toString(), timestamp, checkWord);
            List<BasicNameValuePair> content = new ArrayList<>();
            content.add(new BasicNameValuePair("partnerID", SystemConfig.p.getProperty("sf.partnerID")));//合作伙伴编码、顾客编码
            content.add(new BasicNameValuePair("requestID", FqHttpUtils.generateUUID()));
            content.add(new BasicNameValuePair("serviceCode", FqConstants.SF_ORDER_ROUTE_CODE));//接口服务代码
            content.add(new BasicNameValuePair("timestamp", String.valueOf(timestamp)));
            content.add(new BasicNameValuePair("msgDigest", msgDigest));
            content.add(new BasicNameValuePair("msgData", Waybillobj.toString()));
            CloseableHttpEntity closeableHttpEntity = FqHttpUtils.sendHttpPost(FqConstants.SF_ORDER_ROUTE_URL, content);

            if (closeableHttpEntity != null && closeableHttpEntity.getCode() == 200) {

                if (closeableHttpEntity.getRetObj().containsKey("apiResultCode") &&
                        StringUtils.equals(closeableHttpEntity.getRetObj().getString("apiResultCode"), "A1000")) {

                    JSONObject result = closeableHttpEntity.getRetObj().getJSONObject("apiResultData");
                    if (result.getBoolean("success") && StringUtils.equals("errorCode", "S0000")) {
                        JSONObject msgData = result.getJSONObject("msgData");
                        JSONArray routeResps = msgData.getJSONArray("routeResps");
                        for (int i = 0; i<routeResps.size(); i++) {
                            JSONObject routeResObj = routeResps.getJSONObject(i);
                            String mailNo = routeResObj.getString("mailNo");
                            JSONArray routes = routeResObj.getJSONArray("routes");
                            for (int y=0; y<routes.size(); y++) {
                                JSONObject routObj = routes.getJSONObject(y);
                                Conds routConds = new Conds();
                                routConds.equal("del_flag", Constants.DEL_FLAG_0);
                                routConds.equal("opcode", routObj.getString("opcode"));
                                routConds.equal("mail_no", waybill.getNumber());
                                Logistics logistics =logisticsService.fetchSearchByConds(routConds);
                                if (logistics == null) {
                                    logistics = new Logistics();
                                    logistics.setMailNo(waybill.getNumber());
                                    logistics.setOrderNo(waybill.getOrderCode());
                                    logistics.setAcceptTime(routObj.getDate("acceptTime"));
                                    logistics.setAcceptAddress(routObj.getString("acceptAddress"));
                                    logistics.setNumber(routObj.getString("remark"));
                                    logistics.setOpcode(routObj.getString("opcode"));
                                    logisticsService.save(logistics);
                                }

                                if (StringUtils.equals(routObj.getString("opcode"), "50")) {
                                    waybill.setSendExpressDate(routObj.getDate("acceptTime"));
                                    waybillService.update(waybill);
                                }

                                if (StringUtils.equals(routObj.getString("opcode"), "80")) {
                                    waybill.setAcceptExpressDate(routObj.getDate("acceptTime"));
                                    waybillService.update(waybill);
                                }
                            }
                        }
                    }
                }

            }
        }

        //获得明细数据
        JobDataMap jobInfo = context.getJobDetail().getJobDataMap();
        String id = jobInfo.get("uid") == null ? "" : jobInfo.getString("uid");//这个也是ID主键
        log.info("任务ID：" + id);

        //执行更新操作
        if (context.getNextFireTime() != null) {
            log.info("顺丰路由查询接口调用：下次执行时间=====" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(context.getNextFireTime()) + "==============");
        } else {
            JobService jobService = SpringContextHolder.getBean(JobService.class);
            SysJob sysJob = new SysJob();
            sysJob.setJobuid(id);
            sysJob.setStatus("0");
            jobService.updateStatus(sysJob);
            log.info("顺丰路由查询接口调用任务，已执行完成！");
        }
    }
}
