package com.jwipc.job.handler;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.jwipc.constant.FlagConst;
import com.jwipc.order.entity.ShortageData;
import com.jwipc.order.entity.ShortageDetail;
import com.jwipc.order.entity.ShortagePlan;
import com.jwipc.order.model.po.ShortagePlanReplyPO;
import com.jwipc.order.service.IShortageDataService;
import com.jwipc.order.service.IShortageDetailService;
import com.jwipc.order.service.IShortagePlanService;
import com.jwipc.sys.entity.PurchaseGroup;
import com.jwipc.sys.service.IPurchaseGroupService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.quartz.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.scheduling.quartz.QuartzJobBean;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.time.LocalTime;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * 每10分执行一次，从redis缓存中取sap推过来的数据，直到取完为止。
 */
@PersistJobDataAfterExecution
@DisallowConcurrentExecution
@Slf4j
@Component
public class CreateShortagePlanDataJob extends QuartzJobBean implements InterruptableJob {

    @Autowired
    private IShortageDataService shortageDataService;

    @Autowired
    private IShortageDetailService shortageDetailService;
    @Autowired
    private IShortagePlanService shortagePlanService;
    @Autowired
    private IPurchaseGroupService purchaseGroupService;

    @Resource
    private RedisTemplate redisTemplate;
    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Override
    public void interrupt() throws UnableToInterruptJobException {

    }

    @Override
    protected synchronized void executeInternal(JobExecutionContext context) throws JobExecutionException {
        log.info("从redis缓存中取sap推过来的欠料数据任务开始,凌晨7：00-23：00，每30分钟执行一次。");
        //查询需要自动发布给供应商的采购组 邓京术 2025-06-09
        final LambdaQueryWrapper<PurchaseGroup> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(PurchaseGroup::getAutoDeploy,1);
        final List<PurchaseGroup> purchaseGroups = purchaseGroupService.list(queryWrapper);
        final Set<String> purchaseGroupCodes = purchaseGroups.stream().map(a -> a.getPurchaseGroupCode())
                .collect(Collectors.toSet());
        String dateNumberKey = stringRedisTemplate.opsForValue().get("dateNumber");
        //sap 推过来的欠料数据是否已经完成， 见接口推送数据
        String dateNumber_syn = stringRedisTemplate.opsForValue().get("dateNumber_syn");
        String syc = stringRedisTemplate.opsForValue().get("syc_dateNumber");
        LocalTime nowTime = LocalTime.now();
        long secondsUntilMidnight = 86400 - nowTime.toSecondOfDay();
        //判断取缓存数据是否执行取数完成，如果执行完成，才可以重新取数据，以免取重复
        if ((null == syc || syc.equals("Y")) && StringUtils.isNotEmpty(dateNumberKey) && "Y".equals(dateNumber_syn)) {
            //用来控制当前欠料计划同步是否完成，以免重复。
            String[] dateNumberArr = dateNumberKey.split("@@");
            stringRedisTemplate.opsForValue().set("syc_dateNumber", "N", secondsUntilMidnight, TimeUnit.SECONDS);
            for (String dateNumber : dateNumberArr) {
                Integer synTimes = 0;
                if (null != stringRedisTemplate.opsForValue().get(dateNumber + "_times")) {
                    synTimes = Integer.parseInt(stringRedisTemplate.opsForValue().get(dateNumber +"_times"));
                }
                //检查是否已经同步过了。
                for (int i = 1; i <= synTimes; i++) {
                    if (null != stringRedisTemplate.opsForValue().get(dateNumber + "_syn_shortageData_" + i) && "Y".equals(stringRedisTemplate.opsForValue().get(dateNumber + "_syn_shortageData_" + i))) {
                        //如果当次的数据已经同步并插入数据库，则忽略。
                        continue;
                    }

                    if (redisTemplate.hasKey(dateNumber + "_shortageData_" + i)) {
                        log.info("开始同步" + dateNumber + "_syn_shortageData_" + i + "数据");
                        Object dataobj = redisTemplate.opsForValue().get(dateNumber + "_shortageData_" + i);
                        List<ShortageData> tempShortageDataInsertLists = com.alibaba.fastjson2.JSON.parseArray(dataobj.toString(), ShortageData.class);
                        Object obj = redisTemplate.opsForValue().get(dateNumber + "_shortageDetail_" + i);
                        List<ShortageDetail> tempShortageDetailInsertLists = com.alibaba.fastjson2.JSON.parseArray(obj.toString(), ShortageDetail.class);
                        if (CollUtil.isNotEmpty(tempShortageDataInsertLists)) {
                            //判断是否需要发布给供应商，1、对比采购组，是需要自动发布给供应商。2、供应商不为空的。 邓京术 2025-06-06
                            boolean flag  = initDeployShortData(tempShortageDataInsertLists, tempShortageDetailInsertLists, purchaseGroupCodes);
                            //缓存是否自动发布给供应商 邓京术 2025-06-09
                            if (flag) {
                                stringRedisTemplate.opsForValue().set(dateNumber + "_auto_deploy_shortageData", "Y", secondsUntilMidnight, TimeUnit.SECONDS);
                            }
                            shortageDataService.saveBatch(tempShortageDataInsertLists, 300);
                        }
                        if (CollUtil.isNotEmpty(tempShortageDetailInsertLists)) {
                            shortageDetailService.saveBatch(tempShortageDetailInsertLists, 300);
                        }
                        stringRedisTemplate.opsForValue().set(dateNumber + "_syn_shortageData_" + i, "Y", secondsUntilMidnight, TimeUnit.SECONDS);
                        stringRedisTemplate.opsForValue().set(dateNumber + "_syn_shortageDetail_" + i, "Y", secondsUntilMidnight, TimeUnit.SECONDS);
                        //缓存是否自动发布给供应商

                        if (stringRedisTemplate.hasKey(dateNumber + "_max_times")) {
                            int synTimesTemp = Integer.parseInt(stringRedisTemplate.opsForValue().get(dateNumber + "_max_times"));
                            if (synTimesTemp == i) {
                                //根据版本号查询计划是否已经存在
                                ShortagePlan shortagePlan = shortagePlanService.getById(tempShortageDataInsertLists.get(0).getPlanId());
                                shortagePlan.setSynStatus("更新完成");
                                //判断是否自动发布 邓京术 2025-06-09
                                String auto_deploy_shortageData = stringRedisTemplate.opsForValue().get(dateNumber + "_auto_deploy_shortageData");
                                if (StringUtils.isNotEmpty(auto_deploy_shortageData) && "Y".equals(auto_deploy_shortageData)) {
                                    shortagePlan.setStatus(1);
                                }
                                shortagePlanService.saveOrUpdate(shortagePlan);
                            }
                        }
                    }
                    log.info("同步" + dateNumber + "_syn_shortageData_" + i + "数据结束");
                }
            }
            //用来控制当前欠料计划同步是否完成，以免重复。设置当次同步数据完成。
            stringRedisTemplate.opsForValue().set("syc_dateNumber", "Y",secondsUntilMidnight, TimeUnit.SECONDS);
        }
        log.info("从redis缓存中取sap推过来的欠料数据任务结束");
    }

