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

import cn.estsh.i3plus.ext.mes.api.busi.bu3.ISxProdDataToSoftAdapterStrategyService;
import cn.estsh.i3plus.ext.mes.apiservice.dao.bu3.ISxIotOutPutStatisticsDao;
import cn.estsh.i3plus.ext.mes.pojo.model.bu3.SxOrgCfgModel;
import cn.estsh.i3plus.ext.mes.pojo.model.bu3.SxProdDataBzzgsModel;
import cn.estsh.i3plus.ext.mes.pojo.model.bu3.SxProdDataToSoftAdapterCfgModel;
import cn.estsh.i3plus.ext.mes.pojo.model.bu3.SxProdDataToSoftAdapterDataModel;
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.impp.framework.boot.util.SpringContextsUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 标准总工数
 * 各产品实绩数量*产品标准工时
 */
@Slf4j
public class SxProdDataToSoftAdapterStrategyBzzgsService implements ISxProdDataToSoftAdapterStrategyService {

    private ISxProdDataToSoftAdapterStrategyService strategyService;

    private SxProdDataToSoftAdapterCfgModel cfgModel;

    public SxProdDataToSoftAdapterStrategyBzzgsService(ISxProdDataToSoftAdapterStrategyService strategyService, SxProdDataToSoftAdapterCfgModel cfgModel) {
        this.strategyService = strategyService;
        this.cfgModel = cfgModel;
    }

    @Override
    public SxProdDataToSoftAdapterCfgModel getCfgModel() {
        return cfgModel;
    }

    @Override
    public ISxProdDataToSoftAdapterStrategyService getStrategyService() {
        return strategyService;
    }

    @Override
    public SxProdDataToSoftAdapterDataModel query(SxProdDataToSoftAdapterDataModel data) {

        List<SxProdDataBzzgsModel> resultList = getResultList(data);

        if (CollectionUtils.isEmpty(resultList)) return data;

        SxOrgCfgModel org = getOrganizeName(data.getOrganizeCode());

        Map<String, String> centerExtMap = getCenterExtMap(data.getOrganizeCode());

        Map<String, String> shiftMap = getShiftMap(data.getOrganizeCode());

        resultList = packResultList(resultList, org, centerExtMap, shiftMap);

        return data.obj(resultList);
    }

    @Override
    public Object exec(SxProdDataToSoftAdapterDataModel data) {

        Map<String, List<SxProdDataBzzgsModel>> dataMap = getDataMap(data);

        return getBzzgsResultList(dataMap);

    }

    @Override
    public SxOrgCfgModel getOrganizeName(String organizeCode) { return strategyService.getOrganizeName(organizeCode); }

    @Override
    public Map<String, String> getCenterExtMap(String organizeCode) { return strategyService.getCenterExtMap(organizeCode); }

    @Override
    public Map<String, String> getShiftMap(String organizeCode) { return strategyService.getShiftMap(organizeCode); }

    private List<SxProdDataBzzgsModel> getResultList(SxProdDataToSoftAdapterDataModel data) {
        ISxIotOutPutStatisticsDao outPutStatisticsDao = (ISxIotOutPutStatisticsDao) SpringContextsUtil.getBean("sxIotOutPutStatisticsDao");
        return outPutStatisticsDao.queryIotOutPutStatisticsList(
                new SxProdDataBzzgsModel(data.getOrganizeCode(), MesExtEnumUtil.WORK_ORDER_TYPE.STANDARD_ORDER.getValue(),
                        data.getDate() + MesExtConstWords.APPEND_ZERO_HMS, data.getDate() + MesExtConstWords.APPEND_24_HMS));
    }

    private List<SxProdDataBzzgsModel> packResultList(List<SxProdDataBzzgsModel> resultList, SxOrgCfgModel org, Map<String, String> centerExtMap, Map<String, String> shiftMap) {
        for (SxProdDataBzzgsModel result : resultList) {
            if (null == result) continue;
            result.org(org.getOrg()).orgName(org.getOrgName());
            String[] centerArr = centerExtMap.get(result.getWorkCenterCode()).split(MesExtConstWords.AND);
            if (null != centerArr && centerArr.length >= 1) result.setWorkCenterName(centerArr[0]);
            if (null != centerArr && centerArr.length >= 2) result.setIsDont(centerArr[1]);
            if (null != centerArr && centerArr.length >= 3) result.setDontClass(centerArr[2]);
            result.setShiftName((StringUtils.isEmpty(result.getShiftCode()) || StringUtils.isEmpty(result.getWorkCenterCode())) ? null :
                    shiftMap.get(new StringJoiner(MesExtConstWords.AND).add(result.getWorkCenterCode()).add(result.getShiftCode()).toString()));
        }
        return resultList;
    }

    private Map<String, List<SxProdDataBzzgsModel>> getDataMap(SxProdDataToSoftAdapterDataModel data) {
        List<SxProdDataBzzgsModel> resultList = (List<SxProdDataBzzgsModel>) data.getObj();
        return resultList.stream().filter(o -> null != o).collect(Collectors.groupingBy(o -> new StringJoiner(MesExtConstWords.AND).add(o.getWorkTime()).add(o.getShiftCode()).add(o.getWorkCenterCode()).toString()));
    }

    private List<SxProdDataBzzgsModel> getBzzgsResultList(Map<String, List<SxProdDataBzzgsModel>> dataMap) {

        List<SxProdDataBzzgsModel> resultList = null;

        for(Map.Entry<String, List<SxProdDataBzzgsModel>> entry : dataMap.entrySet()) {
            if (null == entry) continue;

            List<SxProdDataBzzgsModel> itemList = entry.getValue();

            SxProdDataBzzgsModel result = new SxProdDataBzzgsModel(itemList.get(0));

            Double statistics = itemList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getQty()) && !StringUtils.isEmpty(o.getStandardWork())))
                    .mapToDouble(o -> MathOperation.mul(MathOperation.sub(o.getQty(), StringUtils.isEmpty(o.getRemakeQty()) ? new Double(0) : o.getRemakeQty()), o.getStandardWork())).sum();
            result.setStatistics(formatPoint(statistics, null));

            if (CollectionUtils.isEmpty(resultList)) resultList = new ArrayList<>();
            resultList.add(result);

        }

        resultList = CollectionUtils.isEmpty(resultList) ? null :
                resultList.stream().sorted(Comparator.comparing(SxProdDataBzzgsModel::getWorkTime)
                        .thenComparing(SxProdDataBzzgsModel::getShiftCode)
                        .thenComparing(SxProdDataBzzgsModel::getWorkCenterCode)).collect(Collectors.toList());

        return resultList;
    }
}
