package com.ruoyi.quartz.task;

import com.alibaba.fastjson2.JSON;
import com.ruoyi.app.domain.*;
import com.ruoyi.app.mapper.AppLocationMapper;
import com.ruoyi.quartz.domain.app.*;
import com.ruoyi.app.service.*;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.http.HttpUtils;
import com.ruoyi.common.utils.uuid.IdUtils;
import com.ruoyi.system.service.ISysConfigService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 任务执行器定时类
 */
@Component("taskExecutor")
public class TaskExecutor {
    @Autowired
    private IAppTaskService appTaskService;
    @Autowired
    private IAppTaskBakService appTaskBakService;
    @Autowired
    private IAppWcsTaskService appWcsTaskService;
    @Autowired
    private IAppStockService appStockService;
    @Autowired
    private IAppPendingStorageService appPendingStorageService;
    @Autowired
    private ISysConfigService sysConfigService;
    @Autowired
    private IPlcService plcService;

    protected final Logger logger = LoggerFactory.getLogger(this.getClass());

    private final HashMap<Integer, Integer> taskTypeMap = new HashMap<Integer, Integer>() {{
        put(1, 1);// 入库
        put(2, 2);// 出库
        put(3, 3);// 移库
    }};
    @Autowired
    private AppLocationMapper appLocationMapper;

    /**
     * 解析wms任务
     * 任务状态为0
     */
    @Transactional(rollbackFor = Exception.class)
    public void executeWmsTask() {
        // 查询所有的任务
        List<AppTask> wmsTaskList = appTaskService.selectAppTaskList(new AppTask());
        if (wmsTaskList == null || wmsTaskList.isEmpty()) {
            return;
        }
        // 筛选出待解析的任务
        List<AppTask> executingWmsTaskList = wmsTaskList.stream().filter(task -> task.getTaskStatus() == 0).collect(Collectors.toList());
        // 任务待下发列表
        Map<String, AppWcsTask> wcsTaskMap = new HashMap<>();
        for (AppTask appTask : executingWmsTaskList) {
            if (StringUtils.isNotEmpty(appTask.getPreTask())) {
                // 判断前置任务是否已经完成
                List<AppTask> preTaskList = wmsTaskList.stream().filter(task -> Objects.equals(task.getTaskId(), appTask.getPreTask()) && task.getTaskStatus() != 5).collect(Collectors.toList());
                if (!preTaskList.isEmpty()) {
                    continue;
                }
            }
            // 判断这个箱子的任务是否已经下发过
            if (wcsTaskMap.containsKey(appTask.getVehicleId())) {
                appTask.setWcsTaskId(wcsTaskMap.get(appTask.getVehicleId()).getWcsTaskId());
                appTask.setTaskStatus(1);
                continue;
            }
            // 添加一个新wcs任务
            AppWcsTask newWcsTask = new AppWcsTask();
            newWcsTask.setWcsTaskId("WCS_" + IdUtils.fastUUID());
            newWcsTask.setWcsTaskType(taskTypeMap.get(appTask.getTaskType()));
            newWcsTask.setWcsTaskStatus(0);
            newWcsTask.setTaskPriority(appTask.getTaskPriority());
            newWcsTask.setVehicleId(appTask.getVehicleId());
            newWcsTask.setOrigin(appTask.getOrigin());
            newWcsTask.setDestination(appTask.getDestination());
            newWcsTask.setCreateTime(new Date());
            wcsTaskMap.put(appTask.getVehicleId(), newWcsTask);
            // 更新wms任务信息
            appTask.setWcsTaskId(newWcsTask.getWcsTaskId());
            appTask.setTaskStatus(1);
        }
        if(!wcsTaskMap.isEmpty()) {
            // 更新wms任务
            appTaskService.batchUpdateAppTask(executingWmsTaskList);
            // 存储wcs任务
            appWcsTaskService.batchInsertAppWcsTask(new ArrayList<>(wcsTaskMap.values()));
        }
    }

