package cn.estsh.i3plus.ext.mes.apiservice.serviceimpl.busi.jx;

import cn.estsh.i3plus.ext.mes.api.base.bu.IBusiConfigService;
import cn.estsh.i3plus.ext.mes.api.busi.jx.IJxCenterWorkingBoardService;
import cn.estsh.i3plus.ext.mes.pojo.bean.MesBusiConfig;
import cn.estsh.i3plus.ext.mes.pojo.bean.MesOutPutStatistics;
import cn.estsh.i3plus.ext.mes.pojo.bean.MesWorkCenterExt;
import cn.estsh.i3plus.ext.mes.pojo.model.jx.JxCenterWorkingBoardBusiModel;
import cn.estsh.i3plus.ext.mes.pojo.util.MesExtConstWords;
import cn.estsh.i3plus.pojo.base.enumutil.CommonEnumUtil;
import cn.estsh.i3plus.pojo.mes.bean.MesWorkOrder;
import cn.estsh.impp.framework.boot.util.SpringContextsUtil;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

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

/**
 * @Author : wangjie
 * @CreateDate : 2022-02-15
 * @Modify:
 **/
@Slf4j
public class JxCenterWorkingBoardProxyProductionScheduleService extends JxCenterWorkingBoardCommonService implements IJxCenterWorkingBoardService {

    private IBusiConfigService busiConfigService;

    public JxCenterWorkingBoardProxyProductionScheduleService() {
        this.busiConfigService = (IBusiConfigService) SpringContextsUtil.getBean("busiConfigService");
    }

    @Override
    public Map<String, Object> queryCenterWorkingBoardData(Map<String, Object> dataMap) {

        String organizeCode = (String) dataMap.get(MesExtConstWords.ORGANIZE_CODE);

        List<MesWorkCenterExt> workCenterExtDbList = (List<MesWorkCenterExt>) dataMap.get(MesWorkCenterExt.class.getSimpleName());

        dataMap.put("生产进度", getProductionSchedule(organizeCode, workCenterExtDbList, dataMap));

        return dataMap;
    }

