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.base.IShiftExtService;
import cn.estsh.i3plus.ext.mes.api.base.IShiftProdService;
import cn.estsh.i3plus.ext.mes.api.busi.bu3.ISxProdDataToSoftAdapterCfgService;
import cn.estsh.i3plus.ext.mes.api.busi.bu3.ISxProdDataToSoftAdapterStrategyService;
import cn.estsh.i3plus.ext.mes.pojo.bean.MesShiftProd;
import cn.estsh.i3plus.ext.mes.pojo.bean.MesWorkCenterExt;
import cn.estsh.i3plus.ext.mes.pojo.model.bu3.SxOrgCfgModel;
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.mes.api.iservice.base.IConfigService;
import cn.estsh.i3plus.platform.common.tool.MathOperation;
import cn.estsh.i3plus.platform.common.tool.ReflectTool;
import cn.estsh.i3plus.platform.common.tool.TimeTool;
import cn.estsh.i3plus.pojo.base.bean.BaseResultBean;
import cn.estsh.i3plus.pojo.mes.bean.MesConfig;
import cn.estsh.i3plus.pojo.mes.bean.MesShift;
import cn.estsh.i3plus.pojo.mes.bean.MesWorkCenter;
import cn.estsh.i3plus.pojo.model.softswitch.SuitModel;
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.text.ParseException;
import java.util.*;

@Slf4j
public class SxProdDataToSoftAdapterStrategyCommonService implements ISxProdDataToSoftAdapterStrategyService {

    public SxProdDataToSoftAdapterStrategyCommonService() {}

    @Override
    public SxOrgCfgModel getOrganizeName(String organizeCode) {
        SxOrgCfgModel org = new SxOrgCfgModel(organizeCode);
        IConfigService configService = (IConfigService) SpringContextsUtil.getBean("configService");
        MesConfig configDb = configService.getConfigByCfgCode(MesExtConstWords.IOT_ORG_CFG, organizeCode);
        if (null == configDb) return org;
        return org.org(configDb.getCfgKey()).orgName(configDb.getCfgValue());
    }

    @Override
    public Map<String, String> getCenterMap(String organizeCode) {
        Map<String, String> centerMap = new HashMap<>();
        IProdOrgExtService prodOrgExtService = (IProdOrgExtService) SpringContextsUtil.getBean("prodOrgExtService");
        List<MesWorkCenter> workCenterDbList = prodOrgExtService.queryWorkCenterList(organizeCode);
        if (CollectionUtils.isEmpty(workCenterDbList)) return centerMap;
        for (MesWorkCenter workCenterDb : workCenterDbList) {
            if (null == workCenterDb || (StringUtils.isEmpty(workCenterDb.getWorkCenterCode()) || StringUtils.isEmpty(workCenterDb.getWorkCenterName()))) continue;
            centerMap.put(workCenterDb.getWorkCenterCode(), workCenterDb.getWorkCenterName());
        }
        return centerMap;
    }

    @Override
    public Map<String, String> getCenterExtMap(String organizeCode) {
        Map<String, String> centerMap = new HashMap<>();
        IProdOrgExtService prodOrgExtService = (IProdOrgExtService) SpringContextsUtil.getBean("prodOrgExtService");
        List<MesWorkCenterExt> workCenterExtDbList = prodOrgExtService.queryWorkCenterExtList(organizeCode);
        if (CollectionUtils.isEmpty(workCenterExtDbList)) return centerMap;
        for (MesWorkCenterExt workCenterDb : workCenterExtDbList) {
            if (null == workCenterDb || (StringUtils.isEmpty(workCenterDb.getWorkCenterCode()) || StringUtils.isEmpty(workCenterDb.getWorkCenterName()))) continue;
            centerMap.put(workCenterDb.getWorkCenterCode(), new StringJoiner(MesExtConstWords.AND)
                    .add(StringUtils.isEmpty(workCenterDb.getWorkCenterName()) ? MesExtConstWords.EMPTY : workCenterDb.getWorkCenterName())
                    .add(StringUtils.isEmpty(workCenterDb.getIsDont()) ? MesExtConstWords.EMPTY : workCenterDb.getIsDont())
                    .add(StringUtils.isEmpty(workCenterDb.getDontClass()) ? MesExtConstWords.EMPTY : workCenterDb.getDontClass()).toString());
        }
        return centerMap;
    }

