package com.reptileclient.jlifeapp.service.impl;


import com.alibaba.fastjson.JSON;
import com.reptileclient.jlifeapp.dao.jz.CustomerClientMapper;
import com.reptileclient.jlifeapp.dao.qg.JzOrderQgMapper;
import com.reptileclient.jlifeapp.dao.qg.QGLoginMapper;
import com.reptileclient.jlifeapp.entity.jz.CustomerClient;
import com.reptileclient.jlifeapp.entity.qg.JzOrderQg;
import com.reptileclient.jlifeapp.entity.qg.WorkerInfo;
import com.reptileclient.jlifeapp.service.QGOrderSyncService;
import com.reptileclient.jlifeapp.util.OkHttpUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.sql.Date;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;

@Service
public class QGOrderSyncServiceImpl implements QGOrderSyncService {

    private static final Logger log = LoggerFactory.getLogger(QGOrderSyncServiceImpl.class);
    @Autowired
    private QGLoginMapper qgLoginMapper;

    @Autowired
    private JzOrderQgMapper jzOrderQGMapper;

    @Autowired
    private CustomerClientMapper customerClientMapper;


    @Override
    public void recoupQgCityData(String shopId) {
        String sessionId = qgLoginMapper.getSessionId();
        LocalDateTime nowTime = LocalDateTime.now().withMonth(1).withDayOfMonth(1).withHour(0).withMinute(0).withSecond(0);
        LocalDateTime startTime = nowTime.minusMonths(24);
        List<JzOrderQg> finalQg = new ArrayList<>();
        List<JzOrderQg> finalSelf = new ArrayList<>();
        String validToken = "";
        for (int i = 0; i < 20; i++) {
            long startTimeStamp = startTime.plusMonths(i).atZone(ZoneId.systemDefault()).toEpochSecond() * 1000;
            long endTimeStamp = startTime.plusMonths(i + 1).atZone(ZoneId.systemDefault()).toEpochSecond() * 1000;
            List<JzOrderQg> qgList = jzOrderQGMapper.selectByCreateTime(startTimeStamp, endTimeStamp);
            Map<String, Object> objectMap;
            objectMap = OkHttpUtil.get(startTimeStamp, endTimeStamp, shopId, sessionId, false);
            if (objectMap.isEmpty()) {
                continue;
            }
            List<WorkerInfo> o = (List<WorkerInfo>) objectMap.get("workerInfo");
            if (StringUtils.isEmpty(validToken)) {
                validToken = (String) objectMap.get("validToken");
            }
            if (o.size() > 0) {
                List<JzOrderQg> orderQgs = convertWorkerToOrder(o);
                finalQg.addAll(orderQgs);
            }
            finalSelf.addAll(qgList);
        }
        compareAndInsertOrUpdate(finalSelf, finalQg, validToken);
        jzOrderQGMapper.deleteDuplicate();
    }


