package com.rongwei.bscommon.sys.service.impl;


import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.rongwei.bscommon.sys.dao.ApsCraftRouteDao;
import com.rongwei.bscommon.sys.service.ApsCraftRouteOutMaterRequestService;
import com.rongwei.bscommon.sys.service.ApsCraftRouteService;
import com.rongwei.bscommon.sys.service.ApsCraftRouteStepEquService;
import com.rongwei.bscommon.sys.service.ApsCraftRouteStepService;
import com.rongwei.bsentity.domain.ApsCraftRouteDo;
import com.rongwei.bsentity.domain.ApsCraftRouteOutMaterRequestDo;
import com.rongwei.bsentity.domain.ApsCraftRouteStepDo;
import com.rongwei.bsentity.domain.ApsCraftRouteStepEquDo;
import com.rongwei.bsentity.vo.PreviousProcessVo;
import com.rongwei.commonservice.serial.service.impl.SysSerialNumberServiceImpl;
import com.rongwei.commonservice.service.SysMindMappingService;
import com.rongwei.rwcommon.base.R;
import com.rongwei.rwcommon.utils.SecurityUtil;
import com.rongwei.rwcommon.utils.StringUtils;
import com.rongwei.rwcommonentity.commonservers.domain.SysMindMappingDo;
import com.rongwei.rwcommonentity.commonservers.vo.SysSerialVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 *
 */
