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

import cn.estsh.i3plus.ext.mes.api.base.IProdOrgExtService;
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.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 java.util.List;
import java.util.Map;
import java.util.StringJoiner;
import java.util.stream.Collectors;

@Slf4j
@Service
public class SxProdDataToMonthlyStatisticsOutPutByMonthService implements ISxProdDataToMonthlyStatisticsDispatchService {

    @Autowired
    private SxProdDataToMonthlyStatisticsOutPutService dispatchService;

    @Autowired
    private MesProdDataToStatisticsOutPutRepository prodDataToStatisticsOutPutRepository;

    @Autowired
    private IProdOrgExtService prodOrgExtService;

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

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

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

    @Override
    public SxProdDataToAutoStatisticsModel query(SxProdDataToAutoStatisticsModel data) {

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

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

        if (CollectionUtils.isEmpty(outPutStatisticsList)) return data.sourceCount(0).targetCount(0);

        Map<String, Double> partStandardWorkMap = dispatchService.queryPartExtStandardWorkMap(data.getOrganizeCode());

        Map<String, String> careerPersonnelCostMap = prodOrgExtService.getCareerPersonnelCostMap(data.getOrganizeCode());

        Map<String, Object> dataMap = dispatchService.getDataMap(outPutDataMap, partStandardWorkMap);
        if (!CollectionUtils.isEmpty(careerPersonnelCostMap)) dataMap.put("careerPersonnelCostMap", careerPersonnelCostMap);

        return data.sourceCount(outPutStatisticsList.size()).targetCount(outPutDataMap.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, Object> dataMap = (Map<String, Object>) data.getData();

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

        Map<String, Double> partStandardWorkMap = !dataMap.containsKey("partStandardWorkMap") ? null : (Map<String, Double>) dataMap.get("partStandardWorkMap");

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

        saveStatisticsData(data, outPutDataMap, partStandardWorkMap, careerPersonnelCostMap);

        return data;
    }

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

    private void saveStatisticsData(SxProdDataToAutoStatisticsModel data, Map<String, List<MesOutPutStatistics>> dataMap, Map<String, Double> partStandardWorkMap, Map<String, String> careerPersonnelCostMap) {
        for (Map.Entry<String, List<MesOutPutStatistics>> entry : dataMap.entrySet()) {
            List<MesOutPutStatistics> itemList = entry.getValue();
            MesProdDataToStatisticsOutPut statistics = dispatchService.packItemData(data, itemList, partStandardWorkMap);
            statistics.setWorkTime(data.getDate());
            statistics.setPersonnelCost((!CollectionUtils.isEmpty(careerPersonnelCostMap) && careerPersonnelCostMap.containsKey(statistics.getCareerCode())) ? careerPersonnelCostMap.get(statistics.getCareerCode()) : MesExtConstWords.ZERO_STR);
            prodDataToStatisticsOutPutRepository.insert(statistics);
        }
    }

}
