package com.ximai.mes.tm.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ximai.common.constant.UserConstants;
import com.ximai.common.utils.data.DataUtil;
import com.ximai.common.utils.data.StringUtils;
import com.ximai.mes.md.service.IMdWorkunitService;
import com.ximai.mes.pro.domain.proWorkOrder.ProWorkOrderProcess;
import com.ximai.mes.pro.domain.proWorkOrder.ProWorkOrderProcessTool;
import com.ximai.mes.pro.domain.task.ProTask;
import com.ximai.mes.pro.domain.task.ProTaskWorkorder;
import com.ximai.mes.pro.domain.task.ProTaskWorkunit;
import com.ximai.mes.pro.mapper.ProRouteProcessMapper;
import com.ximai.mes.pro.mapper.proWorkOrder.ProWorkOrderProcessMapper;
import com.ximai.mes.pro.mapper.proWorkOrder.ProWorkOrderProcessToolMapper;
import com.ximai.mes.pro.mapper.task.ProTaskWorkorderMapper;
import com.ximai.mes.pro.service.task.IProTaskService;
import com.ximai.mes.tm.domain.TmToolMachines;
import com.ximai.mes.tm.domain.TmToolRequest;
import com.ximai.mes.tm.domain.TmToolRequestItem;
import com.ximai.mes.tm.mapper.TmToolRequestItemMapper;
import com.ximai.mes.tm.mapper.TmToolRequestMapper;
import com.ximai.mes.tm.service.ITmToolMachinesService;
import com.ximai.mes.tm.service.ITmToolRequestItemService;
import com.ximai.mes.tm.service.ITmToolRequestService;
import com.ximai.system.strategy.AutoCodeUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

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

/**
 * 刀模版申请单Service业务层处理
 *
 * @author generator
 * @date 2024-02-02
 */
@Slf4j
@Service
public class TmToolRequestServiceImpl implements ITmToolRequestService {
    @Autowired
    private TmToolRequestMapper tmToolRequestMapper;

    @Autowired
    private ITmToolRequestService tmToolRequestService;

    @Autowired
    private TmToolRequestItemMapper tmToolRequestItemMapper;

    @Autowired
    private ITmToolRequestItemService tmToolRequestItemService;

    @Autowired
    private ITmToolMachinesService tmToolMachinesService;
    @Autowired
    private ProTaskWorkorderMapper proTaskWorkorderMapper;

    @Autowired
    private ProWorkOrderProcessToolMapper proWorkOrderProcessToolMapper;

    @Autowired
    private ProWorkOrderProcessMapper proWorkOrderProcessMapper;

    @Autowired
    private ProRouteProcessMapper proRouteProcessMapper;
    @Autowired
    IMdWorkunitService mdWorkunitService;
    @Autowired
    private AutoCodeUtil autoCodeUtil;
    @Autowired
    private IProTaskService proTaskService;

    /**
     * 查询刀模版申请单
     *
     * @param toolRequestId 刀模版申请单主键
     * @return 刀模版申请单
     */
    @Override
    public TmToolRequest selectTmToolRequestByToolRequestId(Long toolRequestId) {
        TmToolRequest tmToolRequest = tmToolRequestMapper.selectTmToolRequestByToolRequestId(toolRequestId);
        TmToolRequestItem tmToolRequestItem = new TmToolRequestItem();
        tmToolRequestItem.setToolRequestId(toolRequestId);
        List<TmToolRequestItem> tmToolRequestItems = tmToolRequestItemMapper.selectTmToolRequestItemList(tmToolRequestItem);
        tmToolRequest.setImToolRequestItemList(tmToolRequestItems);
        return tmToolRequest;
    }

    /**
     * 查询刀模版申请单列表
     *
     * @param tmToolRequest 刀模版申请单
     * @return 刀模版申请单
     */
    @Override
    public List<TmToolRequest> selectTmToolRequestList(TmToolRequest tmToolRequest) {
        return tmToolRequestMapper.selectTmToolRequestList(tmToolRequest);
    }

    @Override
    public List<TmToolRequest> selectList(QueryWrapper<TmToolRequest> requestQueryWrapper) {
        return tmToolRequestMapper.selectListByQw(requestQueryWrapper);
    }

