package cn.estsh.i3plus.ext.mes.apiservice.serviceimpl.base;

import cn.estsh.i3plus.ext.mes.api.base.IFileManageService;
import cn.estsh.i3plus.ext.mes.api.base.IPcnHttpRequestService;
import cn.estsh.i3plus.ext.mes.api.base.IWorkOrderExtService;
import cn.estsh.i3plus.ext.mes.icloud.sdk.IWmsBomTakeEffectCloud;
import cn.estsh.i3plus.ext.mes.icloud.sdk.IWmsPsPartQueryCloud;
import cn.estsh.i3plus.ext.mes.icloud.sdk.IWmsStockSnCloud;
import cn.estsh.i3plus.ext.mes.pojo.bean.MesPartExt;
import cn.estsh.i3plus.ext.mes.pojo.bean.MesProduceSnExt;
import cn.estsh.i3plus.ext.mes.pojo.model.WmsBomTotalModel;
import cn.estsh.i3plus.ext.mes.pojo.model.WmsPsCheckModel;
import cn.estsh.i3plus.ext.mes.pojo.model.WmsSnInfoModel;
import cn.estsh.i3plus.ext.mes.pojo.repository.MesPartExtRepository;
import cn.estsh.i3plus.ext.mes.pojo.repository.MesProduceSnExtRepository;
import cn.estsh.i3plus.ext.mes.pojo.util.MesExtConstWords;
import cn.estsh.i3plus.platform.common.exception.ImppExceptionEnum;
import cn.estsh.i3plus.platform.common.tool.JsonUtilTool;
import cn.estsh.i3plus.platform.common.tool.SerializeTool;
import cn.estsh.i3plus.pojo.base.bean.BaseResultBean;
import cn.estsh.i3plus.pojo.base.bean.DdlPackBean;
import cn.estsh.i3plus.pojo.base.bean.ListPager;
import cn.estsh.i3plus.pojo.base.common.Pager;
import cn.estsh.i3plus.pojo.base.common.PagerHelper;
import cn.estsh.i3plus.pojo.base.enumutil.CommonEnumUtil;
import cn.estsh.i3plus.pojo.base.tool.DdlPreparedPack;
import cn.estsh.i3plus.pojo.platform.bean.SysFile;
import cn.estsh.impp.framework.boot.exception.ImppExceptionBuilder;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.entity.ContentType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author wangjie
 * @version 1.0
 * @date 2021/1/13 9:28
 **/
@Slf4j
@Service
public class PcnHttpRequestService implements IPcnHttpRequestService {

    @Autowired
    private IWorkOrderExtService workOrderExtService;
    @Autowired
    private IFileManageService fileManageService;
    @Autowired
    private IWmsStockSnCloud wmsStockSnCloud;
    @Autowired
    private IWmsBomTakeEffectCloud wmsBomTakeEffectCloud;
    @Autowired
    private IWmsPsPartQueryCloud psPartQueryCloud;
    @Autowired
    private MesPartExtRepository partExtRepository;
    @Autowired
    private MesProduceSnExtRepository produceSnExtRepository;

    @Override
    public Double getWorkOrderExtMaxSeq(Map<String, Object> params) {
        String organizeCode = (String) params.get(MesExtConstWords.ORGANIZE_CODE);
        Integer count = (Integer) params.get(MesExtConstWords.COUNT);
        return workOrderExtService.getWorkOrderExtMaxSeq(organizeCode, count);
    }

    @Override
    public SysFile uploadFile(Map<String, Object> params) {
        byte[] buf = (byte[]) SerializeTool.deserialization((String) params.get(MesExtConstWords.FILE_BYTE));

        InputStream inputStream = new ByteArrayInputStream(buf);

        MultipartFile file;
        try {
            file = new MockMultipartFile(
                    (String) params.get(MesExtConstWords.FILE_NAME), (String) params.get(MesExtConstWords.ORIGINAL_FILE_NAME),
                    ContentType.APPLICATION_OCTET_STREAM.toString(), inputStream);
        } catch (IOException e) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                    .setErrorCode(ImppExceptionEnum.IO_EXCEPTION_FILE.getCode())
                    .setErrorDetail("文件字节转换成MultipartFile类型出错", e.getMessage())
                    .build();
        }

