package com.scm.contract.service.quartz.job;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.scm.contract.model.apply.LabelApplication;
import com.scm.contract.model.apply.LabelApplicationDetail;
import com.scm.contract.model.print.PrintStatus;
import com.scm.contract.model.print.Printing;
import com.scm.contract.model.print.ReprintCode;
import com.scm.contract.service.apply.LabelApplicationDetailService;
import com.scm.contract.service.apply.LabelApplicationService;
import com.scm.contract.service.print.PrintCodeService;
import com.scm.contract.service.print.ReprintCodeService;
import com.scm.contract.tools.RestTemplateUtils;
import lombok.extern.slf4j.Slf4j;
import org.quartz.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * @Description: 同步定时任务测试
 * <p>
 * 此处的同步是指 当定时任务的执行时间大于任务的时间间隔时
 * 会等待第一个任务执行完成才会走第二个任务
 * @author: zxz
 * @date: 2020年06月19日
 */
@PersistJobDataAfterExecution
@DisallowConcurrentExecution
@Slf4j
public class AsyncJob implements Job {

    @Value("${direwolf.print.url}")
    private String sendUrl;

    @Autowired
    private LabelApplicationDetailService detailService;

    @Autowired
    private LabelApplicationService labelApplicationService;

    @Autowired
    private PrintCodeService printCodeService;

    @Autowired
    private ReprintCodeService reprintCodeService;

    private String parameter;

    public void setParameter(String parameter) {
        this.parameter = parameter;
    }

    @Override
    @Transactional
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        int overStatus = 1000;
        try {
            if (StringUtils.isNotBlank(parameter)) {
                overStatus = Integer.parseInt(parameter);
            }
        } catch (NumberFormatException ignored) {
        }
        //查询需要获取打印状态的id