    /**
     * 发送wcs任务
     * 任务状态为0
     */
    @Transactional(rollbackFor = Exception.class)
    public void sendWcsTask() {
        // 查询出所有的待下发的wcs任务
        AppWcsTask wcsTaskQuery = new AppWcsTask();
        wcsTaskQuery.setWcsTaskStatus(0);
        List<AppWcsTask> wcsTaskList = appWcsTaskService.selectAppWcsTaskList(wcsTaskQuery);
        if (wcsTaskList == null || wcsTaskList.isEmpty()) {
            // 没有待下发的任务，跳过任务
            return;
        }
        // 获取请求地址
        String url = sysConfigService.selectConfigByKey("wcs.url");
        if (StringUtils.isEmpty(url)) {
            // 查询不到wcs任务发送地址
            return;
        }
        for (AppWcsTask appWcsTask : wcsTaskList) {
            // 添加wcs任务请求
            WcsStackerTaskReq wcsStackerTaskReq = getWcsStackerTaskRequest(appWcsTask);
            // 发送http请求---请求5次
            for (int i = 0; i < 5; i++) {
                WcsCommonRes wcsCommonRes = JSON.parseObject(HttpUtils.sendHttpPostWithoutToken(url, JSON.toJSONString(wcsStackerTaskReq)), WcsCommonRes.class);
                if (wcsCommonRes == null) {
                    continue;
                }
                if (wcsCommonRes.getCode() == 0) {
                    // 返回ok
                    appWcsTask.setWcsTaskStatus(1);// 已经发送成功
                } else {
                    // 返回error
                    appWcsTask.setWcsTaskStatus(999);// 任务异常
                }
                appWcsTask.setSendTime(new Date());
                appWcsTaskService.updateAppWcsTask(appWcsTask);
                // 请求成功，不再发送
                break;
            }
        }
    }

    /**
     * 创建wcs请求
     *
     * @param appWcsTask 任务
     * @return 请求详情
     */
    private WcsStackerTaskReq getWcsStackerTaskRequest(AppWcsTask appWcsTask) {
        WcsStackerTaskReq wcsStackerTaskReq = new WcsStackerTaskReq();
        wcsStackerTaskReq.setTaskId(appWcsTask.getWcsTaskId());
        wcsStackerTaskReq.setTaskType(appWcsTask.getWcsTaskType());
        wcsStackerTaskReq.setPriority(appWcsTask.getTaskPriority());
        wcsStackerTaskReq.setOrigin(appWcsTask.getOrigin());
        wcsStackerTaskReq.setDestination(appWcsTask.getDestination());
        wcsStackerTaskReq.setVehicleNo(appWcsTask.getVehicleId());
        return wcsStackerTaskReq;
    }

    @Transactional
    public void completeWmsTask() {
        completeNormalTask();
    }