        return fileManageService.uploadFile(file);
    }

    @Override
    public WmsSnInfoModel getPartNoBySn(String sn, String organizeCode) {
        BaseResultBean baseResultBean = wmsStockSnCloud.getPartNoBySn(sn, organizeCode);
        WmsSnInfoModel wmsSnInfoModel = null;
        if (null != baseResultBean && baseResultBean.success) {
            LinkedHashMap resultObject = (LinkedHashMap) baseResultBean.getResultObject();
            wmsSnInfoModel = JsonUtilTool.decode(JSONObject.toJSONString(resultObject), WmsSnInfoModel.class);
        }
        return wmsSnInfoModel;
    }

    @Override
    public List<WmsBomTotalModel> getBomTotalByPartNo(String partNo, String organizeCode) {
        BaseResultBean baseResultBean = wmsBomTakeEffectCloud.getBomTotalByPartNo(partNo, organizeCode);
        log.info("BOM生效 MES调用WMS 查询结果：{}", baseResultBean.toString());
        List<WmsBomTotalModel> wmsBomTotalList = new ArrayList<>();
        if (null != baseResultBean && baseResultBean.success) {
            wmsBomTotalList = (List<WmsBomTotalModel>) baseResultBean.getResultList();
        } else {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_EXIT.getCode())
                    .setErrorDetail(baseResultBean.getErrorMsg())
                    .build();
        }
        return wmsBomTotalList;
    }

    @Override
    public BaseResultBean getEpBomTotalByPartNo(String partNo, String organizeCode) {
        BaseResultBean baseResultBean = wmsBomTakeEffectCloud.getBomTotalByPartNo(partNo, organizeCode);
        log.info("BOM生效 MES调用WMS 查询结果：{}", baseResultBean.toString());
        //List<WmsBomTotalModel> wmsBomTotalList = new ArrayList<>();
        //if (null != baseResultBean && baseResultBean.success) {
        //    wmsBomTotalList = (List<WmsBomTotalModel>) baseResultBean.getResultList();
        //}
        return baseResultBean;
    }

    /*@Override
    public void doEffect(String wmsBomTotalModelsJSONStr) {
        @SuppressWarnings("unchecked")
        List<WmsBomTotalModel> wmsBomTotalModels = (List<WmsBomTotalModel>) JSON.parse(wmsBomTotalModelsJSONStr);
        log.info("MES调用WMS Bom生效接口：参数{}", wmsBomTotalModels);
        BaseResultBean baseResultBean = wmsBomTakeEffectCloud.doEffect(wmsBomTotalModels);
        log.info("BOM生效 MES调用WMS 执行结果：{}", baseResultBean.toString());
    }*/

    @Override
    public void doEffect(String partNo, String organizeCode) {
        log.info("MES调用WMS Bom生效接口参数，物料：{}，工厂代码：{}", partNo, organizeCode);
        BaseResultBean baseResultBean = wmsBomTakeEffectCloud.doEffect(partNo, organizeCode);
        log.info("BOM生效 MES调用WMS 执行结果：{}", baseResultBean.toString());
    }

    /**
     * PS部件查询
     *
     * @return {@link List<Object>}
     */
    @Override
    public ListPager<WmsPsCheckModel> psPartQuery(WmsPsCheckModel wmsPsCheckModel) {
        BaseResultBean baseResultBean = psPartQueryCloud.queryPsPart(wmsPsCheckModel);
        Pager pager = new Pager();
        pager.setCurrentPage(wmsPsCheckModel.getCurrentPage());
        pager.setPageSize(wmsPsCheckModel.getPageSize());

        List<WmsPsCheckModel> resultList = new ArrayList<>();
        if (null != baseResultBean && baseResultBean.success) {
            List<Object> objectList = baseResultBean.getResultList();
            if (!CollectionUtils.isEmpty(objectList)) {
                for (Object object : objectList) {
                    if (null == object) {
                        continue;
                    }
                    WmsPsCheckModel psCheckModel = JSONObject.toJavaObject(JSONObject.parseObject(JSON.toJSONString(object)), WmsPsCheckModel.class);
                    psCheckModel.setOrderNo(psCheckModel.getWorkOrderNo());
                    psCheckModel.setItemPartNo(psCheckModel.getPartNo());
                    resultList.add(psCheckModel);
                }
            }
        }

        if (!CollectionUtils.isEmpty(resultList)) {
            log.info("PS部件绑定批次查询结果resultList:size[{}]", resultList.size());
            List<String> itemPartNoList = (resultList.stream()
                    .filter(o -> (null != o && !StringUtils.isEmpty(o.getItemPartNo()))).map(WmsPsCheckModel::getItemPartNo).collect(Collectors.toList()))
                    .stream().filter(o -> !StringUtils.isEmpty(o)).distinct().collect(Collectors.toList());
            if (!CollectionUtils.isEmpty(itemPartNoList)) {
                log.info("PS部件绑定批次查询结果itemPartNoList:size[{}]", itemPartNoList.size());
            }
            DdlPackBean packBean = DdlPackBean.getDdlPackBean(wmsPsCheckModel.getOrganizeCode());
            DdlPreparedPack.getInPackList(itemPartNoList, MesExtConstWords.PART_NO, packBean);
            List<MesPartExt> itemPartExtList = partExtRepository.findByHqlWhere(packBean);
            log.info("PS部件绑定批次查询结果itemPartExtList:size[{}]", CollectionUtils.isEmpty(itemPartExtList) ? 0 : itemPartExtList.size());
            itemPartExtList = CollectionUtils.isEmpty(itemPartExtList) ? null :
                    itemPartExtList.stream().filter(o -> null != o).distinct().collect(
                            Collectors.collectingAndThen(
                                    Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(MesPartExt::getPartNo))), ArrayList::new)
            );
            log.info("PS部件绑定批次查询结果itemPartExtList去重:size[{}]", CollectionUtils.isEmpty(itemPartExtList) ? 0 : itemPartExtList.size());
            Map<String, Integer> itemPartNoMap = CollectionUtils.isEmpty(itemPartExtList) ? null :
                    itemPartExtList.stream().filter(o -> null != o)
                            .collect(Collectors.toMap(MesPartExt::getPartNo, o -> Optional.ofNullable(o.getIsPSParts()).orElse(0), (a, b) -> b, HashMap::new));
            if (!CollectionUtils.isEmpty(itemPartNoMap)) {
                log.info("PS部件绑定批次查询结果partNoMap:size[{}]", itemPartNoMap.size());
            }
            for (WmsPsCheckModel psCheckModel : resultList) {
                if (null == psCheckModel) {
                    continue;
                }
                Integer psPartCheckFlag;
                if (CollectionUtils.isEmpty(itemPartNoMap) || !itemPartNoMap.containsKey(psCheckModel.getItemPartNo())) {
                    log.info("PS部件绑定批次查询结果:itemPartExtList未包含的物料[{}]", psCheckModel.getItemPartNo());
                    DdlPackBean packBean1 = DdlPackBean.getDdlPackBean(wmsPsCheckModel.getOrganizeCode());
                    DdlPreparedPack.getStringEqualPack(psCheckModel.getItemPartNo(), MesExtConstWords.PART_NO, packBean1);
                    MesPartExt partExt = partExtRepository.getByProperty(packBean1);
                    psPartCheckFlag = (null == partExt) ? null : partExt.getIsPSParts();
                } else {
                    psPartCheckFlag = itemPartNoMap.get(psCheckModel.getItemPartNo());
                }
                psCheckModel.setPsPartCheckFlag(
                        (StringUtils.isEmpty(psPartCheckFlag) || StringUtils.isEmpty(CommonEnumUtil.TRUE_OR_FALSE.valueOfDescription(psPartCheckFlag)))
                                ? CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue() : psPartCheckFlag);
                psCheckModel.setPsPartCheckFlagName(CommonEnumUtil.TRUE_OR_FALSE.valueOfDescription(psCheckModel.getPsPartCheckFlag()));
            }

            log.info("PS部件绑定批次查询结果完成封装是否PS补件属性:size[{}]", resultList.size());

            if (!StringUtils.isEmpty(wmsPsCheckModel.getPsPartCheckFlag())) {
                resultList = resultList.stream()
                        .filter(o -> (null != o && !StringUtils.isEmpty(o.getPsPartCheckFlag()) && o.getPsPartCheckFlag().compareTo(wmsPsCheckModel.getPsPartCheckFlag()) == 0))
                        .collect(Collectors.toList());
                log.info("PS部件绑定批次查询结果筛选[{}]的数据:size[{}]", wmsPsCheckModel.getPsPartCheckFlag(), CollectionUtils.isEmpty(resultList) ? 0 : resultList.size());
            }

            log.info("PS部件绑定批次查询结果判断是否需要排序");
            if (!CollectionUtils.isEmpty(resultList)) {
                List<WmsPsCheckModel> list1 = resultList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getSn()) && StringUtils.isEmpty(o.getDate()))).collect(Collectors.toList());
                log.info("PS部件绑定批次查询结果排序:筛选出sn不为空date为空的数据量[{}]", CollectionUtils.isEmpty(list1) ? 0 : list1.size());
                List<WmsPsCheckModel> list2 = resultList.stream().filter(o -> (null != o && StringUtils.isEmpty(o.getSn()))).collect(Collectors.toList());
                log.info("PS部件绑定批次查询结果排序:筛选出sn为空的数据量[{}]", CollectionUtils.isEmpty(list2) ? 0 : list2.size());
                resultList = resultList.stream()
                        .filter(o -> (null != o && !StringUtils.isEmpty(o.getSn()) && !StringUtils.isEmpty(o.getDate())))
                        .sorted(Comparator.comparing(WmsPsCheckModel::getSn).thenComparing(WmsPsCheckModel::getDate)).collect(Collectors.toList());
                log.info("PS部件绑定批次查询结果完成对sn不为空date不为空的数据排序:size[{}]", resultList.size());
            }

            pager = PagerHelper.getPager(pager, CollectionUtils.isEmpty(resultList) ? 0 : resultList.size());
            if (!CollectionUtils.isEmpty(resultList)) {
                resultList = resultList.subList((pager.getCurrentPage() - 1) * pager.getPageSize(),
                        (pager.getCurrentPage() * pager.getPageSize()) > resultList.size() ? resultList.size() : pager.getCurrentPage() * pager.getPageSize());
                log.info("PS部件绑定批次查询结果截取分页数据:size[{}]", resultList.size());
            }
        } else {
            pager = PagerHelper.getPager(pager, 0);
        }

        return new ListPager(resultList, pager);
    }

    @Override
    public int getProduceSnNumByOrderNo(String workOrderNo, String organizeCode) {
        List<MesProduceSnExt> produceSnExtList = produceSnExtRepository.findByProperty(
                new String[]{MesExtConstWords.ORGANIZE_CODE, MesExtConstWords.IS_DELETED, MesExtConstWords.IS_VALID, MesExtConstWords.LAST_WORK_ORDER_NO},
                new Object[]{organizeCode, CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), CommonEnumUtil.IS_VAILD.VAILD.getValue(), workOrderNo});
        log.info("HTTP调用MES 获取工单下条码数量 --- 条码个数：{}", produceSnExtList.size());
        return produceSnExtList.size();
    }

}