    @Override
    public Map<String, String> getShiftProdMap(String organizeCode) {
        Map<String, String> shiftProdMap = new HashMap<>();
        IShiftProdService shiftProdService = (IShiftProdService) SpringContextsUtil.getBean("shiftProdService");
        List<MesShiftProd> shiftProdDbList = shiftProdService.getShiftProdList(organizeCode);
        if (CollectionUtils.isEmpty(shiftProdDbList)) return shiftProdMap;
        for (MesShiftProd shiftProdDb : shiftProdDbList) {
            if (null == shiftProdDb || (StringUtils.isEmpty(shiftProdDb.getProdCode()) || StringUtils.isEmpty(shiftProdDb.getProdName()))) continue;
            shiftProdMap.put(shiftProdDb.getProdCode(), shiftProdDb.getProdName());
        }
        return shiftProdMap;
    }

    @Override
    public Map<String, String> getShiftMap(String organizeCode) {
        Map<String, String> shiftMap = new HashMap<>();
        IShiftExtService shiftExtService = (IShiftExtService) SpringContextsUtil.getBean("shiftExtService");
        List<MesShift> shiftDbList = shiftExtService.queryShiftList(organizeCode);
        if (CollectionUtils.isEmpty(shiftDbList)) return shiftMap;
        for (MesShift shiftDb : shiftDbList) {
            if (null == shiftDb || (StringUtils.isEmpty(shiftDb.getWorkCenterCode()) || StringUtils.isEmpty(shiftDb.getShiftCode()) || StringUtils.isEmpty(shiftDb.getShiftName()))) continue;
            shiftMap.put(new StringJoiner(MesExtConstWords.AND).add(shiftDb.getWorkCenterCode()).add(shiftDb.getShiftCode()).toString(), shiftDb.getShiftName());
        }
        return shiftMap;
    }

    @Override
    public Double getBetweenMin(String startTime, String endTime, int scale) {
        if (StringUtils.isEmpty(startTime) || StringUtils.isEmpty(endTime)) return new Double(0);
        Integer seconds;
        try {
            seconds = TimeTool.getSecoundsBetweenTime(1, startTime, endTime);
        } catch (ParseException e) {
            return new Double(0);
        }
        if (seconds.compareTo(0) < 0) return new Double(0);
        return MathOperation.div(new Double(seconds), new Double(60), scale);
    }

    @Override
    public SxProdDataToSoftAdapterDataModel doInvokeSuit(SxProdDataToSoftAdapterDataModel data, Object obj, SxProdDataToSoftAdapterCfgModel cfgModel) {

        List<SuitModel> suitList = instanceSuitList(data, obj, cfgModel);

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

        ISxProdDataToSoftAdapterCfgService bsSuitServiceCloud = (ISxProdDataToSoftAdapterCfgService) SpringContextsUtil.getBean("sxProdDataToSoftAdapterCfgService");

        for (SuitModel suit : suitList) {
            if (null == suit) continue;
            BaseResultBean resultBean = bsSuitServiceCloud.executeBsSuitCaseByCloud(data, cfgModel, suit);
            if (null == resultBean || !resultBean.isSuccess())
                log.info("MES工厂{}DATE{}执行生产数据回传软适配JOB --- EXEC STRATEGY_CLASS[{}] --- EXEC_CLASS[{}] --- EXEC ERROR:doInvokeSuit[{}] --- THREAD:[{}]",
                        data.getOrganizeCode(), data.getDate(), data.getClassName(), cfgModel.getClassName(), null == resultBean ? null : resultBean.getErrorMsg(), data.getCurrentThreadName());

        }

        return data;

    }

