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

import cn.estsh.i3plus.ext.mes.pcn.api.base.ISxPcnHttpService;
import cn.estsh.i3plus.ext.mes.pcn.api.busi.bu3.ISxReworkOrderService;
import cn.estsh.i3plus.ext.mes.pcn.apiservice.dao.bu3.ISxBuPackageExtDao;
import cn.estsh.i3plus.ext.mes.pcn.pojo.bean.*;
import cn.estsh.i3plus.ext.mes.pcn.pojo.model.bu3.SxPackSnReportModel;
import cn.estsh.i3plus.ext.mes.pcn.pojo.repository.*;
import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtConstWords;
import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtEnumUtil;
import cn.estsh.i3plus.mes.pcn.util.PcnHttpUtil;
import cn.estsh.i3plus.platform.common.exception.ImppExceptionEnum;
import cn.estsh.i3plus.platform.common.tool.JsonUtilTool;
import cn.estsh.i3plus.platform.common.tool.TimeTool;
import cn.estsh.i3plus.pojo.base.bean.BaseResultBean;
import cn.estsh.i3plus.pojo.base.bean.DdlPackBean;
import cn.estsh.i3plus.pojo.base.enumutil.CommonEnumUtil;
import cn.estsh.i3plus.pojo.base.tool.DdlPreparedPack;
import cn.estsh.i3plus.pojo.mes.bean.MesPackageDetail;
import cn.estsh.i3plus.pojo.mes.bean.MesWorkOrder;
import cn.estsh.i3plus.pojo.mes.repository.MesPackageDetailRepository;
import cn.estsh.i3plus.pojo.mes.repository.MesWorkOrderRepository;
import cn.estsh.impp.framework.boot.auth.AuthUtil;
import cn.estsh.impp.framework.boot.exception.ImppExceptionBuilder;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

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

/**
 * @PROJECT_NAME: i3plus-mes-panasonic-dev
 * @DESCRIPTION:
 * @USER: xinwang.yi
 * @DATE: 2023-07-04 17:49
 */
@Service
@Slf4j
public class SxReworkOrderService implements ISxReworkOrderService {

    @Autowired
    private MesWorkOrderRepository workOrderRepository;

    @Autowired
    private MesReworkOrderRepository reworkOrderRepository;

    @Autowired
    private MesProduceSnRepairRepository produceSnRepairRepository;

    @Autowired
    private MesProduceSnExtRepository produceSnExtRepository;

    @Autowired
    private MesBusiConfigRepository busiConfigRepository;

    @Autowired
    private MesPackageExtRepository packageExtRepository;

    @Autowired
    private MesPackageDetailRepository packageDetailRepository;

    @Autowired
    private MesProdBindRecordExtRepository prodBindRecordExtRepository;

    @Autowired
    private ISxPcnHttpService pcnHttpService;

    @Autowired
    private ISxBuPackageExtDao packageExtDao;