    @Override
    public void syncOrder() {
        String sessionId = qgLoginMapper.getSessionId();
        int count = jzOrderQGMapper.selectCount();
        Map<String, String> shopIdNameMap = new HashMap<>();
        shopIdNameMap.put("10000257", "上海门店");
//        shopIdNameMap.put("10000276", "北京门店");
//        shopIdNameMap.put("10000277", "深圳门店");
//        shopIdNameMap.put("10002854", "南京门店");
//        shopIdNameMap.put("10002870", "苏州门店");
//        shopIdNameMap.put("10006927", "杭州门店");
        if (count == 0) {
            //全量同步
            long startTime = LocalDate.now().withYear(2020).withDayOfYear(1)
                    .atTime(0, 0, 0).atZone(ZoneId.systemDefault()).toEpochSecond() * 1000;
            long endTime = LocalDateTime.now().atZone(ZoneId.systemDefault()).toEpochSecond() * 1000;
            for (String shopId : shopIdNameMap.keySet()) {
                Map<String, Object> objectMap;
                objectMap = OkHttpUtil.get(startTime, endTime, shopId, sessionId, false);
                log.info("查询{}信息成功", shopIdNameMap.get(shopId));
                if (objectMap.isEmpty()) {
                    continue;
                }
                if (!((boolean) objectMap.get("resStatus"))) {
                    continue;
                }
                List<WorkerInfo> o = new ArrayList<>((List<WorkerInfo>) objectMap.get("workerInfo"));
                if (!o.isEmpty()) {
                    jzOrderQGMapper.batchInsert(convertWorkerToOrder(o));
                }
            }

        } else {
            //  线上案例 有个客户 12-14下单，02-22 预约 修改 同步时间为最近6个月
            // 再次 发现 有人 11月购买的，7月过来预约，修改成12个月 2082210796482579059
            LocalDateTime nowTime = LocalDateTime.now();
            LocalDateTime startTime = nowTime.minusMonths(12);
            long now = nowTime.atZone(ZoneId.systemDefault()).toEpochSecond() * 1000;
            List<JzOrderQg> finalQg = new ArrayList<>();
            List<JzOrderQg> finalSelf = new ArrayList<>();
            String validToken = "";
            for (int i = 0; i < 12; i++) {
                long startTimeStamp = startTime.plusMonths(i).atZone(ZoneId.systemDefault()).toEpochSecond() * 1000;
                long endTimeStamp = startTime.plusMonths(i + 1).atZone(ZoneId.systemDefault()).toEpochSecond() * 1000;
                List<JzOrderQg> qgList = jzOrderQGMapper.selectByCreateTime(startTimeStamp, endTimeStamp);
                for (String shopId : shopIdNameMap.keySet()) {
                    Map<String, Object> objectMap;
                    objectMap = OkHttpUtil.get(startTimeStamp, endTimeStamp, shopId, sessionId, false);
                    if (objectMap.isEmpty()) {
                        continue;
                    }
                    if (!((boolean) objectMap.get("resStatus"))) {
//                    SendSms.toSendMs();
                        log.warn("抓取勤鸽订单失败，勤鸽返回数据：" + JSON.toJSONString(objectMap));
                        continue;
                    }
                    List<WorkerInfo> o = (List<WorkerInfo>) objectMap.get("workerInfo");
                    if (StringUtils.isEmpty(validToken)) {
                        validToken = (String) objectMap.get("validToken");
                    }
                    if (o.size() > 0) {
                        List<JzOrderQg> orderQgs = convertWorkerToOrder(o);
                        finalQg.addAll(orderQgs);
                    }
                    finalSelf.addAll(qgList);
                }
            }
            compareAndInsertOrUpdate(finalSelf, finalQg, validToken);
            jzOrderQGMapper.deleteDuplicate();
            // 新增 7天内 工单核销时间抓取  和 所有已取消的工单
            long sevenDayBefore = nowTime.minusDays(7).atZone(ZoneId.systemDefault()).toEpochSecond() * 1000;
            List<String> waitUpdate = new ArrayList<>();
            for (String shopId : shopIdNameMap.keySet()) {
                Map<String, Object> objectMap;
                objectMap = OkHttpUtil.getFinshTime(sevenDayBefore, now, shopId, sessionId);
                if (objectMap.size() == 0) {
                    continue;
                }
                if (!((boolean) objectMap.get("resStatus"))) {
                    log.warn("抓取勤鸽7日工单核销信息失败，勤鸽返回数据：" + JSON.toJSONString(objectMap));
//                    SendSms.toSendMs();
                    continue;
                }
                List<WorkerInfo> o = (List<WorkerInfo>) objectMap.get("workerInfo");
                if (o.size() > 0) {
                    log.info("{}核销的工单数量：{}", shopIdNameMap.get(shopId), o.size());
                    waitUpdate.addAll(convertWorkerToOrder(o).stream().map(JzOrderQg::getOutId).collect(Collectors.toList()));
                }
            }
            if (waitUpdate.size() > 0) {
                log.info("本次更新工单核销的数量：" + waitUpdate.size());
                jzOrderQGMapper.updateBatchByOutId(waitUpdate, "complete", "完成");
            }
            waitUpdate.clear();
            //获取所有已取消的工单
            for (String shopId : shopIdNameMap.keySet()) {
                Map<String, Object> objectMap;
                objectMap = OkHttpUtil.queryStatus(shopId, sessionId);
                if (objectMap.size() == 0) {
                    continue;
                }
                if (!((boolean) objectMap.get("resStatus"))) {
                    log.warn("抓取勤鸽所有已取消工单信息失败，勤鸽返回数据：" + JSON.toJSONString(objectMap));
//                    SendSms.toSendMs();
                }
                List<WorkerInfo> o = (List<WorkerInfo>) objectMap.get("workerInfo");
                if (o.size() > 0) {
                    log.info("{}取消的工单数量：{}", shopIdNameMap.get(shopId), o.size());
                    waitUpdate.addAll(convertWorkerToOrder(o).stream().map(JzOrderQg::getOutId).collect(Collectors.toList()));
                }
            }
            if (waitUpdate.size() > 0) {
                log.info("本次更新工单取消的数量：" + waitUpdate.size());
                jzOrderQGMapper.updateBatchByOutId(waitUpdate, "cancel", "取消");
            }
        }

    }


