package cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.job;

import cn.estsh.i3plus.ext.mes.pcn.api.job.IMesWorkOrderCalcQtyRestoreDispatchService;
import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtConstWords;
import cn.estsh.i3plus.platform.common.tool.MathOperation;
import cn.estsh.i3plus.pojo.base.bean.DdlPackBean;
import cn.estsh.i3plus.pojo.base.enumutil.CommonEnumUtil;
import cn.estsh.i3plus.pojo.base.tool.DdlPreparedPack;
import cn.estsh.i3plus.pojo.mes.bean.MesWorkOrder;
import cn.estsh.i3plus.pojo.mes.bean.MesWorkOrderCalcQtyRecord;
import cn.estsh.i3plus.pojo.mes.repository.MesWorkOrderCalcQtyRecordRepository;
import cn.estsh.i3plus.pojo.mes.repository.MesWorkOrderRepository;
import cn.estsh.i3plus.pojo.mes.util.MesExtEnumUtil;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
@Service
public class MesWorkOrderCalcQtyRestoreDispatchService implements IMesWorkOrderCalcQtyRestoreDispatchService {

    @Autowired
    private MesWorkOrderCalcQtyRecordRepository workOrderCalcQtyRecordRepository;

    @Autowired
    private MesWorkOrderRepository workOrderRepository;

    @Override
    public List<MesWorkOrderCalcQtyRecord> getWorkOrderCalcQtyRecordList(String organizeCode, Integer qty) {
        DdlPackBean packBean = DdlPackBean.getDdlPackBean(organizeCode);
        DdlPreparedPack.getNumEqualPack(MesExtEnumUtil.MES_LOG_DEAL_STATUS.UNDEAL.getValue(), MesPcnExtConstWords.DEAL_STATUS, packBean);
        DdlPreparedPack.getOrderByPack(new Object[]{CommonEnumUtil.ASC_OR_DESC.ASC.getValue()}, new String[]{MesPcnExtConstWords.CREATE_DATE_TIME}, packBean);
        return workOrderCalcQtyRecordRepository.findByHqlTopWhere(packBean, qty);
    }

