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.*;
import cn.estsh.i3plus.ext.mes.pojo.model.jx.JxCenterWorkingBoardBusiModel;
import cn.estsh.i3plus.ext.mes.pojo.util.MesExtConstWords;
import cn.estsh.i3plus.ext.mes.pojo.util.MesExtEnumUtil;
import cn.estsh.i3plus.platform.common.tool.MathOperation;
import cn.estsh.i3plus.platform.common.tool.TimeTool;
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.*;
import java.util.stream.Collectors;

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

    private IJxCenterWorkingBoardService proxyService0;

    private IJxCenterWorkingBoardService proxyService1;

    private IJxCenterWorkingBoardService proxyService2;

    private IJxCenterWorkingBoardService proxyService3;

    private IJxCenterWorkingBoardService proxyService;

    private IBusiConfigService busiConfigService;

    public JxCenterWorkingBoardMobileOneService(IJxCenterWorkingBoardService proxyService0, IJxCenterWorkingBoardService proxyService1, IJxCenterWorkingBoardService proxyService2, IJxCenterWorkingBoardService proxyService3, IJxCenterWorkingBoardService proxyService) {
        this.proxyService0 = proxyService0;
        this.proxyService1 = proxyService1;
        this.proxyService2 = proxyService2;
        this.proxyService3 = proxyService3;
        this.proxyService = proxyService;
        this.busiConfigService = (IBusiConfigService) SpringContextsUtil.getBean("busiConfigService");
    }

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

        proxyService0.queryCenterWorkingBoardData(dataMap);

        proxyService1.queryCenterWorkingBoardData(dataMap);

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

        packProxyCondition(dataMap, workCenterExtDbList);

        proxyService.queryCenterWorkingBoardData(dataMap);

        proxyService2.queryCenterWorkingBoardData(dataMap);

        calcOntologyLineData(workCenterExtDbList, dataMap);

        return clearUselessData(dataMap);
    }

    @Override
    public Map<String, Object> clearUselessData(Map<String, Object> dataMap) {
        dataMap.remove(MesWorkCenterExt.class.getSimpleName());
        dataMap.remove(MesWorkOrder.class.getSimpleName());
        dataMap.remove(MesOutPutStatistics.class.getSimpleName());
        dataMap.remove(MesShiftProdCenterRecord.class.getSimpleName());
        dataMap.remove(MesShiftProdCenterPm.class.getSimpleName());
        dataMap.remove(MesExtConstWords.START_TIME);
        dataMap.remove(MesExtConstWords.END_TIME);
        dataMap.remove(MesExtConstWords.WORK_TIME);
        dataMap.remove(MesExtConstWords.WORK_CENTER_CODE);
        dataMap.remove(MesExtConstWords.STANDARD_WORK);
        dataMap.remove("serviceTime");
        dataMap.remove("standardTime");
        dataMap.remove("curTime");
        return dataMap;
    }

    private void packProxyCondition(Map<String, Object> dataMap, List<MesWorkCenterExt> workCenterExtDbList) {
        List<String> workTimeList = workCenterExtDbList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getWorkTime()) && !StringUtils.isEmpty(o.getShiftCode()))).map(MesWorkCenterExt::getWorkTime).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(workTimeList)) return;
        Collections.sort(workTimeList);
        dataMap.put(MesExtConstWords.START_TIME, workTimeList.get(0));
        dataMap.put(MesExtConstWords.END_TIME, workTimeList.get(workTimeList.size() - 1));
        dataMap.put("curTime", TimeTool.getNowTime(true));
        dataMap.put("onlyCalcRate", CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValueStr());
    }

    private List<MesBusiConfig> execConfigListSortSeq(String organizeCode) {
        List<MesBusiConfig> busiConfigList = busiConfigService.getConfigListSortSeq(organizeCode, MesExtConstWords.BOARD_WORK_SHOW_FLAG);
        if (!CollectionUtils.isEmpty(busiConfigList)) execCachedCenterWorkingBoardData(organizeCode, CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValueStr(), MesExtConstWords.BOARD_WORK_SHOW_FLAG, JSONObject.toJSONString(busiConfigList));
        return busiConfigList;
    }

    private Map<String, Object> calcOntologyLineData(List<MesWorkCenterExt> workCenterExtDbList, Map<String, Object> dataMap) {

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

        JxCenterWorkingBoardBusiModel psData1 = new JxCenterWorkingBoardBusiModel().title("本体能率");
        JxCenterWorkingBoardBusiModel psData2 = new JxCenterWorkingBoardBusiModel().title("项目");

        String busiConfigList4Cached = (String) execCachedCenterWorkingBoardData(organizeCode, MesExtConstWords.ZERO_STR, MesExtConstWords.BOARD_WORK_SHOW_FLAG, null);
        List<MesBusiConfig> busiConfigList = !StringUtils.isEmpty(busiConfigList4Cached) ? JSONObject.parseArray(busiConfigList4Cached, MesBusiConfig.class) : execConfigListSortSeq(organizeCode);
        if (CollectionUtils.isEmpty(busiConfigList)) return packOntologyLineData(dataMap, psData1, psData2);

        Map<String, MesWorkCenterExt> workCenterExtDbMap = workCenterExtDbList.stream().filter(o -> null != o).collect(Collectors.toMap(MesWorkCenterExt::getWorkCenterCode, o -> o));

        Map<String, List<MesWorkOrder>> centerMap4OrderFilter = (Map<String, List<MesWorkOrder>>) dataMap.get(MesWorkOrder.class.getSimpleName());
        Map<String, List<MesOutPutStatistics>> centerMap4OutPutFilter = (Map<String, List<MesOutPutStatistics>>) dataMap.get(MesOutPutStatistics.class.getSimpleName());
        List<MesShiftProdCenterRecord> shiftProdCenterRecordList = (List<MesShiftProdCenterRecord>) dataMap.get(MesShiftProdCenterRecord.class.getSimpleName());
        List<MesShiftProdCenterPm> shiftProdCenterPmList = (List<MesShiftProdCenterPm>) dataMap.get(MesShiftProdCenterPm.class.getSimpleName());

        Double planQtyAmount = new Double(0);
        Double qtyAmount = new Double(0);

        for (MesBusiConfig busiConfig : busiConfigList) {
            if (null == busiConfig || !workCenterExtDbMap.containsKey(busiConfig.getCfgValue())) continue;
            MesWorkCenterExt workCenterExtDb = workCenterExtDbMap.get(busiConfig.getCfgValue());
            if (StringUtils.isEmpty(workCenterExtDb.getLineType()) || !workCenterExtDb.getLineType().equals(MesExtEnumUtil.LINE_TYPE.ONTOLOGY_LINE.getValueStr())) continue;
            dataMap.put(MesExtConstWords.WORK_TIME, workCenterExtDb.getWorkTime());
            dataMap.put(MesExtConstWords.WORK_CENTER_CODE, workCenterExtDb.getWorkCenterCode());

            List<MesWorkOrder> workOrderList = CollectionUtils.isEmpty(centerMap4OrderFilter) ? null : centerMap4OrderFilter.get(workCenterExtDb.getWorkCenterCode());
            List<MesOutPutStatistics> outPutStatisticsListFilter = CollectionUtils.isEmpty(centerMap4OutPutFilter) ? null : centerMap4OutPutFilter.get(workCenterExtDb.getWorkCenterCode());
            dataMap.put(MesOutPutStatistics.class.getSimpleName(), outPutStatisticsListFilter);

            proxyService3.queryCenterWorkingBoardData(dataMap);

            Double planQty = statisticsOrderPlanQty(workOrderList, workCenterExtDb.getWorkTime());
            Double qty = getOutPutStatisticsList2AmountQty(outPutStatisticsListFilter);

            planQtyAmount = MathOperation.add(planQtyAmount, planQty);
            qtyAmount = MathOperation.add(qtyAmount, qty);

            psData1.addChartData(workCenterExtDb.getWorkCenterCode(), planQty, qty,
                    getBigDecimalPercent(divThenMul100Format1RoundHalfUp((Double) dataMap.get("standardTime"), (Double) dataMap.get("serviceTime"))),
                    getBigDecimalPercent(divThenMul100Format1RoundHalfUp(qty, planQty)));

            psData2.addChartData(workCenterExtDb.getWorkCenterCode(),
                    getRealWorkQty(shiftProdCenterPmList, workCenterExtDb),
                    getNonWorkingTime(shiftProdCenterRecordList, workCenterExtDb, curTime));

        }

        psData1.obj(getStandardRateCfg(organizeCode));
        psData2.obj(new StringJoiner(MesExtConstWords.COMMA).add(String.valueOf(planQtyAmount.intValue())).add(String.valueOf(qtyAmount.intValue())).toString());

        return packOntologyLineData(dataMap, psData1, psData2);

    }

    private String getStandardRateCfg(String organizeCode) {
        String busiConfig4Cached = (String) execCachedCenterWorkingBoardData(organizeCode, MesExtConstWords.ZERO_STR, MesExtConstWords.SX_STANDARD_RATE_CFG, null);
        MesBusiConfig busiConfig = !StringUtils.isEmpty(busiConfig4Cached) ? JSONObject.parseObject(busiConfig4Cached, MesBusiConfig.class) : execStandardRateCfg(organizeCode);
        return null == busiConfig ? getBigDecimalPercent(format1RounHalfUp(new Double(0))) : busiConfig.getCfgValue();
    }

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

    private Double getRealWorkQty(List<MesShiftProdCenterPm> shiftProdCenterPmList, MesWorkCenterExt workCenterExtDb) {
        Optional<MesShiftProdCenterPm> optional = CollectionUtils.isEmpty(shiftProdCenterPmList) ? null :
                shiftProdCenterPmList.stream().filter(o -> (null != o && o.getWorkCenterCode().equals(workCenterExtDb.getWorkCenterCode()) && o.getWorkTime().equals(workCenterExtDb.getWorkTime()) && o.getShiftCode().equals(workCenterExtDb.getShiftCode()))).findFirst();
        return (null == optional || !optional.isPresent()) ? new Double(0) : optional.get().getWorkerQty();
    }

    private Object getNonWorkingTime(List<MesShiftProdCenterRecord> shiftProdCenterRecordList, MesWorkCenterExt workCenterExtDb, String curTime) {
        List<MesShiftProdCenterRecord> stopList = CollectionUtils.isEmpty(shiftProdCenterRecordList) ? null :
                shiftProdCenterRecordList.stream().filter(o -> (null != o && MesExtEnumUtil.SHIFT_PROD_TYPE.UNNORMAL_STOP_CENTER.getValue() == o.getProdType() &&
                        o.getWorkCenterCode().equals(workCenterExtDb.getWorkCenterCode()) && o.getWorkTime().equals(workCenterExtDb.getWorkTime()) && o.getShiftCode().equals(workCenterExtDb.getWorkTime()) && o.getStartTime().compareTo(curTime) <= 0)).collect(Collectors.toList());
        return CollectionUtils.isEmpty(stopList) ? new Double(0) : stopList.stream().filter(o -> null != o).mapToDouble(o -> getStatisticsTime(o, curTime)).sum();
    }

    private Map<String, Object> packOntologyLineData(Map<String, Object> dataMap, JxCenterWorkingBoardBusiModel psData1, JxCenterWorkingBoardBusiModel psData2) {
        dataMap.put("本体能率", psData1);
        dataMap.put("项目", psData2);
        return dataMap;
    }

}
