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

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ximai.common.utils.sign.Md5Utils;
import com.ximai.mes.md.domain.MdItem;
import com.ximai.mes.md.service.IMdItemService;
import com.ximai.mes.md.service.IMdProductLookService;
import com.ximai.mes.md.service.IMdProductPublishedConfService;
import com.ximai.mes.pro.domain.ProScheduleSetupRuleVal;
import com.ximai.mes.pro.domain.proWorkOrder.ProWorkOrderProcess;
import com.ximai.mes.pro.domain.proWorkOrder.ProWorkOrderProcessItem;
import com.ximai.mes.pro.domain.proWorkOrder.ProWorkOrderProcessTool;
import com.ximai.mes.pro.domain.proWorkOrder.ProWorkorder;
import com.ximai.mes.pro.domain.productionSolution.ProProductionSolution;
import com.ximai.mes.pro.domain.productionSolution.ProProductionSolutionSpecificationSheet;
import com.ximai.mes.pro.domain.vo.ProProductionSolutionVo;
import com.ximai.mes.pro.domain.vo.ProWorkOrderProcessVo;
import com.ximai.mes.pro.mapper.ProScheduleSetupRuleValMapper;
import com.ximai.mes.pro.service.IProScheduleSetupRuleValService;
import com.ximai.mes.pro.service.proWorkOrder.IProWorkOrderProcessItemService;
import com.ximai.mes.pro.service.proWorkOrder.IProWorkOrderProcessService;
import com.ximai.mes.pro.service.proWorkOrder.IProWorkOrderProcessToolService;
import com.ximai.mes.pro.service.productionSolution.IProProductionSolutionService;
import com.ximai.mes.pro.service.productionSolution.IProProductionSolutionSpecificationSheetService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 排产换型属性值信息Service业务层处理
 *
 * @author generator
 * @date 2024-04-01
 */
@Service
public class ProScheduleSetupRuleValServiceImpl implements IProScheduleSetupRuleValService {
    @Autowired
    private ProScheduleSetupRuleValMapper proScheduleSetupRuleValMapper;
    @Autowired
    private IMdItemService mdItemService;
    @Autowired
    private IProWorkOrderProcessService proWorkOrderProcessService;
    @Autowired
    private IProProductionSolutionService proProductionSolutionService;
    @Autowired
    private IProProductionSolutionSpecificationSheetService proProductionSolutionSpecificationSheetService;
    @Autowired
    private IProWorkOrderProcessItemService proWorkOrderProcessItemService;
    @Autowired
    private IProWorkOrderProcessToolService proWorkOrderProcessToolService;
    @Autowired
    private IMdProductLookService mdProductLookService;
    @Autowired
    private IMdProductPublishedConfService mdProductPublishedConfService;

    /**
     * 查询排产换型属性值信息
     *
     * @param ruleValId 排产换型属性值信息主键
     * @return 排产换型属性值信息
     */
    @Override
    public ProScheduleSetupRuleVal selectProScheduleSetupRuleValByRuleValId(Long ruleValId) {
        return proScheduleSetupRuleValMapper.selectProScheduleSetupRuleValByRuleValId(ruleValId);
    }

    /**
     * 查询排产换型属性值信息列表
     *
     * @param proScheduleSetupRuleVal 排产换型属性值信息
     * @return 排产换型属性值信息
     */
    @Override
    public List<ProScheduleSetupRuleVal> selectProScheduleSetupRuleValList(ProScheduleSetupRuleVal proScheduleSetupRuleVal) {
        return proScheduleSetupRuleValMapper.selectProScheduleSetupRuleValList(proScheduleSetupRuleVal);
    }

    /**
     * 新增排产换型属性值信息
     *
     * @param proScheduleSetupRuleVal 排产换型属性值信息
     * @return 结果
     */
    @Override
    public int insertProScheduleSetupRuleVal(ProScheduleSetupRuleVal proScheduleSetupRuleVal) {
        proScheduleSetupRuleVal.createAction();
        return proScheduleSetupRuleValMapper.insertProScheduleSetupRuleVal(proScheduleSetupRuleVal);
    }

    /**
     * 修改排产换型属性值信息
     *
     * @param proScheduleSetupRuleVal 排产换型属性值信息
     * @return 结果
     */
    @Override
    public int updateProScheduleSetupRuleVal(ProScheduleSetupRuleVal proScheduleSetupRuleVal) {
        proScheduleSetupRuleVal.updateAction();
        return proScheduleSetupRuleValMapper.updateProScheduleSetupRuleVal(proScheduleSetupRuleVal);
    }

    /**
     * 批量删除排产换型属性值信息
     *
     * @param ruleValIds 需要删除的排产换型属性值信息主键
     * @return 结果
     */
    @Override
    public int deleteProScheduleSetupRuleValByRuleValIds(Long[] ruleValIds) {
        return proScheduleSetupRuleValMapper.deleteProScheduleSetupRuleValByRuleValIds(ruleValIds);
    }

    /**
     * 删除排产换型属性值信息信息
     *
     * @param ruleValId 排产换型属性值信息主键
     * @return 结果
     */
    @Override
    public int deleteProScheduleSetupRuleValByRuleValId(Long ruleValId) {
        return proScheduleSetupRuleValMapper.deleteProScheduleSetupRuleValByRuleValId(ruleValId);
    }

    @Override
    public Map<String, Map<String, Object>> selectScheduleSetupRuleValGroup(QueryWrapper<ProScheduleSetupRuleVal> query) {
        List<Map<String, Object>> list = proScheduleSetupRuleValMapper.selectProScheduleSetupRuleVal(query);
        Map<String, Map<String, Object>> rst = new HashMap<String, Map<String, Object>>();
        list.forEach(s -> {
            //key=工单id+工序名称
            String key = String.valueOf(s.get("workorder_id")) + String.valueOf(s.get("process_name"));
            rst.put(key, s);
        });
        return rst;
    }