    //连续空数据,空数据个数+1个\t, 当前逻辑不支持末位字段为空
    @Override
    public List<SuitModel> instanceSuitList(SxProdDataToSoftAdapterDataModel data, Object obj, SxProdDataToSoftAdapterCfgModel cfgModel) {
        if (null == obj || null == cfgModel) return null;

        List<SuitModel> suitList = null;

        try {
            List resultList = (List) obj;

            String[] fieldArr = cfgModel.getFieldContent().split(MesExtConstWords.COMMA);

            String suitSid = getSuitSid(cfgModel.getSuitSid(), resultList.get(0), data.getDate());

            Integer splitCount = StringUtils.isEmpty(cfgModel.getSplitCount()) ? resultList.size() : Integer.valueOf(cfgModel.getSplitCount());

            Integer size = 0;
            Integer count = 0;
            StringJoiner rowSj = new StringJoiner("\n");
            for (Object result : resultList) {
                if (null == result) continue;

                if (count.compareTo(splitCount) == 0) {
                    count = 0;
                    rowSj = new StringJoiner("\n");
                }

                StringJoiner cellSj = new StringJoiner("\t");
                Integer num = 0;
                for (String field : fieldArr) {
                    if (StringUtils.isEmpty(field)) continue;
                    Object fieldValue = ReflectTool.getFieldValue(result, ReflectTool.getObjectField(result, field));
                    if (!StringUtils.isEmpty(fieldValue)) {
                        if (num.compareTo(0) == 0) cellSj.add(fieldValue.toString());
                        else {
                            StringBuilder sb = new StringBuilder();
                            for (int i = num; i > 0; i --) {
                                sb.append("\t");
                            }
                            sb.append(fieldValue.toString());
                            cellSj.add(sb.toString());
                            num = 0;
                        }
                    } else num ++;
                }

                if (!StringUtils.isEmpty(cellSj.toString())) rowSj.add(cellSj.toString());

                count ++;
                size ++;
                if (count.compareTo(splitCount) == 0 || size.compareTo(resultList.size()) == 0) {
                    if (StringUtils.isEmpty(rowSj.toString())) continue;

                    if (CollectionUtils.isEmpty(suitList)) suitList = new ArrayList<>();

                    SuitModel suit = new SuitModel();
                    suit.setSuitCaseCode(cfgModel.getSuitCaseCode());
                    suit.setSuitSid(splitCount.compareTo(resultList.size()) < 0 ? (suitSid + MesExtConstWords.E_UNDERLINE + (suitList.size() + 1)) : suitSid);
                    suit.setParamXml(rowSj.toString());
                    suitList.add(suit);
                }

            }
        } catch (Exception e) {
            log.info("MES工厂{}DATE{}执行生产数据回传软适配JOB --- EXEC STRATEGY_CLASS[{}] --- EXEC_CLASS[{}] --- EXEC ERROR:instanceSuitList[{}] --- THREAD:[{}]",
                    data.getOrganizeCode(), data.getDate(), data.getClassName(), cfgModel.getClassName(), e.getMessage(), data.getCurrentThreadName());
        }

        return suitList;
    }

    private String getSuitSid(String suitSidCfg, Object obj, String date) {
        String[] fieldList = new String[]{MesExtConstWords.ORG, MesExtConstWords.DATE_YMD, MesExtConstWords.TIME_HMS};
        for (String field : fieldList) {
            if (StringUtils.isEmpty(field) || !suitSidCfg.contains(field)) continue;
            suitSidCfg = suitSidCfg.replaceFirst(field, MesExtConstWords.PLACE_HOLDER);
            suitSidCfg = String.format(suitSidCfg, getFormatArgs(field, obj, date));
        }
        return suitSidCfg;
    }

    private Object getFormatArgs(String field, Object obj, String date) {
        switch (field) {
            case MesExtConstWords.ORG :
                return ReflectTool.getFieldValue(obj, ReflectTool.getObjectField(obj, MesExtConstWords.ORG));
            case MesExtConstWords.DATE_YMD :
                return date.replaceAll(MesExtConstWords.E_LINE, MesExtConstWords.EMPTY);
            case MesExtConstWords.TIME_HMS :
                return TimeTool.getTimeShort();
            default:
                break;
        }
        return null;
    }

    public static void main(String[] args) {
        StringJoiner sj = new StringJoiner("\t");
        sj.add("111");
        StringBuilder sb = new StringBuilder();
        for (int i = 4; i > 0; i --) {
            sb.append("\t");
        }
        sj.add(sb.append("222").toString());
        System.out.println(sj.toString());
        String[] sjArr = sj.toString().split("\t");
        System.out.println(sjArr.toString());
    }

}
