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

import cn.estsh.i3plus.ext.mes.api.base.jx.IJxTimeSegmentStatisticsService;
import cn.estsh.i3plus.ext.mes.api.busi.jx.IJxCenterWorkingBoardService;
import cn.estsh.i3plus.ext.mes.pojo.bean.MesOutPutStatistics;
import cn.estsh.i3plus.ext.mes.pojo.bean.MesOutPutStatisticsTimeSegment;
import cn.estsh.i3plus.ext.mes.pojo.bean.MesTimeSegmentStatistics;
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.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.text.ParseException;
import java.util.*;
import java.util.stream.Collectors;

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

    private IJxCenterWorkingBoardService proxyService0;

    private IJxCenterWorkingBoardService proxyService;

    private IJxTimeSegmentStatisticsService timeSegmentStatisticsService;

    public JxCenterWorkingBoardCenterThreeService(IJxCenterWorkingBoardService proxyService0, IJxCenterWorkingBoardService proxyService) {
        this.proxyService0 = proxyService0;
        this.proxyService = proxyService;
        this.timeSegmentStatisticsService = (IJxTimeSegmentStatisticsService) SpringContextsUtil.getBean("jxTimeSegmentStatisticsService");
    }

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

        dataMap = proxyService0.queryCenterWorkingBoardData(dataMap);

        MesWorkCenterExt workCenterExtDb = (MesWorkCenterExt) dataMap.get(MesWorkCenterExt.class.getSimpleName());

        packProxyCondition(dataMap, workCenterExtDb);

        dataMap = proxyService.queryCenterWorkingBoardData(dataMap);

        List<MesWorkOrder> workOrderList = (List<MesWorkOrder>) dataMap.get(MesWorkOrder.class.getSimpleName());

        List<MesOutPutStatistics> outPutStatisticsList = (List<MesOutPutStatistics>) dataMap.get(MesOutPutStatistics.class.getSimpleName());

        List<MesOutPutStatisticsTimeSegment> outPutStatisticsTimeSegmentList = (List<MesOutPutStatisticsTimeSegment>) dataMap.get(MesOutPutStatisticsTimeSegment.class.getSimpleName());

        Optional<MesWorkOrder> curWorkOrder = getFirstWorkOrder(workOrderList, outPutStatisticsList, workCenterExtDb);

        List<MesOutPutStatistics> curOutPutStatisticsList = getFirstOutPutStatisticsList(outPutStatisticsList, curWorkOrder);

        dataMap.put("当前生产机种名", getCurProdPartNo(curOutPutStatisticsList, curWorkOrder));

        dataMap.put("当前计划台数", getQtyStr(getCurPlanQty(curOutPutStatisticsList, curWorkOrder, workCenterExtDb, dataMap)));

        dataMap.put("当前实绩台数", getQtyStr(dataMap.containsKey(MesExtConstWords.COMPLET_QTY) ? (Double) dataMap.get(MesExtConstWords.COMPLET_QTY) : getOutPutStatisticsList2AmountQty(curOutPutStatisticsList)));

        dataMap.put("小时产量", getTimeSegmentStatistics(outPutStatisticsTimeSegmentList, workCenterExtDb));

        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(MesExtConstWords.COMPLET_QTY);
        dataMap.remove(MesExtConstWords.START_TIME);
        dataMap.remove(MesExtConstWords.END_TIME);
        dataMap.remove(MesExtConstWords.WORK_TIME);
        dataMap.remove(MesExtConstWords.SHIFT_CODE);
        dataMap.remove(MesExtConstWords.WORK_CENTER_CODE);
        return dataMap;
    }

    private void packProxyCondition(Map<String, Object> dataMap, MesWorkCenterExt workCenterExtDb) {
        if (StringUtils.isEmpty(workCenterExtDb.getWorkTime()) || StringUtils.isEmpty(workCenterExtDb.getShiftCode())) return;
        dataMap.put(MesExtConstWords.START_TIME, TimeTool.timeCalc(TimeTool.stringParseToDate(workCenterExtDb.getWorkTime(), MesExtConstWords.DATE_FORMAT), Calendar.DATE, -1, MesExtConstWords.DATE_FORMAT));
        dataMap.put(MesExtConstWords.END_TIME, workCenterExtDb.getWorkTime());
        dataMap.put(MesExtConstWords.WORK_TIME, workCenterExtDb.getWorkTime());
        dataMap.put(MesExtConstWords.SHIFT_CODE, workCenterExtDb.getShiftCode());
        dataMap.put(MesExtConstWords.WORK_CENTER_CODE, workCenterExtDb.getWorkCenterCode());
    }

    private Optional<MesWorkOrder> getFirstWorkOrder(List<MesWorkOrder> workOrderList, List<MesOutPutStatistics> outPutStatisticsList, MesWorkCenterExt workCenterExtDb) {

        if (!CollectionUtils.isEmpty(outPutStatisticsList)) return CollectionUtils.isEmpty(workOrderList) ? null : workOrderList.stream().filter(o -> (null != o && o.getOrderNo().equals(outPutStatisticsList.get(0).getWorkOrderNo()))).findFirst();

        List<MesWorkOrder> workOrderList2Sort = getWorkOrderList2Sort(workOrderList, outPutStatisticsList, workCenterExtDb);

        return CollectionUtils.isEmpty(workOrderList2Sort) ? null : Optional.of(workOrderList2Sort.get(0));

    }

    private List<MesOutPutStatistics> getFirstOutPutStatisticsList(List<MesOutPutStatistics> outPutStatisticsList, Optional<MesWorkOrder> curWorkOrder) {
        String curWorkOrderNo = (null != curWorkOrder && curWorkOrder.isPresent()) ? curWorkOrder.get().getOrderNo() : (!CollectionUtils.isEmpty(outPutStatisticsList) ? outPutStatisticsList.get(0).getWorkOrderNo() : null);
        return (StringUtils.isEmpty(curWorkOrderNo) || CollectionUtils.isEmpty(outPutStatisticsList)) ? null : outPutStatisticsList.stream().filter(o -> (null != o && o.getWorkOrderNo().equals(curWorkOrderNo))).collect(Collectors.toList());
    }

    private Object getCurProdPartNo(List<MesOutPutStatistics> curOutPutStatisticsList, Optional<MesWorkOrder> curWorkOrder) {
        return !CollectionUtils.isEmpty(curOutPutStatisticsList) ? curOutPutStatisticsList.get(0).getPartNo() : ((null != curWorkOrder && curWorkOrder.isPresent()) ? curWorkOrder.get().getPartNo() : MesExtConstWords.EMPTY);
    }

    private Double getCurPlanQty(List<MesOutPutStatistics> curOutPutStatisticsList, Optional<MesWorkOrder> curWorkOrder, MesWorkCenterExt workCenterExtDb, Map<String, Object> dataMap) {
        return (null == curWorkOrder || !curWorkOrder.isPresent()) ? MesExtConstWords.ZERO :
                (curWorkOrder.get().getStartTime().contains(workCenterExtDb.getWorkTime()) ? curWorkOrder.get().getQty() :
                        MathOperation.add(MathOperation.sub(curWorkOrder.get().getQty(), curWorkOrder.get().getCompleteQty()), amountOutPutStatisticsQty(curOutPutStatisticsList, dataMap)));
    }

    private Double amountOutPutStatisticsQty(List<MesOutPutStatistics> outPutStatisticsList, Map<String, Object> dataMap) {
        Double qty = getOutPutStatisticsList2AmountQty(outPutStatisticsList);
        dataMap.put(MesExtConstWords.COMPLET_QTY, qty);
        return qty;
    }

    private Object getTimeSegmentStatistics(List<MesOutPutStatisticsTimeSegment> outPutStatisticsTimeSegmentList, MesWorkCenterExt workCenterExtDb) {

        JxCenterWorkingBoardBusiModel psData = new JxCenterWorkingBoardBusiModel().title("小时产量");

        if (StringUtils.isEmpty(workCenterExtDb.getWorkTime()) || StringUtils.isEmpty(workCenterExtDb.getShiftCode())) return psData;

        String item = new StringJoiner(MesExtConstWords.AND).add("TIME_SEGMENT").add(workCenterExtDb.getWorkCenterCode()).add(workCenterExtDb.getShiftCode()).toString();
        String timeSegmentStatisticsList4Cached = (String) execCachedCenterWorkingBoardData(workCenterExtDb.getOrganizeCode(), MesExtConstWords.ZERO_STR, item, null);
        List<MesTimeSegmentStatistics> timeSegmentStatisticsList = !StringUtils.isEmpty(timeSegmentStatisticsList4Cached) ? JSONObject.parseArray(timeSegmentStatisticsList4Cached, MesTimeSegmentStatistics.class) : execTimeSegmentStatistics(workCenterExtDb, item);
        timeSegmentStatisticsList = CollectionUtils.isEmpty(timeSegmentStatisticsList) ? null :
                timeSegmentStatisticsList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getStartTime()) && !StringUtils.isEmpty(o.getEndTime()))).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(timeSegmentStatisticsList)) return psData;

        timeSegmentStatisticsList = timeSegmentStatisticsList.stream().filter(o -> null != o).sorted(Comparator.comparing(MesTimeSegmentStatistics::getStartTime)).collect(Collectors.toList());

        Map<String, List<MesOutPutStatisticsTimeSegment>> statisticsMap = CollectionUtils.isEmpty(outPutStatisticsTimeSegmentList) ? null :
                outPutStatisticsTimeSegmentList.stream().filter(o -> null != o).collect(Collectors.groupingBy(MesOutPutStatisticsTimeSegment::getTimeSegmentCode));

        for (MesTimeSegmentStatistics timeSegmentStatistics : timeSegmentStatisticsList) {
            if (null == timeSegmentStatistics) continue;

            List<MesOutPutStatisticsTimeSegment> statisticsList = CollectionUtils.isEmpty(statisticsMap) ? null : statisticsMap.get(timeSegmentStatistics.getTimeSegmentCode());
            psData.addChartData(timeSegmentStatistics.getStartTime().substring(0, 5), getAmountPlanQty(timeSegmentStatistics, workCenterExtDb), getOutPutStatisticsTimeSegmentList2AmountQty(statisticsList));
        }

        return psData;

    }

    private List<MesTimeSegmentStatistics> execTimeSegmentStatistics(MesWorkCenterExt workCenterExtDb, String item) {
        List<MesTimeSegmentStatistics> timeSegmentStatisticsList = timeSegmentStatisticsService.getTimeSegmentStatisticsList(workCenterExtDb.getOrganizeCode(), workCenterExtDb.getWorkCenterCode(), workCenterExtDb.getShiftCode());
        if (!CollectionUtils.isEmpty(timeSegmentStatisticsList)) execCachedCenterWorkingBoardData(workCenterExtDb.getOrganizeCode(), CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValueStr(), item, JSONObject.toJSONString(timeSegmentStatisticsList));
        return timeSegmentStatisticsList;
    }

    private Double getAmountPlanQty(MesTimeSegmentStatistics timeSegmentStatistics, MesWorkCenterExt workCenterExtDb) {
        try {
            if (StringUtils.isEmpty(workCenterExtDb.getWorkTakt()) || MathOperation.compareTo(workCenterExtDb.getWorkTakt(), new Double(0)) == 0) return new Double(0);
            return MathOperation.mul(new Double(TimeTool.getSecoundsBetweenTime(1, appendWorkTime(timeSegmentStatistics.getStartTime(), workCenterExtDb.getWorkTime()), appendWorkTime(timeSegmentStatistics.getEndTime(), workCenterExtDb.getWorkTime()))), workCenterExtDb.getWorkTakt());
        } catch (ParseException e) {
            return new Double(0);
        }
    }

    private String appendWorkTime(String hms, String workTime) {
        return new StringJoiner(MesExtConstWords.ONE_SPACE).add(workTime).add(hms).toString();
    }

    public Double getOutPutStatisticsTimeSegmentList2AmountQty(List<MesOutPutStatisticsTimeSegment> outPutStatisticsTimeSegmentList) {
        return CollectionUtils.isEmpty(outPutStatisticsTimeSegmentList) ? new Double(0) : outPutStatisticsTimeSegmentList.stream().filter(o -> null != o).mapToDouble(MesOutPutStatisticsTimeSegment::getQty).sum();
    }

}