        List<Printing> printings = detailService.getPrinting();
        if (CollectionUtils.isNotEmpty(printings)) {
            List<String> ids = new ArrayList<>();
            List<String> detailIds = new ArrayList<>();
            List<String> reprintCodeIds = new ArrayList<>();
            Set<String> detailLabelApplicationIds = new HashSet<>();
            Set<String> reprintLabelApplicationIds = new HashSet<>();
            for (Printing printing : printings) {
                String id = printing.getId();
                ids.add(id);
                String labelApplicationId = printing.getLabelApplicationId();
                Boolean isReprint = printing.getIsReprint();
                if (Objects.isNull(isReprint)) isReprint = false;
                if (isReprint) {
                    reprintCodeIds.add(id);
                    reprintLabelApplicationIds.add(labelApplicationId);
                } else {
                    detailIds.add(id);
                    detailLabelApplicationIds.add(labelApplicationId);
                }
            }
            Map<String, Object> dataMap = new HashMap<>();
            dataMap.put("ids", ids);
            Map map = RestTemplateUtils.postSend(sendUrl + "/api/print/status", dataMap);
            if (Objects.isNull(map)) return;
            Integer code = (Integer) map.get("code");
            if (Objects.isNull(code) || 200 != code) return;
            Object data = map.get("data");
            if (!Objects.isNull(data)) {
                List<PrintStatus> printStatuses = JSON.parseArray(data.toString(), PrintStatus.class);
                Map<String, Integer> reprintStatusMap = new HashMap<>();
                Map<String, Integer> detailStatusMap = new HashMap<>();
                for (PrintStatus printStatus : printStatuses) {
                    String id = printStatus.getId();
                    Integer status = printStatus.getStatus();
                    ids.remove(id);
                    boolean detailRemoveBoolean = detailIds.remove(id);
                    if (detailRemoveBoolean) detailStatusMap.put(id, status);
                    boolean reprintRemoveBoolean = reprintCodeIds.remove(id);
                    if (reprintRemoveBoolean) reprintStatusMap.put(id, status);
                }
                //ids中如果不为空吧剩余的发送给高大师进行打印(莫名消失的任务补发）
                if (CollectionUtils.isNotEmpty(ids)) {
                    printCodeService.printSendByJob(detailIds, reprintCodeIds);
                }

                //修改overIds的从表订单状态为2
                if (CollectionUtils.isNotEmpty(reprintStatusMap)) {
                    List<ReprintCode> reprintCodes = reprintCodeService.getListByIds(new ArrayList<>(reprintStatusMap.keySet()));
                    boolean isChange = false;
                    for (ReprintCode reprintCode : reprintCodes) {
                        String reprintCodeId = reprintCode.getId();
                        Integer status = reprintStatusMap.get(reprintCodeId);
                        Integer oldPrintStatus = reprintCode.getPrintStatus();
                        if (Objects.isNull(oldPrintStatus) || !status.equals(oldPrintStatus)){
                            isChange = true;
                            reprintCode.setPrintStatus(status);
                            if (overStatus == status) {
                                reprintCode.setIsPrint(2);
                            }
                        }
                    }
                    //如果返回的有變化就去修改
                    if (isChange) {
                        reprintCodeService.updatePrintBash(reprintCodes);

                        List<String> reprintLabelApplicationIdList = new ArrayList<>(reprintLabelApplicationIds);
                        List<LabelApplication> labelApplications = labelApplicationService.getListByIds(reprintLabelApplicationIdList);
                        List<ReprintCode> reprintCodeList = reprintCodeService.getListBylApplicationIds(reprintLabelApplicationIdList);
                        Map<String,List<ReprintCode>> reprintCodeMap = new HashMap<>();
                        for (ReprintCode reprintCode : reprintCodeList) {
                            String labelApplicationId = reprintCode.getLabelApplicationId();
                            if (!reprintCodeMap.containsKey(labelApplicationId)) {
                                reprintCodeMap.put(labelApplicationId,new ArrayList<>());
                            }
                            reprintCodeMap.get(labelApplicationId).add(reprintCode);
                        }

                        labelApplicationService.setName(labelApplications, true);
                        List<String> overLabelApplicationIds = new ArrayList<>();
                        for (LabelApplication labelApplication : labelApplications) {
                            boolean b = true;
                            String id = labelApplication.getId();
                            List<ReprintCode> reprintCodes1 = reprintCodeMap.getOrDefault(id, new ArrayList<>());
                            for (ReprintCode reprintCode : reprintCodes1) {
                                Integer isPrint = reprintCode.getIsPrint();
                                if (2 != isPrint) {
                                    b = false;
                                    break;
                                }
                            }
                            if (b) {
                                overLabelApplicationIds.add(id);
                            }
                        }
                        if (CollectionUtils.isNotEmpty(overLabelApplicationIds)) {
                            labelApplicationService.updateStatus(overLabelApplicationIds, "5",false);
                        }
                    }
                }

                if (CollectionUtils.isNotEmpty(detailStatusMap)) {
                    List<LabelApplicationDetail> detailList = detailService.listByDetailIds(new ArrayList<>(detailStatusMap.keySet()));
                    boolean isChange = false;
                    for (LabelApplicationDetail detail : detailList) {
                        String detailId = detail.getId();
                        Integer status = detailStatusMap.get(detailId);
                        Integer oldPrintStatus = detail.getPrintStatus();
                        if (Objects.isNull(oldPrintStatus) || !status.equals(oldPrintStatus)){
                            isChange = true;
                            detail.setPrintStatus(status);
                            if (overStatus == status) {
                                detail.setIsPrint(2);
                            }
                        }
                    }
                    if (isChange){
                        detailService.updatePrintBash(detailList);

                        //主表检查是否所有订单都已经打印完毕，如果打印完毕修改状态
                        List<LabelApplication> labelApplications = labelApplicationService.getListByIds(new ArrayList<>(detailLabelApplicationIds));
                        labelApplicationService.setName(labelApplications, true);
                        List<String> overLabelApplicationIds = new ArrayList<>();
                        for (LabelApplication labelApplication : labelApplications) {
                            boolean b = true;
                            List<LabelApplicationDetail> details1 = labelApplication.getDetails();
                            for (LabelApplicationDetail detail : details1) {
                                Integer isPrint = detail.getIsPrint();
                                if (2 != isPrint) {
                                    b = false;
                                    break;
                                }
                            }
                            if (b) {
                                overLabelApplicationIds.add(labelApplication.getId());
                            }
                        }
                        if (CollectionUtils.isNotEmpty(overLabelApplicationIds)) {
                            labelApplicationService.updateStatus(overLabelApplicationIds, "5", true);
                        }
                    }
                }
            }
        }
    }
}