    public void syncQGSHOrder() {
        String sessionId = qgLoginMapper.getSessionId();
        LocalDateTime startDay = LocalDate.now().withYear(2020).withDayOfYear(1)
                .atTime(0, 0, 0);
        long startTime = startDay.atZone(ZoneId.systemDefault()).toEpochSecond() * 1000;
        LocalDateTime endDay = LocalDateTime.now();
        jzOrderQGMapper.deleteByCity("上海");
        //计算半年的时间的long
        long endTime = endDay.atZone(ZoneId.systemDefault()).toEpochSecond() * 1000;

        long temp1 = startDay.plusMonths(6).atZone(ZoneId.systemDefault()).toEpochSecond() * 1000;

        long temp2 = temp1 - startTime;
        while (startTime < endTime) {
            //查询
            Map<String, Object> objectMap;
            List<WorkerInfo> o = new ArrayList<>();
            objectMap = OkHttpUtil.get(startTime, startTime + temp2, "10000257", sessionId, true);
            if (objectMap.size() == 0) {
                continue;
            }
            if (!((boolean) objectMap.get("resStatus"))) {
                continue;
            }
            o.addAll((List<WorkerInfo>) objectMap.get("workerInfo"));
            if (o.size() > 0) {
                jzOrderQGMapper.batchInsert(convertWorkerToOrder(o));
            }
            startTime = startTime + temp2;
        }

    }

    /**
     * merge 订单状态  有相同则更新状态，不相同则插入
     *
     * @param qgList     本地最近一个月插入的数据
     * @param orderQgs   勤鸽那边最近一个月的数据
     * @param validToken
     */
    private void compareAndInsertOrUpdate(List<JzOrderQg> qgList, List<JzOrderQg> orderQgs, String validToken) {
        if (!qgList.isEmpty()) {
            for (JzOrderQg jzOrderQg : qgList) {
                JzOrderQg outOrderQg = getOutOrderQgByOrderSn(jzOrderQg.getOutId(), orderQgs);
                if (null != outOrderQg) {
                    outOrderQg.setId(jzOrderQg.getId());
                    outOrderQg.setCreateTime(jzOrderQg.getCreateTime());
                    outOrderQg.setUpdateTime(new java.util.Date());
                    outOrderQg.setUpdateUser(0);
                    //姓名、手机号、地址等 不会变，不需要在查一次
                    outOrderQg.setUserName(jzOrderQg.getUserName());
                    outOrderQg.setUserPhone(jzOrderQg.getUserPhone());
                    outOrderQg.setAddress(jzOrderQg.getAddress());
                    jzOrderQGMapper.updateByPrimaryKeySelective(outOrderQg);
                }
            }
        }
        List<JzOrderQg> batchInsert = new ArrayList<>();
        for (JzOrderQg orderQg : orderQgs) {
            JzOrderQg outOrderQgByOrderSn = getOutOrderQgByOrderSn(orderQg.getOutId(), qgList);
            if (null == outOrderQgByOrderSn) {
                //补充手机号等信息
                AtomicBoolean type = new AtomicBoolean(false);
                batchInsert.forEach(a -> {
                    if (a.getOutId().equals(orderQg.getOutId())) {
                        type.set(true);
                    }
                });
                if (!type.get()) {
                    addUserMissInfo(orderQg, validToken);
                    batchInsert.add(orderQg);
                }
            }
        }
        if (!batchInsert.isEmpty()) {
            jzOrderQGMapper.batchInsert(batchInsert);
        }
    }

    private void addUserMissInfo(JzOrderQg orderQgs, String validToken) {
        Map<String, String> userMissInfo = OkHttpUtil.getUserMissInfo(validToken, orderQgs.getBuyerId(), orderQgs.getOutId());
        orderQgs.setUserName(userMissInfo.get("name"));
        orderQgs.setUserPhone(userMissInfo.get("phone"));
        orderQgs.setAddress(userMissInfo.get("address"));
    }

