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

import cn.estsh.i3plus.ext.mes.api.busi.bu3.ISxProdDataToMonthlyStatisticsDispatchService;
import cn.estsh.i3plus.ext.mes.pojo.bean.MesOutPutStatistics;
import cn.estsh.i3plus.ext.mes.pojo.bean.MesProdDataToStatisticsOutPut;
import cn.estsh.i3plus.ext.mes.pojo.bean.MesWorkOrderExt;
import cn.estsh.i3plus.ext.mes.pojo.model.bu3.SxProdDataToAutoStatisticsModel;
import cn.estsh.i3plus.ext.mes.pojo.repository.MesProdDataToStatisticsOutPutRepository;
import cn.estsh.i3plus.ext.mes.pojo.util.MesExtConstWords;
import cn.estsh.i3plus.ext.mes.pojo.util.MesExtEnumUtil;
import cn.estsh.impp.framework.boot.exception.ImppBusiException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

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

@Slf4j
@Service
public class SxProdDataToMonthlyStatisticsOutPutFlagByDayService implements ISxProdDataToMonthlyStatisticsDispatchService {

    @Autowired
    private SxProdDataToMonthlyStatisticsOutPutService dispatchService;

    @Autowired
    private MesProdDataToStatisticsOutPutRepository prodDataToStatisticsOutPutRepository;

    @Override
    public String name() { return MesExtEnumUtil.JOB_STATISTICS_PROD_DATA_KEY.OUT_PUT_DAY_KEY2.name(); }

    @Override
    public String flag() { return MesExtEnumUtil.JOB_STATISTICS_PROD_DATA_KEY.OUT_PUT_DAY_KEY2.getFlag(); }

    @Override
    public SxProdDataToAutoStatisticsModel restock(SxProdDataToAutoStatisticsModel data) {
        return dispatchService.restock(data)
                .statisticsType(flag()).dataKey(MesExtEnumUtil.JOB_STATISTICS_PROD_DATA_KEY.OUT_PUT_DAY_KEY2.getValue());
    }

    @Override
    public SxProdDataToAutoStatisticsModel query(SxProdDataToAutoStatisticsModel data) {

        List<MesOutPutStatistics> outPutStatisticsList = dispatchService.queryOutPutStatisticsList(data);

        Map<String, List<MesOutPutStatistics>> outPutDataMap = getOutPutDataMap(outPutStatisticsList);

        List<MesWorkOrderExt> workOrderExtList = dispatchService.queryWorkOrderExtList(data);

        Map<String, List<MesWorkOrderExt>> orderDataMap = getOrderDataMap(workOrderExtList);

        List<String> keyList = dispatchService.getKeyList(outPutDataMap, orderDataMap);

        return data.sourceCount(CollectionUtils.isEmpty(outPutStatisticsList) ? 0 : outPutStatisticsList.size())
                .targetCount(CollectionUtils.isEmpty(keyList) ? 0 : keyList.size())
                .data(dispatchService.getDataMap(keyList, outPutDataMap, orderDataMap));

    }

    @Override
    @Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = {ImppBusiException.class, Exception.class})
    public SxProdDataToAutoStatisticsModel exec(SxProdDataToAutoStatisticsModel data) {

        dispatchService.doTravel(data);

        if (null == data.getData()) return data;

        Map<String, Object> dataMap = (Map<String, Object>) data.getData();

        List<String> keyList = (List<String>) dataMap.get("keyList");

        Map<String, List<MesOutPutStatistics>> outPutDataMap = !dataMap.containsKey("outPutDataMap") ? null : (Map<String, List<MesOutPutStatistics>>) dataMap.get("outPutDataMap");

        Map<String, List<MesWorkOrderExt>> orderDataMap = !dataMap.containsKey("orderDataMap") ? null : (Map<String, List<MesWorkOrderExt>>) dataMap.get("orderDataMap");

        saveStatisticsData(data, keyList, outPutDataMap, orderDataMap);

        return data;
    }

    private Map<String, List<MesOutPutStatistics>> getOutPutDataMap(List<MesOutPutStatistics> outPutStatisticsList) {
        return CollectionUtils.isEmpty(outPutStatisticsList) ? null :
                outPutStatisticsList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getCareerCode()) && !StringUtils.isEmpty(o.getCategoryCode()))).collect(Collectors.groupingBy(o ->
                        new StringJoiner(MesExtConstWords.AND).add(o.getWorkCenterCode()).add(o.getPartNo()).add(o.getWorkOrderType().toString()).add(o.getCategoryCode()).add(o.getCareerCode()).add(o.getWorkTime()).toString()));
    }

    private Map<String, List<MesWorkOrderExt>> getOrderDataMap(List<MesWorkOrderExt> workOrderExtList) {
        return CollectionUtils.isEmpty(workOrderExtList) ? null :
                workOrderExtList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getReserved1()) && !StringUtils.isEmpty(o.getReserved2()) &&
                        MesExtEnumUtil.WORK_ORDER_STATUS.CREATE.getValue() != o.getWorkOrderStatus() && MesExtEnumUtil.WORK_ORDER_STATUS.REMOVE.getValue() != o.getWorkOrderStatus())
                ).collect(Collectors.groupingBy(o -> new StringJoiner(MesExtConstWords.AND).add(o.getWorkCenterCode()).add(o.getPartNo()).add(o.getWorkOrderType().toString()).add(o.getReserved1()).add(o.getReserved2()).add(o.getStartTime().substring(0, 10)).toString()));
    }

    private void saveStatisticsData(SxProdDataToAutoStatisticsModel data, List<String> keyList,
                                    Map<String, List<MesOutPutStatistics>> outPutDataMap, Map<String, List<MesWorkOrderExt>> orderDataMap) {
        for (String key : keyList) {
            if (StringUtils.isEmpty(key)) continue;
            List<MesOutPutStatistics> outPutStatisticsList = CollectionUtils.isEmpty(outPutDataMap) ? null : outPutDataMap.get(key);
            List<MesWorkOrderExt> workOrderExtList = CollectionUtils.isEmpty(orderDataMap) ? null : orderDataMap.get(key);
            String[] keyArr = key.split(MesExtConstWords.AND);
            MesProdDataToStatisticsOutPut statistics = dispatchService.packItemData(data, keyArr, workOrderExtList, outPutStatisticsList);
            statistics.setWorkTime(keyArr[5]);
            prodDataToStatisticsOutPutRepository.insert(statistics);
        }
    }

}