    @Override
    public void insertProScheduleSetupRuleVal(ProWorkorder proWorkorder) {
        ProScheduleSetupRuleVal proScheduleSetupRuleVal = new ProScheduleSetupRuleVal();
        MdItem mdItem = mdItemService.selectMdItemById(proWorkorder.getProductId());
        ProWorkOrderProcess proWorkOrderProcessQuery = new ProWorkOrderProcess();
        proWorkOrderProcessQuery.setWorkorderId(proWorkorder.getWorkorderId());
        List<ProWorkOrderProcessVo> processList = proWorkOrderProcessService.selectProWorkOrderProcessList(proWorkOrderProcessQuery);
        proScheduleSetupRuleVal.setWorkorderId(proWorkorder.getWorkorderId());
        //产品
        proScheduleSetupRuleVal.setItemTypeId(mdItem.getItemTypeId());
        proScheduleSetupRuleVal.setItemTypeName(mdItem.getItemTypeName());
        proScheduleSetupRuleVal.setProductStandard(mdItem.getSpecification());
        //查询生产规格书
        ProProductionSolutionVo proProductionSolution = proProductionSolutionService.selectProProductionSolutionByProductionSolutionId(proWorkorder.getProductionSolutionId());
        if (proProductionSolution != null) {
            ProProductionSolutionSpecificationSheet specificationSheet = proProductionSolutionSpecificationSheetService.selectSpecificationSheetByProductionSolutionId(proProductionSolution.getProductionSolutionId());
            if (specificationSheet != null) {
                proScheduleSetupRuleVal.setSheetLength(specificationSheet.getPrintingPaperlenth() == null ? null : specificationSheet.getPrintingPaperlenth() + "");
                proScheduleSetupRuleVal.setSheetWidth(specificationSheet.getPrintingWidth() == null ? null : specificationSheet.getPrintingWidth() + "");
                proScheduleSetupRuleVal.setProductWidth(specificationSheet.getWidth() == null ? null : specificationSheet.getWidth() + "");
                proScheduleSetupRuleVal.setInlay(specificationSheet.getInlay());
                if (StringUtils.isBlank(specificationSheet.getOppositeColorName()) && StringUtils.isBlank(specificationSheet.getFrontColorName())) {
                    proScheduleSetupRuleVal.setProConColor(null);
                } else {
                    proScheduleSetupRuleVal.setProConColor(specificationSheet.getOppositeColorName() + specificationSheet.getFrontColorName());
                }
            }
        }
        //工单
        proScheduleSetupRuleVal.setRouteCode(processRoute(processList));
        processList.forEach(s -> {
            Map<Long, String> bomMapping = this.scheduleSetupRuleWithBom(proWorkorder, processList);
            Map<Long, String> toolMapping = this.scheduleSetupRuleWithTool(proWorkorder, processList);
            proScheduleSetupRuleVal.setProcessId(s.getProcessId());
            proScheduleSetupRuleVal.setProcessName(s.getProcessName());
            //物料清单(材料（反冲）)
            proScheduleSetupRuleVal.setMaterialRecoil(bomMapping.get(s.getProcessId()));
            //工装夹具
            proScheduleSetupRuleVal.setTool(toolMapping.get(s.getProcessId()));
            proScheduleSetupRuleVal.setApiFlag(true);
            this.insertProScheduleSetupRuleVal(proScheduleSetupRuleVal);
        });
    }

    private static String processRoute(List<ProWorkOrderProcessVo> processList) {
        String ids = processList.stream().map(s2 -> s2.getProcessName() + "").sorted().collect(Collectors.joining(","));
        return Md5Utils.hash(ids);
    }

    //BOM主键排序后MD5
    public Map<Long, String> scheduleSetupRuleWithBom(ProWorkorder proWorkorder, List<ProWorkOrderProcessVo> processList) {
        Map<Long, String> rst = new HashMap<Long, String>();
        processList.forEach(s -> {
            ProWorkOrderProcessItem query = new ProWorkOrderProcessItem();
            query.setWorkorderProcessId(s.getWorkorderProcessId());
            query.setIsBackflush("Y");
            List<ProWorkOrderProcessItem> processItemList = proWorkOrderProcessItemService.selectProWorkOrderProcessItemList(query);
            String itemIds = processItemList.stream().map(s2 -> s2.getItemId() + "").sorted().collect(Collectors.joining(","));
            rst.put(s.getProcessId(), Md5Utils.hash(itemIds));
        });
        return rst;
    }

    /**
     * 工装量具排序后MD5
     *
     * @param proWorkorder
     * @return
     */
    public Map<Long, String> scheduleSetupRuleWithTool(ProWorkorder proWorkorder, List<ProWorkOrderProcessVo> processList) {
        Map<Long, String> rst = new HashMap<Long, String>();
        processList.forEach(s -> {
            ProWorkOrderProcessTool query = new ProWorkOrderProcessTool();
            query.setWorkorderProcessId(s.getWorkorderProcessId());
            List<ProWorkOrderProcessTool> processToolList = proWorkOrderProcessToolService.selectProWorkOrderProcessToolList(query);
            String itemIds = processToolList.stream().map(s2 -> s2.getToolId() + "").sorted().collect(Collectors.joining(","));
            rst.put(s.getProcessId(), Md5Utils.hash(itemIds));
        });
        return rst;
    }


    @Override
    public void deleteScheduleSetupRuleVal(Long workorderId) {
        proScheduleSetupRuleValMapper.deleteByWorkorderId(workorderId);
    }

}