    private JzOrderQg getOutOrderQgByOrderSn(String ordeId, List<JzOrderQg> orderQgs) {
        for (JzOrderQg orderQg : orderQgs) {
            if (orderQg.getOutId().equals(ordeId)) {
                return orderQg;
            }
        }
        return null;
    }

    private List<JzOrderQg> convertWorkerToOrder(List<WorkerInfo> orginList) {
        List<JzOrderQg> jzOrderQgList = new ArrayList<>();
        for (WorkerInfo workerInfo : orginList) {
            JzOrderQg orderQg = new JzOrderQg();
            orderQg.setOrderSn(workerInfo.getBizOrderId()); //订单编号
            if (StringUtils.isEmpty(workerInfo.getServSkuName()) || workerInfo.getServiceName().split("服务内容:").length == 0) {
                log.info("商品描述：" + workerInfo + ", 对应的sku=" + workerInfo.getServSkuName());
                orderQg.setGoods(workerInfo.getServiceName() + "-未知商品");
            } else {
                orderQg.setGoods(workerInfo.getServiceName() + "-" + workerInfo.getServSkuName().split("服务内容:")[1]);
            }
            orderQg.setCity(workerInfo.getServiceStoreName().substring(0, 2));
            orderQg.setOrderLabel(workerInfo.getLabelName());
            if (StringUtils.isEmpty(workerInfo.getPayTime())) {
                orderQg.setPayTime(Date.from(LocalDate.of(1949, 10, 1).atStartOfDay().atZone(ZoneId.systemDefault()).toInstant()));
            } else {
                orderQg.setPayTime(Date.from(LocalDateTime.parse(workerInfo.getPayTime(), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")).atZone(ZoneId.systemDefault()).toInstant()));
            }
            orderQg.setUserName(workerInfo.getBuyerName());
            orderQg.setUserPhone(workerInfo.getBuyerMobile());
            orderQg.setAddress(workerInfo.getBuyerAddress());
            if (StringUtils.isEmpty(workerInfo.getExpectDate())) {
                orderQg.setUserBookTime("买家暂未预约");
            } else {
                orderQg.setUserBookTime(workerInfo.getExpectDate()); //消费者预约时间
            }
            if (StringUtils.isEmpty(workerInfo.getGmtReserveStart()) || StringUtils.isEmpty(workerInfo.getGmtReserveEnd())) {
                orderQg.setRealBookTime("暂无实际预约时间");
            } else {
                orderQg.setRealBookTime(workerInfo.getGmtReserveStart() + "-" + workerInfo.getGmtReserveEnd()); //服务商开始结果时间
            }
            orderQg.setOutOrderStatusCode(workerInfo.getTaskStatusCode());
            orderQg.setOutOrderStatusCodeValue(workerInfo.getTaskStatusName());
            orderQg.setMemo(workerInfo.getReserveFailDesc()); //预约失败描述
            orderQg.setServantName(workerInfo.getWorkerName()); //阿姨名字
            orderQg.setCreateTime(new java.util.Date());
            orderQg.setCreateUser(0);
            orderQg.setOrderCreateTime(workerInfo.getGmtCreate()); //订单创建时间
            orderQg.setOutId(workerInfo.getId()); //勤鸽订单id
            orderQg.setBuyerId(workerInfo.getBuyerId());
            orderQg.setShopName(workerInfo.getServiceStoreName()); //网点名称
            orderQg.setWorkOrderNumber(workerInfo.getServiceCount()); //工单份数
            orderQg.setAssignTime(workerInfo.getAssignTime()); // 分配时间
            orderQg.setGmtIdentify(workerInfo.getGmtIdentify()); //完成时间
            jzOrderQgList.add(orderQg);
            insertCustomerClient(orderQg.getUserPhone(), orderQg.getUserName(), orderQg.getAddress());
        }
        return jzOrderQgList;
    }


    private void insertCustomerClient(String phone, String userName, String address) {
        CustomerClient customerClient = customerClientMapper.selectByTel(phone);
        if (null == customerClient) {
            customerClient = new CustomerClient();
            customerClient.setCustomerNo(customerClientMapper.selectCustomerNo());
            customerClient.setTel(phone);
            customerClient.setCustomerAddr(address);
            if (StringUtils.isNotBlank(userName)) {
                customerClient.setCustomerName(userName);
            }
            customerClient.setChannelId(15);
            customerClient.setSource("qinge");
            customerClientMapper.insertSelective(customerClient);
        }
    }
}