    private JxCenterWorkingBoardBusiModel getProductionSchedule(String organizeCode, List<MesWorkCenterExt> workCenterExtDbList, Map<String, Object> dataMap) {

        JxCenterWorkingBoardBusiModel psData = new JxCenterWorkingBoardBusiModel().title("生产进度");

        List<MesWorkOrder> workOrderList = (List<MesWorkOrder>) dataMap.get(MesWorkOrder.class.getSimpleName());
        List<MesOutPutStatistics> outPutStatisticsList = (List<MesOutPutStatistics>) dataMap.get(MesOutPutStatistics.class.getSimpleName());
        if (CollectionUtils.isEmpty(workOrderList) && CollectionUtils.isEmpty(outPutStatisticsList)) return psData;

        String categoryCodeCfg4Cached = (String) execCachedCenterWorkingBoardData(organizeCode, MesExtConstWords.ZERO_STR, MesExtConstWords.SX_CATEGORY_CFG, null);
        MesBusiConfig categoryCodeCfg = !StringUtils.isEmpty(categoryCodeCfg4Cached) ? JSONObject.parseObject(categoryCodeCfg4Cached, MesBusiConfig.class) : execCatagoryCodeCfg(organizeCode);
        if (null == categoryCodeCfg || StringUtils.isEmpty(categoryCodeCfg.getCfgValue()) || StringUtils.isEmpty(categoryCodeCfg.getCfgValueSeq())) return psData;

        String[] categoryCodeArr = categoryCodeCfg.getCfgValueSeq().split(MesExtConstWords.COMMA);
        String[] categoryNameArr = categoryCodeCfg.getCfgValue().split(MesExtConstWords.COMMA);
        if (categoryCodeArr.length != categoryNameArr.length) return psData;

        Map<String, List<MesWorkOrder>> centerMap4OrderFilter = new HashMap<>();
        Map<String, List<MesOutPutStatistics>> centerMap4OutPutFilter = new HashMap<>();

        Map<String, List<MesWorkOrder>> centerMap4Order = getCenterMap4Order(workOrderList);
        Map<String, List<MesOutPutStatistics>> centerMap4OutPut = getCenterMap4OutPut(outPutStatisticsList);

        Map<String, List<MesWorkOrder>> categoryCodeMap4Order = new HashMap<>();
        Map<String, List<MesOutPutStatistics>> categoryCodeMap4OutPut = new HashMap<>();

        for (MesWorkCenterExt workCenterExtDb : workCenterExtDbList) {
            if (null == workCenterExtDb) continue;
            if (StringUtils.isEmpty(workCenterExtDb.getCategoryCode()) || StringUtils.isEmpty(workCenterExtDb.getWorkTime()) || StringUtils.isEmpty(workCenterExtDb.getShiftCode())) continue;

            List<MesWorkOrder> workOrderList4Center = CollectionUtils.isEmpty(centerMap4Order) ? null : getWorkOrderListByWorkTime(centerMap4Order.get(workCenterExtDb.getWorkCenterCode()), workCenterExtDb.getWorkTime());
            List<MesOutPutStatistics> outPutStatisticsList4Center = CollectionUtils.isEmpty(centerMap4OutPut) ? null : getOutPutStatisticsListByWorkTime(centerMap4OutPut.get(workCenterExtDb.getWorkCenterCode()), workCenterExtDb.getWorkTime());

            List<MesWorkOrder> categoryCodeList4Order = (!CollectionUtils.isEmpty(categoryCodeMap4Order) && categoryCodeMap4Order.containsKey(workCenterExtDb.getCategoryCode())) ? categoryCodeMap4Order.get(workCenterExtDb.getCategoryCode()) : new ArrayList<>();
            List<MesOutPutStatistics> categoryCodeList4OutPut = (!CollectionUtils.isEmpty(categoryCodeMap4OutPut) && categoryCodeMap4OutPut.containsKey(workCenterExtDb.getCategoryCode())) ? categoryCodeMap4OutPut.get(workCenterExtDb.getCategoryCode()) : new ArrayList<>();
            if (!CollectionUtils.isEmpty(workOrderList4Center)) categoryCodeList4Order.addAll(workOrderList4Center);
            if (!CollectionUtils.isEmpty(outPutStatisticsList4Center)) categoryCodeList4OutPut.addAll(outPutStatisticsList4Center);

            categoryCodeMap4Order.put(workCenterExtDb.getCategoryCode(), categoryCodeList4Order);
            categoryCodeMap4OutPut.put(workCenterExtDb.getCategoryCode(), categoryCodeList4OutPut);

            if (!CollectionUtils.isEmpty(workOrderList4Center)) centerMap4OrderFilter.put(workCenterExtDb.getWorkCenterCode(), workOrderList4Center);
            if (!CollectionUtils.isEmpty(outPutStatisticsList4Center)) centerMap4OutPutFilter.put(workCenterExtDb.getWorkCenterCode(), outPutStatisticsList4Center);
        }

        for (int i = 0; i < categoryCodeArr.length; i ++) {
            List<MesWorkOrder> workOrderList4Category = CollectionUtils.isEmpty(categoryCodeMap4Order) ? null : categoryCodeMap4Order.get(categoryCodeArr[i]);
            List<MesOutPutStatistics> outPutStatisticsList4Category = CollectionUtils.isEmpty(categoryCodeMap4OutPut) ? null : categoryCodeMap4OutPut.get(categoryCodeArr[i]);

            Double planQtyAmount = getWorkOrderList2AmountQty(workOrderList4Category);
            Double completeQtyAmount = getOutPutStatisticsList2AmountQty(outPutStatisticsList4Category);

            psData.addChartData(categoryNameArr[i], completeQtyAmount, planQtyAmount, getBigDecimalPercent(divThenMul100Format1RoundHalfUp(completeQtyAmount, planQtyAmount)));
        }

        dataMap.put(MesWorkOrder.class.getSimpleName(), centerMap4OrderFilter);
        dataMap.put(MesOutPutStatistics.class.getSimpleName(), centerMap4OutPutFilter);

        return psData;
    }

    private MesBusiConfig execCatagoryCodeCfg(String organizeCode) {
        MesBusiConfig catagoryCodeCfg = busiConfigService.getBusiConfigByCfgCode(organizeCode, MesExtConstWords.SX_CATEGORY_CFG);
        if (null != catagoryCodeCfg) execCachedCenterWorkingBoardData(organizeCode, CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValueStr(), MesExtConstWords.SX_CATEGORY_CFG, JSONObject.toJSONString(catagoryCodeCfg));
        return catagoryCodeCfg;
    }

    private Map<String, List<MesWorkOrder>> getCenterMap4Order(List<MesWorkOrder> workOrderList) {
        return CollectionUtils.isEmpty(workOrderList) ? null : workOrderList.stream().filter(o -> null != o).collect(Collectors.groupingBy(MesWorkOrder::getWorkCenterCode));
    }

    private Map<String, List<MesOutPutStatistics>> getCenterMap4OutPut(List<MesOutPutStatistics> outPutStatisticsList) {
        return CollectionUtils.isEmpty(outPutStatisticsList) ? null : outPutStatisticsList.stream().filter(o -> null != o).collect(Collectors.groupingBy(MesOutPutStatistics::getWorkCenterCode));
    }

}