@Service
public class ApsCraftRouteServiceImpl extends ServiceImpl<ApsCraftRouteDao, ApsCraftRouteDo>
        implements ApsCraftRouteService {

    @Autowired
    private ApsCraftRouteService apsCraftRouteService;

    @Autowired
    private ApsCraftRouteStepService apsCraftRouteStepService;

    @Autowired
    private ApsCraftRouteOutMaterRequestService apsCraftRouteOutMaterRequestService;

    @Autowired
    private ApsCraftRouteStepEquService apsCraftRouteStepEquService;

    @Autowired
    SysMindMappingService sysMindMappingService;

    @Autowired
    private SysSerialNumberServiceImpl sysSerialNumberService;

    /*
    复制工艺路线
     */
    @Override
    public R copyCraftRoute(Map<String, Object> params) {
        String craftrouteid = params.get("CRAFTROUTEID").toString();
        String newRouteId = SecurityUtil.getUUID();
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
        LocalDateTime now = LocalDateTime.now();
        //流水号
        SysSerialVo sysSerialVo = new SysSerialVo();
        sysSerialVo.setRuleTemplateStr("GL@{date:yyyyMMdd}@{serialNumber:#0000}");
        sysSerialVo.setModulecode("aps_craft_route_ROUTENUM");
        sysSerialVo.setResetrule("date:yyyyMMdd");
        sysSerialVo.setIfautomaticreset("y");

        //原工艺路线-->新工艺路线
        ApsCraftRouteDo newCraftRouteDo = apsCraftRouteService.getById(craftrouteid);
        newCraftRouteDo.setId(newRouteId);
        newCraftRouteDo.setRoutename(newCraftRouteDo.getRoutename() + "-" + now.format(dateTimeFormatter));
        newCraftRouteDo.setRoutenum(sysSerialNumberService.getCodeByTemplate(sysSerialVo));
        newCraftRouteDo.setRoption("复制");

        //工艺路线对应的步骤信息
        Map<String, Object> map = new HashMap<>();
        map.put("CRAFTROUTEID", craftrouteid);
        List<ApsCraftRouteStepDo> apsCraftRouteStepDoList = apsCraftRouteStepService.listByMap(map).stream().collect(Collectors.toList());
        Collections.sort(apsCraftRouteStepDoList, Comparator.comparingInt(ApsCraftRouteStepDo::getLevel));
        Collections.sort(apsCraftRouteStepDoList, Comparator.comparing(ApsCraftRouteStepDo::getCreatedate));

        //工艺路线对应的输出
        List<ApsCraftRouteOutMaterRequestDo> apsCraftRouteOutMaterRequestDoList = apsCraftRouteOutMaterRequestService.listByMap(map).stream().collect(Collectors.toList());

        //工艺路线对应的可选设备
        List<ApsCraftRouteStepEquDo> apsCraftRouteStepEquDoList = apsCraftRouteStepEquService.listByMap(map).stream().collect(Collectors.toList());

        //工艺路线对应的思维导图
        List<SysMindMappingDo> sysMindMappingDos = new ArrayList<>();
        Map<String, Object> mindMap = new HashMap<>();
        mindMap.put("BSID", craftrouteid);
        List<SysMindMappingDo> sysMindMappingDoList = sysMindMappingService.listByMap(mindMap).stream().collect(Collectors.toList());
        Collections.sort(sysMindMappingDoList, Comparator.comparing(SysMindMappingDo::getTreecode, Comparator.nullsFirst(Comparator.naturalOrder())));
        if (sysMindMappingDoList.size() == 0) {
            return R.error("工艺路线图不存在");
        }
        SysMindMappingDo sysMindMappingDo = BeanUtil.toBean(sysMindMappingDoList.get(0), SysMindMappingDo.class);
        String mindStrId = SecurityUtil.getUUID();
        sysMindMappingDo.setId(mindStrId);
        sysMindMappingDo.setBsid(newRouteId);
        sysMindMappingDos.add(sysMindMappingDo);

        List<String> overRouteStepIds = new ArrayList<>();
        List<PreviousProcessVo> newProcessIds = new ArrayList<>();//前道步骤信息
        List<ApsCraftRouteStepDo> apsCraftRouteStepDos = new ArrayList<>();//新的步骤
        List<ApsCraftRouteOutMaterRequestDo> apsCraftRouteOutMaterRequestDos = new ArrayList<>();//新的输出
        List<ApsCraftRouteStepEquDo> apsCraftRouteStepEquDos = new ArrayList<>();//新的可选设备
        for (ApsCraftRouteStepDo apsCraftRouteStepDo : apsCraftRouteStepDoList) {
            if (overRouteStepIds.contains(apsCraftRouteStepDo.getId())) {
                continue;
            } else {
                String stepId;
                ApsCraftRouteStepDo craftRouteStepDo;
                PreviousProcessVo previousProcessVo;
                if (StringUtils.isNotBlank(apsCraftRouteStepDo.getPreviousstepid())) {
                    //后面步骤
                    List<ApsCraftRouteStepDo> apsCraftRouteStepDoList1 = apsCraftRouteStepDoList.stream().filter(acrs -> apsCraftRouteStepDo.getPreviousstepid().equals(acrs.getPreviousstepid())).collect(Collectors.toList());
                    Collections.sort(apsCraftRouteStepDoList1, Comparator.comparing(ApsCraftRouteStepDo::getCreatedate));
                    for (ApsCraftRouteStepDo apsCraftRouteStepDo1 : apsCraftRouteStepDoList1) {
                        previousProcessVo = new PreviousProcessVo();
                        stepId = SecurityUtil.getUUID();
                        craftRouteStepDo = BeanUtil.toBean(apsCraftRouteStepDo1, ApsCraftRouteStepDo.class);

                        craftRouteStepDo.setId(stepId);
                        craftRouteStepDo.setCraftrouteid(newRouteId);
                        //前道步骤
                        List<PreviousProcessVo> processVo = newProcessIds.stream().filter(pro -> pro.getPreviousstepid().equals(apsCraftRouteStepDo1.getPreviousstepid())).collect(Collectors.toList());
                        //更新前道步骤的后道步骤
                        ApsCraftRouteStepDo aDo = apsCraftRouteStepDos.stream().filter(qtr -> processVo.get(0).getProcessId().equals(qtr.getId())).findAny().orElse(null);
                        aDo.setNextstepid(aDo.getNextstepid().replace(apsCraftRouteStepDo1.getId(), stepId));

                        craftRouteStepDo.setPreviousstepid(processVo.get(0).getProcessId());
                        craftRouteStepDo.setPreviousstepname(processVo.get(0).getProcessName());

                        //本道步骤信息
                        previousProcessVo.setProcessId(stepId);//新步骤ID
                        previousProcessVo.setProcessName(apsCraftRouteStepDo1.getProcessname());
                        previousProcessVo.setPreviousstepid(apsCraftRouteStepDo1.getId());//原步骤ID

                        //本道步骤的输出
                        List<ApsCraftRouteOutMaterRequestDo> craftRouteOutMaterRequestDos = apsCraftRouteOutMaterRequestDoList.stream().filter(omd -> apsCraftRouteStepDo1.getId().equals(omd.getCraftstepid())).collect(Collectors.toList());
                        if (craftRouteOutMaterRequestDos.size() == 0) {
                            return R.error("工艺步骤" + craftRouteStepDo.getProcessname() + "没输出");
                        }
                        for (ApsCraftRouteOutMaterRequestDo craftRouteOutMaterRequestDo : craftRouteOutMaterRequestDos) {
                            craftRouteOutMaterRequestDo.setId(SecurityUtil.getUUID());
                            craftRouteOutMaterRequestDo.setCraftrouteid(newRouteId);
                            craftRouteOutMaterRequestDo.setCraftstepid(stepId);

                            apsCraftRouteOutMaterRequestDos.add(craftRouteOutMaterRequestDo);
                        }

                        //本道步骤的可选设备
                        List<ApsCraftRouteStepEquDo> craftRouteStepEquDoList = apsCraftRouteStepEquDoList.stream().filter(crse -> apsCraftRouteStepDo1.getId().equals(crse.getCraftstepid())).collect(Collectors.toList());
                        for (ApsCraftRouteStepEquDo craftRouteStepEquDo : craftRouteStepEquDoList) {
                            craftRouteStepEquDo.setId(SecurityUtil.getUUID());
                            craftRouteStepEquDo.setCraftrouteid(newRouteId);
                            craftRouteStepEquDo.setCraftstepid(stepId);

                            apsCraftRouteStepEquDos.add(craftRouteStepEquDo);
                        }

                        //本道步骤思维导图
                        List<SysMindMappingDo> sysMindMappingDoList1 = sysMindMappingDoList.stream().filter(mind -> mind.getId().equals(apsCraftRouteStepDo1.getId())).collect(Collectors.toList());
                        SysMindMappingDo sysMindMappingDo1 = sysMindMappingDoList1.get(0);
                        sysMindMappingDo1.setId(stepId);
                        sysMindMappingDo1.setParentid(processVo.get(0).getProcessId());
                        sysMindMappingDo1.setBsid(newRouteId);
                        //存新的步骤信息
                        JSONObject jsonObject = JSON.parseObject(sysMindMappingDo1.getRoption());
                        jsonObject.put("ID", stepId);
                        jsonObject.put("CRAFTROUTEID", newRouteId);
                        sysMindMappingDo1.setRoption(jsonObject.toString());

                        sysMindMappingDos.add(sysMindMappingDo1);
                        newProcessIds.add(previousProcessVo);
                        apsCraftRouteStepDos.add(craftRouteStepDo);

                        overRouteStepIds.add(apsCraftRouteStepDo1.getId());
                    }
                } else {
                    //首道步骤
                    previousProcessVo = new PreviousProcessVo();
                    stepId = SecurityUtil.getUUID();
                    craftRouteStepDo = BeanUtil.toBean(apsCraftRouteStepDo, ApsCraftRouteStepDo.class);

                    //本道步骤信息
                    previousProcessVo.setProcessId(stepId);//新步骤ID
                    previousProcessVo.setProcessName(apsCraftRouteStepDo.getProcessname());
                    previousProcessVo.setPreviousstepid(apsCraftRouteStepDo.getId());//原步骤ID

                    //本道步骤输出
                    List<ApsCraftRouteOutMaterRequestDo> craftRouteOutMaterRequestDos = apsCraftRouteOutMaterRequestDoList.stream().filter(omd -> apsCraftRouteStepDo.getId().equals(omd.getCraftstepid())).collect(Collectors.toList());
                    if (craftRouteOutMaterRequestDos.size() == 0) {
                        return R.error("工艺步骤" + apsCraftRouteStepDo.getProcessname() + "没输出");
                    }
                    for (ApsCraftRouteOutMaterRequestDo craftRouteOutMaterRequestDo : craftRouteOutMaterRequestDos) {
                        craftRouteOutMaterRequestDo.setId(SecurityUtil.getUUID());
                        craftRouteOutMaterRequestDo.setCraftrouteid(newRouteId);
                        craftRouteOutMaterRequestDo.setCraftstepid(stepId);

                        apsCraftRouteOutMaterRequestDos.add(craftRouteOutMaterRequestDo);
                    }

                    //本道步骤的可选设备
                    List<ApsCraftRouteStepEquDo> craftRouteStepEquDoList = apsCraftRouteStepEquDoList.stream().filter(crse -> apsCraftRouteStepDo.getId().equals(crse.getCraftstepid())).collect(Collectors.toList());
                    for (ApsCraftRouteStepEquDo craftRouteStepEquDo : craftRouteStepEquDoList) {
                        craftRouteStepEquDo.setId(SecurityUtil.getUUID());
                        craftRouteStepEquDo.setCraftrouteid(newRouteId);
                        craftRouteStepEquDo.setCraftstepid(stepId);

                        apsCraftRouteStepEquDos.add(craftRouteStepEquDo);
                    }

                    //本道步骤思维导图
                    List<SysMindMappingDo> sysMindMappingDoList1 = sysMindMappingDoList.stream().filter(mind -> mind.getId().equals(apsCraftRouteStepDo.getId())).collect(Collectors.toList());
                    SysMindMappingDo sysMindMappingDo1 = sysMindMappingDoList1.get(0);
                    sysMindMappingDo1.setId(stepId);
                    sysMindMappingDo1.setParentid(mindStrId);
                    sysMindMappingDo1.setBsid(newRouteId);
                    //存新的步骤信息
                    JSONObject jsonObject = JSON.parseObject(sysMindMappingDo1.getRoption());
                    jsonObject.put("ID", stepId);
                    jsonObject.put("CRAFTROUTEID", newRouteId);
                    sysMindMappingDo1.setRoption(jsonObject.toString());

                    craftRouteStepDo.setId(stepId);
                    craftRouteStepDo.setCraftrouteid(newRouteId);

                    sysMindMappingDos.add(sysMindMappingDo1);
                    newProcessIds.add(previousProcessVo);
                    apsCraftRouteStepDos.add(craftRouteStepDo);
                }
            }
        }

        boolean bool1 = apsCraftRouteService.save(newCraftRouteDo);
        boolean bool2 = apsCraftRouteStepService.saveOrUpdateBatch(apsCraftRouteStepDos);
        boolean bool3 = apsCraftRouteOutMaterRequestService.saveOrUpdateBatch(apsCraftRouteOutMaterRequestDos);
        boolean bool4 = apsCraftRouteStepEquService.saveOrUpdateBatch(apsCraftRouteStepEquDos);
        boolean bool5 = sysMindMappingService.saveOrUpdateBatch(sysMindMappingDos);

        if (bool1 && bool2 && bool3 && bool4 && bool5) {
            return R.ok(newRouteId);
        } else {
            return R.error("复制工艺路线失败");
        }
    }
}