    /**
     * 新增刀模版申请单
     *
     * @param tmToolRequest 刀模版申请单
     * @return 结果
     */
    @Override
    public int insertTmToolRequestAndItem(TmToolRequest tmToolRequest) {
        int i = this.insertTmToolRequest(tmToolRequest);
        List<TmToolRequestItem> imToolRequestItemList = tmToolRequest.getImToolRequestItemList();
        if (CollectionUtil.isNotEmpty(imToolRequestItemList)) {
            Long toolRequestId = tmToolRequest.getToolRequestId();
            for (TmToolRequestItem tmToolRequestItem : imToolRequestItemList) {
                tmToolRequestItem.setToolRequestId(toolRequestId);
                tmToolRequestItemService.insertTmToolRequestItem(tmToolRequestItem);
            }
        }
        return i;
    }


    /**
     * 新增刀模版申请单
     *
     * @param tmToolRequest 刀模版申请单
     * @return 结果
     */
    @Override
    public int insertTmToolRequest(TmToolRequest tmToolRequest) {
        tmToolRequest.createAction();
        if (StringUtils.isEmpty(tmToolRequest.getToolRequestCode())) {
            tmToolRequest.setToolRequestCode(autoCodeUtil.genSerialCode(UserConstants.TOOL_REQUEST_CODE, ""));
        }

        return tmToolRequestMapper.insertTmToolRequest(tmToolRequest);
    }

    /**
     * 修改刀模版申请单
     *
     * @param tmToolRequest 刀模版申请单
     * @return 结果
     */
    @Override
    public int updateTmToolRequest(TmToolRequest tmToolRequest) {
        tmToolRequest.updateAction();
        return tmToolRequestMapper.updateTmToolRequest(tmToolRequest);
    }

    /**
     * 批量删除刀模版申请单
     *
     * @param toolRequestIds 需要删除的刀模版申请单主键
     * @return 结果
     */
    @Override
    public int deleteTmToolRequestByToolRequestIds(Long[] toolRequestIds) {
        return tmToolRequestMapper.deleteTmToolRequestByToolRequestIds(toolRequestIds);
    }

    /**
     * 删除刀模版申请单信息
     *
     * @param toolRequestId 刀模版申请单主键
     * @return 结果
     */
    @Override
    public int deleteTmToolRequestByToolRequestId(Long toolRequestId) {
        return tmToolRequestMapper.deleteTmToolRequestByToolRequestId(toolRequestId);
    }

    // 查询工作单元上已经在使用的刀模版具
    private List<TmToolMachines> getTmToolMachinesInUse(List<Long> workunitIds) {
        QueryWrapper<TmToolMachines> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("ttm.workunit_id", workunitIds);
        queryWrapper.in("ttm.type", Arrays.asList(1, 2, 3));
        queryWrapper.eq("ttm.warehouse", 1);
        queryWrapper.isNotNull("ttrui.item_id");
        return tmToolMachinesService.selectListJoinUseItemByQw(queryWrapper);
    }


    private List<TmToolMachines> getTmToolMachines(Long taskWorkunitId) {
        QueryWrapper<TmToolMachines> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("ttm.task_workunit_id", taskWorkunitId);
        List<TmToolMachines> tmToolMachinesList2 = tmToolMachinesService.selectListJoinUseItemByQw(queryWrapper);
        return tmToolMachinesList2;
    }

