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.MesProdDataToStatisticsShiftProd;
import cn.estsh.i3plus.ext.mes.pojo.bean.MesShiftProdCenterRecord;
import cn.estsh.i3plus.ext.mes.pojo.model.bu3.SxProdDataToAutoStatisticsModel;
import cn.estsh.i3plus.ext.mes.pojo.repository.MesProdDataToStatisticsShiftProdRepository;
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 SxProdDataToMonthlyStatisticsShiftProdByDayService implements ISxProdDataToMonthlyStatisticsDispatchService {

    @Autowired
    private SxProdDataToMonthlyStatisticsShiftProdService dispatchService;

    @Autowired
    private MesProdDataToStatisticsShiftProdRepository prodDataToStatisticsShiftProdRepository;

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

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

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

    @Override
    public SxProdDataToAutoStatisticsModel query(SxProdDataToAutoStatisticsModel data) {

        List<MesShiftProdCenterRecord> shiftProdCenterRecordList = dispatchService.queryShiftProdCenterRecordList(data);

        shiftProdCenterRecordList = removeUnValidData(shiftProdCenterRecordList);

        Map<String, List<MesShiftProdCenterRecord>> dataMap = getDataMap(shiftProdCenterRecordList);

        return CollectionUtils.isEmpty(shiftProdCenterRecordList) ? data.sourceCount(0).targetCount(0) :
                data.sourceCount(shiftProdCenterRecordList.size()).targetCount(dataMap.size()).data(dataMap);

    }

    @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, List<MesShiftProdCenterRecord>> dataMap = (Map<String, List<MesShiftProdCenterRecord>>) data.getData();

        saveStatisticsData(data, dataMap);

        return data;
    }

    private List<MesShiftProdCenterRecord> removeUnValidData(List<MesShiftProdCenterRecord> shiftProdCenterRecordList) {
        return CollectionUtils.isEmpty(shiftProdCenterRecordList) ? null :
                shiftProdCenterRecordList.stream().filter(o -> (null != o &&
                        !StringUtils.isEmpty(o.getWorkCenterCode()) &&
                        !StringUtils.isEmpty(o.getShiftCode()) &&
                        !StringUtils.isEmpty(o.getProdCode()) &&
                        !StringUtils.isEmpty(o.getProdType()) &&
                        !StringUtils.isEmpty(o.getWorkerQty()) &&
                        !StringUtils.isEmpty(o.getStartTime()) &&
                        !StringUtils.isEmpty(o.getEndTime()) &&
                        !StringUtils.isEmpty(o.getCategoryCode()) &&
                        !StringUtils.isEmpty(o.getCareerCode()))).collect(Collectors.toList());
    }

    private Map<String, List<MesShiftProdCenterRecord>> getDataMap(List<MesShiftProdCenterRecord> shiftProdCenterRecordList) {
        return CollectionUtils.isEmpty(shiftProdCenterRecordList) ? null :
                shiftProdCenterRecordList.stream().filter(o -> null != o).collect(Collectors.groupingBy(o -> new StringJoiner(MesExtConstWords.AND)
                        .add(o.getWorkTime()).add(o.getWorkCenterCode()).add(o.getShiftCode()).add(o.getProdCode()).add(o.getProdType().toString()).add(o.getCategoryCode()).add(o.getCareerCode()).toString()));
    }

    private void saveStatisticsData(SxProdDataToAutoStatisticsModel data, Map<String, List<MesShiftProdCenterRecord>> dataMap) {
        for (Map.Entry<String, List<MesShiftProdCenterRecord>> entry : dataMap.entrySet()) {
            List<MesShiftProdCenterRecord> itemList = entry.getValue();
            MesProdDataToStatisticsShiftProd statistics = dispatchService.packItemData(data, itemList);
            statistics.setWorkTime(itemList.get(0).getWorkTime());
            prodDataToStatisticsShiftProdRepository.insert(statistics);
        }
    }

}