    @Override
    public MesWorkOrder getWorkOrderDb(String organizeCode, Long workOrderId) {
        return workOrderRepository.getByProperty(
                new String[]{MesPcnExtConstWords.ORGANIZE_CODE, MesPcnExtConstWords.IS_DELETED, MesPcnExtConstWords.IS_VALID, MesPcnExtConstWords.ID},
                new Object[]{organizeCode, CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), CommonEnumUtil.IS_VAILD.VAILD.getValue(), workOrderId});
    }

    @Override
    public void doRestoreWorkOrderCalcQty(String organizeCode, MesWorkOrder workOrder, List<MesWorkOrderCalcQtyRecord> workOrderCalcQtyRecordList) {

        //搜集记录ID集合
        List<Long> idList = workOrderCalcQtyRecordList.stream().filter(o -> null != o).map(MesWorkOrderCalcQtyRecord::getId).collect(Collectors.toList());
        if (null == workOrder) {
            //修改记录状态
            saveWorkOrderCalcQtyRecord(organizeCode, idList, MesExtEnumUtil.MES_LOG_DEAL_STATUS.DEAL_FAILURE.getValue(), "工单信息不存在");
            log.info("补录生产工单计数JOB --- 补录: {} --- ID: {} --- END --- {} {} --- MesWorkOrderCalcQtyRecord: {} ---",
                    workOrderCalcQtyRecordList.get(0).getWorkOrderNo(), workOrderCalcQtyRecordList.get(0).getId(), MesExtEnumUtil.MES_LOG_DEAL_STATUS.DEAL_FAILURE.getDescription(), "工单信息不存在", idList.toString());
            return;
        }

        //计数
        Double completeQty = !StringUtils.isEmpty(workOrder.getCompleteQty()) ? workOrder.getCompleteQty() : new Double(MesPcnExtConstWords.ZERO);
        Double suspiciousPartQty = !StringUtils.isEmpty(workOrder.getSuspiciousPartQty()) ? workOrder.getSuspiciousPartQty() : new Double(MesPcnExtConstWords.ZERO);
        Double scrapPartQty = !StringUtils.isEmpty(workOrder.getScrapPartQty()) ? workOrder.getScrapPartQty() : new Double(MesPcnExtConstWords.ZERO);
        for (MesWorkOrderCalcQtyRecord workOrderCalcQtyRecord : workOrderCalcQtyRecordList) {
            if (null == workOrderCalcQtyRecord) continue;
            if (!StringUtils.isEmpty(workOrderCalcQtyRecord.getCompleteQty())) completeQty = MathOperation.add(completeQty, workOrderCalcQtyRecord.getCompleteQty());
            if (!StringUtils.isEmpty(workOrderCalcQtyRecord.getSuspiciousPartQty())) suspiciousPartQty = MathOperation.add(suspiciousPartQty, workOrderCalcQtyRecord.getSuspiciousPartQty());
            if (!StringUtils.isEmpty(workOrderCalcQtyRecord.getScrapPartQty())) scrapPartQty = MathOperation.add(scrapPartQty, workOrderCalcQtyRecord.getScrapPartQty());
        }

        //未完成数
        Double unCompleteQty = !StringUtils.isEmpty(workOrder.getUnCompleteQty()) ? workOrder.getUnCompleteQty() : workOrder.getQty();
        unCompleteQty = MathOperation.compareTo(unCompleteQty, new Double(MesPcnExtConstWords.ZERO)) <= MesPcnExtConstWords.ZERO ? new Double(MesPcnExtConstWords.ZERO) : MathOperation.sub(workOrder.getQty(), completeQty);
        if (MathOperation.compareTo(unCompleteQty, new Double(MesPcnExtConstWords.ZERO)) < MesPcnExtConstWords.ZERO) unCompleteQty = new Double(MesPcnExtConstWords.ZERO);

        //状态
        Integer workOrderStatus = workOrder.getWorkOrderStatus();
        if (workOrderStatus.compareTo(MesExtEnumUtil.ORDER_STATUS.RELEASE.getValue()) == MesPcnExtConstWords.ZERO || workOrderStatus.compareTo(MesExtEnumUtil.ORDER_STATUS.PROCESS.getValue()) == MesPcnExtConstWords.ZERO) {
            if (MathOperation.compareTo(completeQty, workOrder.getQty()) >= MesPcnExtConstWords.ZERO) workOrderStatus = MesExtEnumUtil.ORDER_STATUS.COMPLETE.getValue();
            else workOrderStatus = MesExtEnumUtil.ORDER_STATUS.PROCESS.getValue();
        }

        //添加修改属性
        Map<String, Object> propertyMap = new HashMap<>();
        Map<String, Object> conditionMap = new HashMap<>();
        conditionMap.put(MesPcnExtConstWords.ID, workOrder.getId());
        conditionMap.put(MesPcnExtConstWords.ORGANIZE_CODE, organizeCode);
        conditionMap.put(MesPcnExtConstWords.IS_DELETED, CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue());
        conditionMap.put(MesPcnExtConstWords.IS_VALID, CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue());
        if (MathOperation.compareTo(workOrder.getCompleteQty(), completeQty) != MesPcnExtConstWords.ZERO) {
            propertyMap.put(MesPcnExtConstWords.COMPLETE_QTY, completeQty);
            conditionMap.put(MesPcnExtConstWords.COMPLETE_QTY, workOrder.getCompleteQty());
        }
        if (MathOperation.compareTo(workOrder.getSuspiciousPartQty(), suspiciousPartQty) != MesPcnExtConstWords.ZERO) {
            propertyMap.put(MesPcnExtConstWords.SUSPICIOUS_PART_QTY, suspiciousPartQty);
            conditionMap.put(MesPcnExtConstWords.SUSPICIOUS_PART_QTY, workOrder.getSuspiciousPartQty());
        }
        if (MathOperation.compareTo(workOrder.getScrapPartQty(), scrapPartQty) != MesPcnExtConstWords.ZERO) {
            propertyMap.put(MesPcnExtConstWords.SCRAP_PART_QTY, scrapPartQty);
            conditionMap.put(MesPcnExtConstWords.SCRAP_PART_QTY, workOrder.getScrapPartQty());
        }
        if (MathOperation.compareTo(workOrder.getUnCompleteQty(), unCompleteQty) != MesPcnExtConstWords.ZERO) {
            propertyMap.put(MesPcnExtConstWords.UN_COMPLETE_QTY, unCompleteQty);
            conditionMap.put(MesPcnExtConstWords.UN_COMPLETE_QTY, workOrder.getUnCompleteQty());
        }
        if (workOrder.getWorkOrderStatus().compareTo(workOrderStatus) != MesPcnExtConstWords.ZERO) {
            propertyMap.put(MesPcnExtConstWords.WORK_ORDER_STATUS, workOrderStatus);
            conditionMap.put(MesPcnExtConstWords.WORK_ORDER_STATUS, workOrder.getWorkOrderStatus());
        }

        //当前没有任何修改
        if (CollectionUtils.isEmpty(propertyMap)) {
            //修改记录状态
            saveWorkOrderCalcQtyRecord(organizeCode, idList, MesExtEnumUtil.MES_LOG_DEAL_STATUS.DEAL_SUCCESS.getValue(), "工单信息无变更");
            log.info("补录生产工单计数JOB --- 补录: {} --- ID: {} --- END --- {} {} --- MesWorkOrderCalcQtyRecord: {} ---",
                    workOrder.getWorkOrderNo(), workOrder.getId(), MesExtEnumUtil.MES_LOG_DEAL_STATUS.DEAL_SUCCESS.getDescription(), "工单信息无变更", idList.toString());
            return;
        }

        //添加常规字段判断是否需要修改
        if (workOrder.getSystemSyncStatus().compareTo(CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue()) != 0) {
            propertyMap.put(MesPcnExtConstWords.SYSTEM_SYNC_STATUS, CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue());
            conditionMap.put(MesPcnExtConstWords.SYSTEM_SYNC_STATUS, workOrder.getSystemSyncStatus());
        }

        if (!workOrder.getSystemSyncDatetime().equals(MesPcnExtConstWords.EMPTY)) propertyMap.put(MesPcnExtConstWords.SYSTEM_SYNC_DATE_TIME, MesPcnExtConstWords.EMPTY);

        String userInfo = workOrderCalcQtyRecordList.get(workOrderCalcQtyRecordList.size() - MesPcnExtConstWords.ONE).getCreateUser();
        if (!workOrder.getModifyUser().equals(userInfo)) propertyMap.put(MesPcnExtConstWords.MODIFY_USER, userInfo);

        propertyMap.put(MesPcnExtConstWords.MODIFY_DATE_TIME, (new SimpleDateFormat(MesPcnExtConstWords.DATE_FORMAT_SSS)).format(new Date()));
        conditionMap.put(MesPcnExtConstWords.MODIFY_DATE_TIME, workOrder.getModifyDatetime());

        //修改值
        String[] propertyName = new String[propertyMap.size()];
        Object[] propertyValue = new Object[propertyMap.size()];

        Integer index = 0;
        for (Map.Entry<String, Object> innerEntry : propertyMap.entrySet()) {
            if (null == innerEntry) continue;
            propertyName[index] = innerEntry.getKey();
            propertyValue[index] = innerEntry.getValue();
            index ++;
        }

        //修改条件
        String[] conditionName = new String[conditionMap.size()];
        Object[] conditionValue = new Object[conditionMap.size()];

        index = 0;
        for (Map.Entry<String, Object> innerEntry : conditionMap.entrySet()) {
            if (null == innerEntry) continue;
            conditionName[index] = innerEntry.getKey();
            conditionValue[index] = innerEntry.getValue();
            index ++;
        }

        //当工单修改成功后, 再修改记录状态
        if (workOrderRepository.updateByPropertiesNoSync(conditionName, conditionValue, propertyName, propertyValue) == 1) {
            //修改记录状态
            saveWorkOrderCalcQtyRecord(organizeCode, idList, MesExtEnumUtil.MES_LOG_DEAL_STATUS.DEAL_SUCCESS.getValue(), "工单信息已变更成功");

            log.info("补录生产工单计数JOB --- 补录: {} --- ID: {} --- END --- conditionMap: {} --- propertyMap: {} --- {} {} --- MesWorkOrderCalcQtyRecord: {} ---",
                    workOrder.getWorkOrderNo(), workOrder.getId(), JSONObject.toJSONString(conditionMap), JSONObject.toJSONString(propertyMap),
                    MesExtEnumUtil.MES_LOG_DEAL_STATUS.DEAL_SUCCESS.getDescription(), "工单信息已变更成功", idList.toString());
        }

    }

    //修改记录状态
    @Override
    public void saveWorkOrderCalcQtyRecord(String organizeCode, List<Long> idList, Integer dealStatus, String remark) {
        String[] propertyName = new String[]{MesPcnExtConstWords.DEAL_STATUS, MesPcnExtConstWords.MODIFY_USER,
                MesPcnExtConstWords.MODIFY_DATE_TIME, MesPcnExtConstWords.SYSTEM_SYNC_STATUS, MesPcnExtConstWords.REMARK};
        Object[] propertyValue = new Object[]{dealStatus, MesPcnExtConstWords.JOB,
                (new SimpleDateFormat(MesPcnExtConstWords.DATE_FORMAT_SSS)).format(new Date()), CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), remark};
        DdlPackBean packBean = DdlPackBean.getDdlPackBean(organizeCode);
        DdlPreparedPack.getInPackList(idList, MesPcnExtConstWords.ID, packBean);
        workOrderCalcQtyRecordRepository.updateByPropertiesNoSync(propertyName, propertyValue, packBean);
    }

}