    /**
     * 拷贝工单创建刀模版具
     *
     * @param proTask 刀模版申请单
     * @return 结果
     */
    @Override
    public int copyTmToolMachines(ProTask proTask) {
        ProTask queryTask = proTaskService.selectProTaskByTaskId(proTask.getTaskId());

        //获取任务单的taskId和processId
        Long taskId = proTask.getTaskId();
        Long processId = proTask.getProcessId();
        Long taskWorkunitId = proTask.getTaskWorkunitId();

        int i = 0;
        int requestNum = 0;
        //如果生产工单的工艺下没有设置工装夹具则不生成申请单
        Long workorderProcessId;

        //同过任务单id查询所有工单
        ProTaskWorkorder proTaskWorkorder = new ProTaskWorkorder();
        proTaskWorkorder.setTaskId(taskId);
        List<ProTaskWorkorder> proTaskWorkorders = proTaskWorkorderMapper.selectProTaskWorkorderList(proTaskWorkorder);
        if (CollectionUtil.isEmpty(proTaskWorkorders)) {
            return 0;
        }

        List<Long> workOrderIdList = proTaskWorkorders.stream().map(ProTaskWorkorder::getWorkorderId).collect(Collectors.toList());
        List<ProWorkOrderProcess> proWorkOrderProcessVoList = new ArrayList<>();
        for (Long workOrderId : workOrderIdList) {
            QueryWrapper<ProWorkOrderProcess> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("t1.workorder_id", workOrderId);
            queryWrapper.eq("t1.process_id", processId);
            List<ProWorkOrderProcess> proWorkOrderProcesses = proWorkOrderProcessMapper.selectListByQw(queryWrapper);
            ProWorkOrderProcess proWorkOrderProcess = proWorkOrderProcesses.get(0);
            proWorkOrderProcessVoList.add(proWorkOrderProcess);
        }

        if (CollectionUtil.isEmpty(proWorkOrderProcessVoList)) {
            return 0;
        }

        List<ProWorkOrderProcessTool> proWorkOrderProcessTools = new ArrayList<>();
        for (ProWorkOrderProcess proWorkOrderProcessVo : proWorkOrderProcessVoList) {
            workorderProcessId = proWorkOrderProcessVo.getWorkorderProcessId();
            List<ProWorkOrderProcessTool> proWorkOrderProcessToolsList = proWorkOrderProcessToolMapper.selectProWorkOrderProcessToolByWorkorderProcessId(workorderProcessId);
            proWorkOrderProcessTools.addAll(proWorkOrderProcessToolsList);
        }

        if (CollectionUtil.isEmpty(proWorkOrderProcessTools)) {
            return 0;
        }

        //根据tool_id进行判重，只保留要求数量最大的
        Map<Long, ProWorkOrderProcessTool> toolIdAndProcessToolMap = new HashMap<>();//tool_id,工装对象
        for (ProWorkOrderProcessTool proWorkOrderProcessTool : proWorkOrderProcessTools) {
            if (BeanUtil.isEmpty(toolIdAndProcessToolMap.get(proWorkOrderProcessTool.getToolId()))) {
                toolIdAndProcessToolMap.put(proWorkOrderProcessTool.getToolId(), proWorkOrderProcessTool);
            } else {
                ProWorkOrderProcessTool proWorkOrderProcessToolMap = toolIdAndProcessToolMap.get(proWorkOrderProcessTool.getToolId());
                BigDecimal quantity = proWorkOrderProcessToolMap.getQuantity() == null ? BigDecimal.ZERO : proWorkOrderProcessToolMap.getQuantity();
                if (quantity.compareTo(proWorkOrderProcessTool.getQuantity()) < 0) {//当map中的数量小于时，将新的替换
                    toolIdAndProcessToolMap.put(proWorkOrderProcessTool.getToolId(), proWorkOrderProcessTool);
                }
            }
        }


        List<TmToolMachines> tmToolMachinesList = getTmToolMachines(taskWorkunitId);
        Map<Long, Double> doubleMap = tmToolMachinesList.stream().collect(Collectors.groupingBy(TmToolMachines::getToolId, Collectors.summingDouble(x -> DataUtil.getNormalData(x.getQuantity()).intValue())));

        List<ProWorkOrderProcessTool> workOrderProcessToolSwap = new ArrayList<>();
        Set<Long> toolIds = toolIdAndProcessToolMap.keySet();
        for (Long toolId : toolIds) {
            ProWorkOrderProcessTool proWorkOrderProcessTool = toolIdAndProcessToolMap.get(toolId);
            if (proWorkOrderProcessTool == null) {
                Double v = doubleMap.get(toolId);
                BigDecimal quantity = proWorkOrderProcessTool.getQuantity();
                proWorkOrderProcessTool.setQuantity(quantity.subtract(new BigDecimal(v)));
                workOrderProcessToolSwap.add(proWorkOrderProcessTool);
                requestNum = requestNum + proWorkOrderProcessTool.getQuantity().intValue();
            }
        }
        proWorkOrderProcessTools = workOrderProcessToolSwap;


        //----------1.新增申请单主表数据
        TmToolRequest tmToolRequest = new TmToolRequest();
        tmToolRequest.setProcessId(processId);
        tmToolRequest.setWorkunitId(proTask.getWorkunitId());
        tmToolRequest.setTaskWorkunitId(taskWorkunitId);
        tmToolRequest.setTaskId(taskId);
        tmToolRequest.setRequestDate(new Date());
        tmToolRequest.setStartTime(DataUtil.repliceData(tmToolRequest.getStartTime(), proTask.getStartTime()));
        tmToolRequest.setEndTime(DataUtil.repliceData(tmToolRequest.getEndTime(), proTask.getEndTime()));
        //总数量取生产工单中工序的工装夹具的总数量
        tmToolRequest.setRequestNum(requestNum);
        //编排编号（后续获取）
        tmToolRequest.setArrangeCode(queryTask.getArrangeCode());
        //申请数量取排产单中
        int estimatedLifeTime = 0;
        if (null != proTask.getQuantity()) {
            estimatedLifeTime = proTask.getQuantity().intValue();
        }

        tmToolRequest.setEstimatedLifeTime(estimatedLifeTime);//预计使用寿命取

        i = this.insertTmToolRequest(tmToolRequest);
        Long toolRequestId = tmToolRequest.getToolRequestId();//申请表主键id

        //------2.新增申请单附表信息
        for (ProWorkOrderProcessTool proWorkOrderProcessTool : proWorkOrderProcessTools) {
            if (null == proWorkOrderProcessTool.getQuantity()) {
                continue;
            }

            int quantity = proWorkOrderProcessTool.getQuantity().intValue();
            if (quantity <= 0) {
                continue;
            }

            for (int j = 0; j < quantity; j++) {
                TmToolRequestItem tmToolRequestItem = new TmToolRequestItem();
                tmToolRequestItem.setToolRequestId(toolRequestId);
                tmToolRequestItem.setItemId(proWorkOrderProcessTool.getToolId());
                tmToolRequestItem.setQuantity(1);
                tmToolRequestItemService.insertTmToolRequestItem(tmToolRequestItem);
            }
        }

        return i;
    }


