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.accounts.service.MpAccountsService;
import com.cftech.base.codingrule.utils.CodingruleUtils;
import com.cftech.core.sql.Conds;
import com.cftech.core.util.*;
import com.cftech.logistics.model.Logistics;
import com.cftech.logistics.service.LogisticsService;
import com.cftech.member.model.Member;
import com.cftech.member.service.MemberService;
import com.cftech.mp.fans.model.MpFanssEntity;
import com.cftech.mp.fans.service.MpFanssService;
import com.cftech.order.model.Order;
import com.cftech.order.service.OrderService;
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.*;

/**
 * 同步顺丰物流节点接口
 * 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);
        OrderService orderService = SpringContextHolder.getBean(OrderService.class);
        MpAccountsService mpAccountsService = SpringContextHolder.getBean(MpAccountsService.class);
        MemberService memberService = SpringContextHolder.getBean(MemberService.class);
        MpFanssService fanssService = SpringContextHolder.getBean(MpFanssService.class);
        CodingruleUtils codingruleUtils = SpringContextHolder.getBean(CodingruleUtils.class);

        String appId = SystemConfig.p.getProperty("WX_MP_SERVER_APPID");
        Long accoountId = mpAccountsService.getMpAccountsAppid(appId).getId();

        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(result.getString("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("mail_no", mailNo);
                                routConds.equal("del_flag", Constants.DEL_FLAG_0);
                                routConds.equal("opcode", routObj.getString("opCode"));
                                routConds.equal("number", routObj.getString("remark"));
                                Logistics logistics = logisticsService.fetchSearchByConds(routConds);
                                if (logistics == null) {
                                    //路由事件节点
                                    Date acceptTime = DateFormatUtils.formatDate(routObj.getString("acceptTime"), "yyyy-MM-dd HH:mm:ss");

                                    logistics = new Logistics();
                                    logistics.setAccountsId(accoountId);
                                    logistics.setMailNo(mailNo);
                                    logistics.setOrderNo(waybill.getOrderCode());
                                    logistics.setAcceptTime(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(acceptTime);
                                        waybillService.update(waybill);
                                    }

                                    //订单签收
                                    if (StringUtils.equals(routObj.getString("opCode"), "80")) {
                                        waybill.setAcceptExpressDate(acceptTime);
                                        waybillService.update(waybill);

                                        //回写订单已完成状态
                                        Conds orderConds = new Conds();
                                        orderConds.equal("o.del_flag", Constants.DEL_FLAG_0);
                                        orderConds.equal("o.id", waybill.getOrderId());
                                        Order order = orderService.fetchSearchByConds(orderConds);
                                        if (order != null) {
                                            order.setStatus("4");
                                            orderService.update(order);
                                        }

                                        Conds memberConds = new Conds();
                                        memberConds.equal("del_flag", Constants.DEL_FLAG_0);
                                        memberConds.equal("open_id", order.getOpenid());
                                        Member member = memberService.fetchSearchByConds(memberConds);
                                        if (member == null) {
                                            MpFanssEntity fanssEntity = fanssService.getWxUser(order.getOpenid());
                                            //生成会员数据
                                            member = new Member();
                                            member.setNumber(codingruleUtils.getNumber(fanssEntity.getMpaccountid(), Member.class.getName()));
                                            member.setName(fanssEntity.getNickname());
                                            member.setImageurl(fanssEntity.getHeadimgurl());
                                            member.setSex(Long.parseLong(fanssEntity.getSex()));
                                            memberService.save(member);
                                        }

                                    }
                                }
                            }
                        }
                    }
                }

            }
        }

        //获得明细数据
        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("顺丰路由查询接口调用任务，已执行完成！");
        }
    }
}