    @Override
    public void updateReworkOrderStatus(String organizeCode, String userName, String nowTime, Integer woStatus, List<String> workOrderNoList) {
        updateReworkOrder(organizeCode, userName, woStatus, workOrderNoList);
        if (woStatus == MesPcnExtEnumUtil.WORK_ORDER_STATUS.CLOSE.getValue()) {
            List<MesWorkOrder> workOrderList = getMesWorkOrders(organizeCode, workOrderNoList);
            MesBusiConfig waterPurifierCode = getMesBusiConfig(organizeCode);
            List<String> waterPurifierCodeList = !Optional.ofNullable(waterPurifierCode).isPresent() || StringUtils.isEmpty(waterPurifierCode.getCfgValue()) ? new ArrayList<>() : Arrays.asList(waterPurifierCode.getCfgValue().split(MesPcnExtConstWords.COMMA));
            log.info("手动完成工单修改未下线条码 --- 净水器线配置代码：{} --- 查询到的工单号：{}", waterPurifierCodeList, workOrderList.stream().map(MesWorkOrder::getOrderNo).collect(Collectors.toList()));
            List<MesWorkOrder> workOrderFilterByCenterList = workOrderList.stream().filter(o -> !waterPurifierCodeList.contains(o.getWorkCenterCode()) && o.getQty().compareTo(o.getCompleteQty()) != 0).collect(Collectors.toList());
            if (!CollectionUtils.isEmpty(workOrderFilterByCenterList)) {
                List<String> orderNoList = workOrderFilterByCenterList.stream().map(MesWorkOrder::getOrderNo).collect(Collectors.toList());

                for (String orderNo : orderNoList) {
                    log.info("手动完成工单修改未下线条码  --- 工单号：{}正在进行条码解绑", orderNo);
                    DdlPackBean packBean = DdlPackBean.getDdlPackBean(organizeCode);
                    DdlPreparedPack.getStringEqualPack(orderNo, MesPcnExtConstWords.WORK_ORDER_NO, packBean);
                    List<MesProduceSnRepair> produceSnRepairList = produceSnRepairRepository.findByHqlWhere(packBean);

                    // 未下线条码
                    produceSnRepairList = produceSnRepairList.stream().filter(o -> StringUtils.isEmpty(o.getOutWorkCenterTime())).collect(Collectors.toList());

                    if (!CollectionUtils.isEmpty(produceSnRepairList)) {
                        List<String> serialNumberList = produceSnRepairList.stream().map(MesProduceSnRepair::getSerialNumber).collect(Collectors.toList());
                        updateProduceSn(organizeCode, serialNumberList);

                        updatePackage(organizeCode, serialNumberList);

                        clearProdBindRecord(organizeCode, orderNo, nowTime, serialNumberList);

                        unbindReworkRangeList(organizeCode, orderNo, serialNumberList, userName);

                        produceSnRepairList.forEach(o -> {
                            o.setIsDeleted(CommonEnumUtil.IS_DEAL.YES.getValue());
                            o.setModifyUser(userName);
                            o.setModifyDatetime(nowTime);
                            o.setSystemSyncStatus(MesPcnExtEnumUtil.IF_SYNC_STATUS.NO_SYNC.getValue());
                        });
                        produceSnRepairRepository.saveAll(produceSnRepairList);
                    }
                }
            } else {
                log.info("手动完成工单修改未下线条码 --- 净水器线配置代码：{} --- 所查询工单号为净水器线，不进行解绑：{}", waterPurifierCodeList, workOrderList.stream().map(MesWorkOrder::getOrderNo).collect(Collectors.toList()));
            }
        }

    }

    private void unbindReworkRangeList(String organizeCode, String orderNo, List<String> serialNumberList, String userName) {
        try {
            String requestUrl = pcnHttpService.getRequestUrl(organizeCode, MesPcnExtConstWords.UNBIND_REWORK_RANGE_LIST_URL);
            Map<String, String> params = new HashMap<>();
            params.put(MesPcnExtConstWords.ORGANIZE_CODE, organizeCode);
            params.put(MesPcnExtConstWords.WORK_ORDER_NO, orderNo);
            params.put(MesPcnExtConstWords.SERIAL_NUMBER, JSONObject.toJSONString(serialNumberList));
            params.put(MesPcnExtConstWords.USER_NAME, userName);
            String data = PcnHttpUtil.doPost(requestUrl, params);
            BaseResultBean baseResultBean = null;
            if (!StringUtils.isEmpty(data)) {
                baseResultBean = JsonUtilTool.decode(data, BaseResultBean.class);
            } else {
                throw ImppExceptionBuilder.newInstance().setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                        .setErrorDetail("HTTP[%s]调用主接口失败", requestUrl)
                        .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                        .build();
            }
            if (!baseResultBean.success) {
                throw ImppExceptionBuilder.newInstance().setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                        .setErrorDetail(baseResultBean.getErrorMsg())
                        .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                        .build();
            }
        } catch (Exception e) {
            throw ImppExceptionBuilder.newInstance().setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                    .setErrorDetail("返工范围与当前工单解除关联失败")
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .build();
        }
        //BaseResultBean baseResultBean = reworkRangeCloud.unbindReworkRangeList(mesWorkOrder.getOrderNo(), serialNumberList, organizeCode, AuthUtil.getSessionUser().getUserName());
        //if (!baseResultBean.success) {
        //    throw ImppExceptionBuilder.newInstance().setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
        //            .setErrorDetail(baseResultBean.getErrorMsg())
        //            .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
        //            .build();
        //}

        //DdlPackBean packBean = DdlPackBean.getDdlPackBean(organizeCode);
        //DdlPreparedPack.getStringEqualPack(mesWorkOrder.getOrderNo(), MesExtConstWords.REWORK_ORDER_NO, packBean);
        //List<MesReworkRange> reworkRangeList = reworkRangeRepository.findByHqlWhere(packBean);
        //
        //reworkRangeList = reworkRangeList.stream().filter(o -> serialNumberList.contains(o.getSerialNumber())).collect(Collectors.toList());
        //
        //reworkRangeList.forEach(o-> {
        //    o.setModifyUser(AuthUtil.getSessionUser().getUserName());
        //    o.setModifyDatetime(nowTime);
        //    o.setBindStatus(MesExtEnumUtil.PACKAGE_BIND_STATUS.BINGDING.getValue());
        //    o.setSystemSyncStatus(MesExtEnumUtil.IF_SYNC_STATUS.NO_SYNC.getValue());
        //    o.setReworkOrderNo("");
        //});
        //
        //reworkRangeRepository.saveAll(reworkRangeList);
    }