    /**
     * 排产创建刀模版申请单
     *
     * @param proTaskWorkunits 刀模版申请单
     * @return 结果
     */
    @Override
    public void addedToolRequestAppForm(List<ProTaskWorkunit> proTaskWorkunits) {
        if (CollectionUtil.isEmpty(proTaskWorkunits)) {
            log.info("排产任务不存在");
            return;
        }

        List<ProTask> proTasks = proTaskService.selectListByQw(new QueryWrapper<ProTask>().in("t1.task_id",  proTaskWorkunits.stream().map(ProTaskWorkunit::getTaskId).collect(Collectors.toSet())));
        if (CollectionUtil.isEmpty(proTasks)) {
            log.info("工序任务不存在");
            return;
        }

        Map<Long, ProTask> taskMap = new HashMap<>();
        proTasks = proTasks.stream().filter(x -> x.getTaskId() != null).collect(Collectors.toList());
        for (ProTask proTask : proTasks) {
            ProTask proTask1 = taskMap.get(proTask.getTaskId());
            if (proTask1 == null) {
                taskMap.put(proTask.getTaskId(), proTask);
            }
        }

        // 按照工作单元分组上线的工序任务
        Map<Long, List<ProTaskWorkunit>> byWorkunitIdMap = proTaskWorkunits.stream().collect(Collectors.groupingBy(ProTaskWorkunit::getWorkunitId));
        for (Map.Entry<Long, List<ProTaskWorkunit>> entry : byWorkunitIdMap.entrySet()) {
            List<ProTaskWorkunit> taskWorkunitList = entry.getValue();
            for (ProTaskWorkunit proTaskWorkunit : taskWorkunitList) {
                //获取任务单的taskId和processId
                Long taskId = proTaskWorkunit.getTaskId();
                ProTask proTask = taskMap.get(taskId);
                Long processId = proTask.getProcessId();

                //如果生产工单的工艺下没有设置工装夹具则不生成申请单
                //同过任务单id查询所有工单
                ProTaskWorkorder proTaskWorkorder = new ProTaskWorkorder();
                proTaskWorkorder.setTaskId(taskId);
                List<ProTaskWorkorder> proTaskWorkorders = proTaskWorkorderMapper.selectProTaskWorkorderList(proTaskWorkorder);
                if (CollectionUtil.isEmpty(proTaskWorkorders)) {
                    continue;
                }

                QueryWrapper<ProWorkOrderProcess> queryWrapper = new QueryWrapper<>();
                queryWrapper.in("t1.workorder_id", proTaskWorkorders.stream().map(ProTaskWorkorder::getWorkorderId).collect(Collectors.toList()));
                queryWrapper.eq("t1.process_id", processId);
                List<ProWorkOrderProcess> proWorkOrderProcessList = proWorkOrderProcessMapper.selectListByQw(queryWrapper);
                if (CollectionUtil.isEmpty(proWorkOrderProcessList)) {
                    continue;
                }

                List<Long> workorderProcessIds = proWorkOrderProcessList.stream().map(ProWorkOrderProcess::getWorkorderProcessId).distinct().collect(Collectors.toList());
                List<ProWorkOrderProcessTool> proWorkOrderProcessTools = proWorkOrderProcessToolMapper.selectListByQw( new  QueryWrapper<ProWorkOrderProcessTool>().in("t1.workorder_process_id", workorderProcessIds));
                if (CollectionUtil.isEmpty(proWorkOrderProcessTools)) {
                    continue;
                }

                Map<Long, Optional<ProWorkOrderProcessTool>> processToolls = proWorkOrderProcessTools.stream().filter(x -> x.getQuantity() != null
                        && x.getQuantity().doubleValue() > 0).collect(Collectors.groupingBy(ProWorkOrderProcessTool::getToolId, Collectors.maxBy(Comparator.comparingDouble(x -> x.getQuantity().doubleValue()))));

                List<ProWorkOrderProcessTool> processTools = new ArrayList<>();
                int requestNum = 0;

                for (Map.Entry<Long, Optional<ProWorkOrderProcessTool>> entrySet : processToolls.entrySet()) {
                    Optional<ProWorkOrderProcessTool> value = entrySet.getValue();
                    if (value.isPresent()) {
                        ProWorkOrderProcessTool tool = value.get();
                        BigDecimal quantity = tool.getQuantity();
                        requestNum = requestNum + quantity.intValue();
                        processTools.add(tool);
                    }
                }


                if (requestNum == 0) {
                    return;
                }

                // 1.新增申请单主表数据
                TmToolRequest tmToolRequest = new TmToolRequest();
                tmToolRequest.setProcessId(processId);
                tmToolRequest.setWorkunitId(proTaskWorkunit.getWorkunitId());
                tmToolRequest.setTaskWorkunitId(proTaskWorkunit.getTaskWorkunitId());
                tmToolRequest.setTaskId(taskId);
                tmToolRequest.setRequestDate(new Date());
                tmToolRequest.setStartTime(DataUtil.repliceData(tmToolRequest.getStartTime(), proTaskWorkunits.get(0).getScheduleStartDate()));
                tmToolRequest.setEndTime(DataUtil.repliceData(tmToolRequest.getEndTime(), proTaskWorkunits.get(0).getScheduleEndDate()));

                // 申请数量取排产单中
                int estimatedLifeTime = 0;
                if (null != proTaskWorkunit.getQuantity()) {
                    estimatedLifeTime = proTaskWorkunit.getQuantity().intValue();
                }

                // 预计使用寿命取
                tmToolRequest.setEstimatedLifeTime(estimatedLifeTime);

                //总数量取生产工单中工序的工装夹具的总数量
                tmToolRequest.setRequestNum(requestNum);

                //编排编号（后续获取）
                tmToolRequest.setArrangeCode(proTask.getArrangeCode());
                this.insertTmToolRequest(tmToolRequest);

                // 1.申请表主键id
                Long toolRequestId = tmToolRequest.getToolRequestId();

                // 2.新增申请单附表信息
                for (ProWorkOrderProcessTool proWorkOrderProcessTool : processTools) {
                    int quantity = proWorkOrderProcessTool.getQuantity().intValue();
                    for (int j = 0; j < quantity; j++) {
                        TmToolRequestItem tmToolRequestItem = new TmToolRequestItem();
                        tmToolRequestItem.setToolRequestId(toolRequestId);
                        tmToolRequestItem.setItemId(proWorkOrderProcessTool.getToolId());
                        tmToolRequestItem.setQuantity(1);

                        tmToolRequestItemService.insertTmToolRequestItem(tmToolRequestItem);
                    }
                }
            }
        }

    }

    @Override
    public void updateTmToolRequestByTaskWorkunit(ProTaskWorkunit taskWorkunit) {
        QueryWrapper<TmToolRequest> query = new QueryWrapper<>();
        query.eq("task_workunit_id", taskWorkunit.getTaskWorkunitId());
        List<TmToolRequest> list = this.selectList(query);
        list.forEach(s->{
            s.setWorkunitId(taskWorkunit.getWorkunitId());
            s.setStartTime(taskWorkunit.getScheduleStartDate());
            s.setEndTime(taskWorkunit.getScheduleEndDate());
            this.updateTmToolRequest(s);
        });
    }
}