    //判断是否需要自动发布给供应商。
    private boolean initDeployShortData(List<ShortageData> tempShortageDataInsertLists, List<ShortageDetail> tempShortageDetailInsertLists,Set<String> purchaseGroupCodes) {
        boolean flag = false;
        for(ShortageData s : tempShortageDataInsertLists) {
            for (ShortageDetail shortageDetail1Temp : tempShortageDetailInsertLists) {
                if (shortageDetail1Temp.getId().equals(s.getDetailId()) && purchaseGroupCodes.contains(shortageDetail1Temp.getPurchaseGroup()) && StringUtils.isNotEmpty(s.getSupplierCode())) {
                    s.setDeployToSupplier(1);
                    s.setStatus(FlagConst.N.getCode());
                    flag = true;
                    break;
                }
            }
        }
        return flag;
    }

    //查询欠料计划最近5次最早的回复 ，回写至当前版本
    private void initShortData(List<ShortageData> tempShortageDataInsertLists, List<ShortageDetail> tempShortageDetailInsertLists) {
        for(ShortageData s : tempShortageDataInsertLists) {
            ShortagePlanReplyPO shortagePlanReplyPO = new ShortagePlanReplyPO();
            for (ShortageDetail shortageDetail1Temp : tempShortageDetailInsertLists) {
                if (shortageDetail1Temp.getId().equals(s.getDetailId())) {
                    shortagePlanReplyPO.setWorkOrderNumber(shortageDetail1Temp.getWorkOrderNumber());
                    shortagePlanReplyPO.setMaterialCode(shortageDetail1Temp.getMaterialCode());
                    shortagePlanReplyPO.setFactoryCode(shortageDetail1Temp.getFactoryCode());
                    break;
                }
            }

             if (null != s.getMainMaterialReply() || null != s.getMainMaterialReplyDate() || null != s.getRemark()) {
                 continue;
             }
            ShortagePlanReplyPO sp = shortageDataService.findSupplierRecentReply(shortagePlanReplyPO);
            if(ObjectUtil.isNotEmpty(sp)) {
                //获取最近5次里面的回复
                s.setMainMaterialReply(sp.getMainMaterialReply());
                s.setMainMaterialReplyDate(sp.getMainMaterialReplyDate());
                s.setRemark(sp.getRemark());
            }
        }
    }
}