    /**
     * 完成通常任务
     */
    private void completeNormalTask() {
        // 查找 Wms 任务
        AppTask appTask = new AppTask();
        appTask.setTaskStatus(5);
        List<AppTask> appTasks = appTaskService.selectAppTaskList(appTask);
        if (appTasks == null || appTasks.isEmpty()) {
            return;
        }
        for (AppTask task : appTasks) {
            if (task.getTaskType().compareTo(1) == 0) { // 入库任务
                // 从码盘表内拉出数据
                AppPendingStorage appPendingStorage = new AppPendingStorage();
                appPendingStorage.setVehicleNo(task.getVehicleId());
                List<AppPendingStorage> appPendingStorages = appPendingStorageService.selectAppPendingStorageList(appPendingStorage);
                if (appPendingStorages == null) {
                    return;
                }
                if (appPendingStorages.isEmpty()) {
                    AppTask updateRemark = new AppTask();
                    updateRemark.setTaskId(task.getTaskId());
                    updateRemark.setRemark("该载具似乎未进行过码盘");
                    appTaskService.updateAppTask(updateRemark); // 更新备注信息
                    AppTaskBak appTaskBak = new AppTaskBak();
                    BeanUtils.copyProperties(task, appTaskBak);
                    appTaskBakService.insertAppTaskBak(appTaskBak); // 将任务数据归档
                    appTaskService.deleteAppTaskByTaskId(task.getTaskId()); // 删除旧数据
                    return;
                }
                for (AppPendingStorage pendingStorage : appPendingStorages) {
                    // 插入库存
                    String stockId = IdUtils.fastSimpleUUID();
                    AppStock appStock = new AppStock();
                    appStock.setStockId(stockId);
                    appStock.setListId(pendingStorage.getListId());
                    appStock.setVehicleId(pendingStorage.getVehicleNo());
                    appStock.setLocationId(task.getDestination());
                    appStock.setGoodsId(pendingStorage.getGoodsId());
                    appStock.setGoodsName(pendingStorage.getGoodsDesc());
                    appStock.setGoodsUnit(pendingStorage.getUnit());
                    appStock.setProviderId("-");
                    appStock.setProviderName("-");
                    appStock.setRemainNum(pendingStorage.getGoodsNum());
                    appStock.setOriginNum(pendingStorage.getGoodsNum());
                    appStock.setBatchNo("-");
                    appStock.setInvAge(0L);
                    appStock.setGoodsStatus(0);
                    appStock.setStockStatus(0);
                    appStock.setCreateTime(new Date());
                    appStock.setUpdateTime(new Date());
                    appStock.setCreateUser(pendingStorage.getCreatePerson());
                    appStock.setUpdateBy(pendingStorage.getCreatePerson());
                    appStock.setRemark("");
                    int insertStockResult = appStockService.insertAppStock(appStock);
                    logger.info("插入库存：{}，结果：{}", JSON.toJSONString(appStock), insertStockResult);
                    if(insertStockResult > 0) {
                        appPendingStorageService.deleteAppPendingStorageByRecordId(pendingStorage.getRecordId()); // 删除码盘数据
                        // 如果是PMS入库则发送PMS入库完成
                        if(pendingStorage.getStorageType().compareTo(2) == 0) {
                            PmsInFeedBack pmsInFeedBack = new PmsInFeedBack();
                            PmsInComplete pmsInComplete = new PmsInComplete();
                            pmsInComplete.setCrmOrder(stockId);
                            pmsInComplete.setSapCode("2290");
                            pmsInComplete.setInArea("TPLK");
                            pmsInComplete.setInLocation("6001");
                            pmsInComplete.setOutArea("TPHC");
                            pmsInComplete.setOutLocation("6001");
                            pmsInFeedBack.setHeaderInfo(pmsInComplete);
                            List<PmsInCompleteDetail> pmsInCompleteDetails = new ArrayList<>();
                            PmsInCompleteDetail pmsInCompleteDetail = new PmsInCompleteDetail();
                            pmsInCompleteDetail.setMaterialNo(pendingStorage.getGoodsId());
                            pmsInCompleteDetail.setMaterialName(pendingStorage.getGoodsDesc());
                            pmsInCompleteDetail.setAmount(pendingStorage.getGoodsNum().intValue());
                            pmsInCompleteDetail.setUnit(pendingStorage.getUnit());
                            pmsInCompleteDetail.setBarcode(pendingStorage.getGoodsCode());
                            pmsInCompleteDetails.add(pmsInCompleteDetail);
                            pmsInFeedBack.setDetailList(pmsInCompleteDetails);
                            String url = sysConfigService.selectConfigByKey("pms.intComplete");
                            if (StringUtils.isEmpty(url)) {
                                return;
                            }
                            PmsCommonRes pmsCommonRes = JSON.parseObject(HttpUtils.sendHttpPostWithoutToken(url, JSON.toJSONString(pmsInFeedBack)), PmsCommonRes.class);
                            logger.info("pms入库反馈请求信息：{}，结果：{}", JSON.toJSONString(pmsInFeedBack), JSON.toJSONString(pmsCommonRes));
                        }
                    }

                }
                AppTask updateRemark = new AppTask();
                updateRemark.setTaskId(task.getTaskId());
                updateRemark.setRemark("已插入库存");
                appTaskService.updateAppTask(updateRemark); // 更新备注信息
                AppTaskBak appTaskBak = new AppTaskBak();
                appTaskBak.setTaskId(task.getTaskId());
                appTaskBak.setTaskStatus(task.getTaskStatus());
                appTaskBak.setRemark(updateRemark.getRemark());
                appTaskBak.setTaskType(task.getTaskType());
                appTaskBak.setTaskPriority(task.getTaskPriority());
                appTaskBak.setVehicleId(task.getVehicleId());
                appTaskBak.setOrigin(task.getOrigin());
                appTaskBak.setDestination(task.getDestination());
                appTaskBak.setWcsTaskId(task.getWcsTaskId());
                appTaskBak.setFinishTime(task.getFinishTime());
                appTaskBak.setGoodsId(task.getGoodsId());
                appTaskBak.setOpNum(task.getOpNum());
                appTaskBak.setStockNum(task.getStockNum());
                appTaskBak.setOpUser(task.getOpUser());
                appTaskBak.setPreTask(task.getPreTask());
                logger.info("入库任务数据归档成功。{}", JSON.toJSONString(appTaskBak));
                appTaskBakService.insertAppTaskBak(appTaskBak);// 数据归档
                appTaskService.deleteAppTaskByTaskId(task.getTaskId()); // 删除旧数据
                return;
            }
            if (task.getTaskType().compareTo(2) == 0) { // 出库任务
                if(task.getOpNum().compareTo(task.getStockNum()) >= 0) {
                    // 整出
                    AppStock appStock = new AppStock();
                    appStock.setGoodsId(task.getGoodsId());
                    appStock.setVehicleId(task.getVehicleId());
                    List<AppStock> appStocks = appStockService.selectAppStockList(appStock);
                    if(appStocks == null) {
                        return;
                    }
                    for (AppStock stock : appStocks) {
                        int deleteAppStockByStockId = appStockService.deleteAppStockByStockId(stock.getStockId());
                        logger.info("删除库存：{}", JSON.toJSONString(stock));
                        if(deleteAppStockByStockId > 0) {
                            AppTask updateRemark = new AppTask();
                            updateRemark.setTaskId(task.getTaskId());
                            updateRemark.setRemark("出库完成");
                            appTaskService.updateAppTask(updateRemark); // 更新备注信息
                            AppTaskBak appTaskBak = new AppTaskBak();
                            BeanUtils.copyProperties(task, appTaskBak);
                            logger.info("出库任务数据归档成功。{}", JSON.toJSONString(appTaskBak));
                            appTaskBakService.insertAppTaskBak(appTaskBak);// 数据归档
                            appTaskService.deleteAppTaskByTaskId(task.getTaskId()); // 删除旧数据
                        }
                        // 调用 pms 接口
                        PmsOutFeedBack pmsOutFeedBack = new PmsOutFeedBack();
                        PmsOutFeedBackRecordList recordListItem = new PmsOutFeedBackRecordList();
                        recordListItem.setAmount(task.getOpNum().intValue());
                        recordListItem.setBusinessOrder(task.getOrderId());
                        recordListItem.setMaterialsNo(task.getGoodsId());
                        List<PmsOutFeedBackRecordList> recordList = new ArrayList<>();
                        recordList.add(recordListItem);
                        pmsOutFeedBack.setRecordList(recordList);
                        String url = sysConfigService.selectConfigByKey("pms.outComplete");
                        if (StringUtils.isEmpty(url)) {
                            continue;
                        }
                        PmsCommonRes pmsCommonRes = JSON.parseObject(HttpUtils.sendHttpPostWithoutToken(url, JSON.toJSONString(pmsOutFeedBack)), PmsCommonRes.class);
                        logger.info("pms出库反馈请求信息：{}，结果：{}", JSON.toJSONString(pmsOutFeedBack), JSON.toJSONString(pmsCommonRes));
                    }
                    AppStock appStockCheck = new AppStock();
                    appStockCheck.setLocationId(task.getOrigin());
                    List<AppStock> appStockCheckData = appStockService.selectAppStockList(appStockCheck);
                    if(appStockCheckData == null) {
                        return;
                    }
                    if(appStockCheckData.isEmpty()) {
                        // 这个位置没有库存了，直接释放货位
                        AppLocation location = new AppLocation();
                        location.setLocationId(task.getOrigin());
                        location.setLocationStatus(0);
                        appLocationMapper.updateAppLocation(location);
                    }
                }
                // 如果小于的话就不做处理
                return;
            }
            if (task.getTaskType().compareTo(9) == 0) { // 移库任务
                int updateNewLocation = appStockService.updateNewLocation(task.getOrigin(), task.getDestination());
                if(updateNewLocation > 0) {
                    // 释放原库位
                    AppLocation location = new AppLocation();
                    location.setLocationId(task.getOrigin());
                    location.setLocationStatus(0);
                    appLocationMapper.updateAppLocation(location);

                    AppTask updateRemark = new AppTask();
                    updateRemark.setTaskId(task.getTaskId());
                    updateRemark.setRemark("移库完成");
                    appTaskService.updateAppTask(updateRemark); // 更新备注信息
                    AppTaskBak appTaskBak = new AppTaskBak();
                    BeanUtils.copyProperties(task, appTaskBak);
                    logger.info("移库任务数据归档成功。{}", JSON.toJSONString(appTaskBak));
                    appTaskBakService.insertAppTaskBak(appTaskBak);// 数据归档
                    appTaskService.deleteAppTaskByTaskId(task.getTaskId()); // 删除旧数据
                }
                return;
            }


        }
    }
    /**
     * 定时任务更新plcid
     */
    @Transactional(rollbackFor = Exception.class)
    public void scheduleTask() {
//        System.out.println("开始执行");
        //查询入库表
        List<Plc> plcs = plcService.selectPlcList();
        Plc plc = plcs.get(0);
        //查询入库任务表 到达9999999 则自动从0开始
        if(plc.getPlcid() == 9999999){
            plc.setPlcid(0L);
            plcService.updatePlc(plc);
        }
        AppTask appTask = new AppTask();
        appTask.setTaskStatus(0);
        appTask.setPlcId(null);
        List<AppTask> AppTasks = appTaskService.selectPlcList();
        Long count = plc.getPlcid();
        if(AppTasks.size() > 0){
            List<String> list = AppTasks.stream().map(AppTask::getVehicleId).distinct().collect(Collectors.toList());
            for(String ctl: list){
                AppTask appTask1 = new AppTask();
                appTask1.setTaskStatus(0);
                appTask1.setVehicleId(ctl);
                appTask1.setPlcId(++count);
                appTaskService.updatePlcId(appTask1);
            }
        }
        if(count.longValue() != plc.getPlcid().longValue()){
            logger.info("定时任务更改plc：{}",count);
            plc.setPlcid(count);
            plcService.updatePlc(plc);
        }
        plcs = plcService.selectPlcList();
        plc = plcs.get(0);
        //查询入库任务表 到达9999999 则自动从0开始
        if(plc.getPlcid() == 9999999){
            plc.setPlcid(0L);
            plcService.updatePlc(plc);
        }


    }
}