    private void clearProdBindRecord(String organizeCode, String orderNo, String nowTime, List<String> serialNumberList) {
        DdlPackBean packBean = DdlPackBean.getDdlPackBean(organizeCode);
        DdlPreparedPack.getStringEqualPack(orderNo, MesPcnExtConstWords.WORK_ORDER_NO, packBean);
        DdlPreparedPack.getInPackList(serialNumberList, MesPcnExtConstWords.SERIAL_NUMBER, packBean);
        List<MesProdBindRecordExt> prodBindRecordExtList = prodBindRecordExtRepository.findByHqlWhere(packBean);
        prodBindRecordExtList.forEach(o -> {
            o.setIsDeletedExt(MesPcnExtEnumUtil.IS_VAILD.VAILD.getValue());
            o.setIsValidExt(MesPcnExtEnumUtil.IS_VAILD.INVAILD.getValue());
            o.setModifyDatetimeExt(nowTime);
            o.setModifyDatetime(nowTime);
            o.setModifyUser(AuthUtil.getSessionUser().getUserName());
            o.setModifyUserExt(AuthUtil.getSessionUser().getUserName());
        });

        prodBindRecordExtRepository.saveAll(prodBindRecordExtList);
    }

    private void updatePackage(String organizeCode, List<String> serialNumberList) {
        DdlPackBean packBean = DdlPackBean.getDdlPackBean(organizeCode);
        DdlPreparedPack.getInPackList(serialNumberList, MesPcnExtConstWords.SERIAL_NUMBER, packBean);
        List<MesPackageDetail> packageDetailList = packageDetailRepository.findByHqlWhere(packBean);
        List<String> packageNoList = packageDetailList.stream().map(MesPackageDetail::getPackageNo).distinct().collect(Collectors.toList());

        packBean = DdlPackBean.getDdlPackBean(organizeCode);
        DdlPreparedPack.getInPackList(packageNoList, MesPcnExtConstWords.PACKAGENO, packBean);
        List<MesPackageExt> packageExtList = packageExtRepository.findByHqlWhere(packBean);
        packageExtList.forEach(o -> {
            o.setLastWorkOrderNo(o.getWorkOrderNo());
        });
        packageExtRepository.saveAll(packageExtList);
    }

    private void updateProduceSn(String organizeCode, List<String> serialNumberList) {
        DdlPackBean packBean = DdlPackBean.getDdlPackBean(organizeCode);
        DdlPreparedPack.getInPackList(serialNumberList, MesPcnExtConstWords.SERIAL_NUMBER, packBean);
        List<MesProduceSnExt> produceSnExtList = produceSnExtRepository.findByHqlWhere(packBean);
        //String nowTime = TimeTool.getNowTime(true);
        produceSnExtList.forEach(o -> {
            o.setSnStatus(MesPcnExtEnumUtil.PRODUCE_SN_STATUS.OFFLINE.getValue());
            //o.setModifyUserExt(AuthUtil.getSessionUser().getUserName());
            //o.setModifyDatetimeExt(nowTime);
            //o.setModifyUser(AuthUtil.getSessionUser().getUserName());
            //o.setModifyDatetime(nowTime);
            o.setSystemSyncStatus(MesPcnExtEnumUtil.IF_SYNC_STATUS.NO_SYNC.getValue());
            o.setSystemSyncStatusExt(MesPcnExtEnumUtil.IF_SYNC_STATUS.NO_SYNC.getValue());
        });
        produceSnExtRepository.saveAll(produceSnExtList);
    }

    private MesBusiConfig getMesBusiConfig(String organizeCode) {
        MesBusiConfig waterPurifierCode = busiConfigRepository.getByProperty(
                new String[]{MesPcnExtConstWords.ORGANIZE_CODE, MesPcnExtConstWords.IS_DELETED, MesPcnExtConstWords.IS_VALID, MesPcnExtConstWords.CFG_CODE},
                new Object[]{organizeCode, CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), CommonEnumUtil.IS_VAILD.VAILD.getValue(), MesPcnExtConstWords.WATER_PURIFIER_CODE});
        return waterPurifierCode;
    }

    private List<MesWorkOrder> getMesWorkOrders(String organizeCode, List<String> workOrderNoList) {
        DdlPackBean packBean = DdlPackBean.getDdlPackBean(organizeCode);
        DdlPreparedPack.getInPackList(workOrderNoList, MesPcnExtConstWords.ORDER_NO, packBean);
        List<MesWorkOrder> workOrderList = workOrderRepository.findByHqlWhere(packBean);
        return workOrderList;
    }

    private List<MesReworkOrder> updateReworkOrder(String organizeCode, String userName, Integer woStatus, List<String> workOrderNoList) {
        DdlPackBean packBean = DdlPackBean.getDdlPackBean(organizeCode);
        DdlPreparedPack.getInPackList(workOrderNoList, MesPcnExtConstWords.REWORK_ORDER_NO, packBean);
        List<MesReworkOrder> reworkOrderList = reworkOrderRepository.findByHqlWhere(packBean);
        String nowTime = TimeTool.getNowTime(true);
        if (!CollectionUtils.isEmpty(reworkOrderList)) {
            reworkOrderList.forEach(o -> {
                o.setWorkOrderStatus(woStatus);
                o.setSystemSyncStatus(MesPcnExtEnumUtil.IF_SYNC_STATUS.NO_SYNC.getValue());
                o.setModifyUser(userName);
                o.setModifyDatetime(nowTime);
            });
            reworkOrderRepository.saveAll(reworkOrderList);
        }
        return reworkOrderList;
    }

    @Override
    public List<MesProduceSnRepair> queryMesProduceSnRepairList(String organizeCode, String workOrderNo) {
        DdlPackBean packBean = DdlPackBean.getDdlPackBean(organizeCode);
        DdlPreparedPack.getStringEqualPack(MesPcnExtConstWords.WORK_ORDER_NO, workOrderNo, packBean);
        return produceSnRepairRepository.findByHqlWhere(packBean);
    }

    @Override
    public List<SxPackSnReportModel> queryStandardWorkOrderPackSn(SxPackSnReportModel model) {
        log.info("queryStandardWorkOrderPackSn --- 参数：{}", model);
        List<SxPackSnReportModel> sxPackSnReportModels = packageExtDao.queryStandardWorkOrderPackSnList(model);

        log.info("queryStandardWorkOrderPackSn --- 结果集数：{}", sxPackSnReportModels.size());
        return sxPackSnReportModels;
    }
}
