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

import cn.estsh.i3plus.ext.mes.pcn.api.base.ISxPcnHttpService;
import cn.estsh.i3plus.ext.mes.pcn.api.base.ISxWorkOrderExtService;
import cn.estsh.i3plus.ext.mes.pcn.api.base.bu.IBuFirstOrderService;
import cn.estsh.i3plus.ext.mes.pcn.pojo.bean.*;
import cn.estsh.i3plus.ext.mes.pcn.pojo.model.WmsSnInfoModel;
import cn.estsh.i3plus.ext.mes.pcn.pojo.repository.MesFirstOrderDetailRepository;
import cn.estsh.i3plus.ext.mes.pcn.pojo.repository.MesOrderJobRepository;
import cn.estsh.i3plus.ext.mes.pcn.pojo.repository.MesProduceSnMcRecordRepository;
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.convert.ConvertBean;
import cn.estsh.i3plus.platform.common.exception.ImppExceptionEnum;
import cn.estsh.i3plus.platform.common.tool.JsonUtilTool;
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.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.StringUtils;

import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * @Author: xiangming.liao
 * @CreateDate: 2021/01/18 16:00
 * @Description:
 **/
@Slf4j
@Service
public class BuFirstOrderService implements IBuFirstOrderService {

    @Autowired
    private MesOrderJobRepository orderJobRepository;

    @Autowired
    private ISxWorkOrderExtService workOrderExtService;

    @Autowired
    private MesFirstOrderDetailRepository mesFirstOrderDetailRDao;

    @Autowired
    private MesProduceSnMcRecordRepository produceSnMcRecordRepository;

    @Autowired
    private ISxPcnHttpService pcnHttpService;

    @Override
    public void doCheckSerialNumber(String serialNumber, String orderNo, String workOrderNo, String organizeCode, String modifyUser) {
        if (StringUtils.isEmpty(serialNumber) || StringUtils.isEmpty(orderNo) ||
                StringUtils.isEmpty(workOrderNo) || StringUtils.isEmpty(organizeCode) || StringUtils.isEmpty(modifyUser)) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                    .setErrorDetail("入参缺失必要参数")
                    .build();
        }

        //扫描管理码
        MesProduceSnMcRecord produceSnMcRecordDb = produceSnMcRecordRepository.getByProperty(
                new String[]{MesPcnExtConstWords.ORGANIZE_CODE, MesPcnExtConstWords.IS_DELETED, MesPcnExtConstWords.IS_VALID, MesPcnExtConstWords.MANAGE_CODE, MesPcnExtConstWords.SN_STATUS},
                new Object[]{organizeCode, CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), CommonEnumUtil.IS_VAILD.VAILD.getValue(), serialNumber, MesPcnExtEnumUtil.MC_RECORD_SN_STATUS.LINE_ON.getValue()});


        if (produceSnMcRecordDb == null) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_NOT_EXIT.getCode())
                    .setErrorDetail("管理码[%s]不存在或未上线", serialNumber)
                    .build();
        }

        if (!produceSnMcRecordDb.getWorkOrderNo().equals(workOrderNo)) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_NOT_EXIT.getCode())
                    .setErrorDetail("管理码[%s]不存在于当前工单中", serialNumber)
                    .build();
        }

        //MesProduceSnExt produceSnExt = produceSnExtRepository.getByProperty(
        //        new String[]{MesPcnExtConstWords.ORGANIZE_CODE, MesPcnExtConstWords.IS_DELETED, MesPcnExtConstWords.IS_VALID, MesPcnExtConstWords.SERIAL_NUMBER, MesPcnExtConstWords.WORK_ORDER_NO},
        //        new Object[]{organizeCode, CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), CommonEnumUtil.IS_VAILD.VAILD.getValue(), serialNumber, workOrderNo});
        //
        //if (produceSnExt == null) {
        //    throw ImppExceptionBuilder.newInstance()
        //            .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
        //            .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_NOT_EXIT.getCode())
        //            .setErrorDetail("管理码[%s]不存在于当前工单中", serialNumber)
        //            .build();
        //}

        MesOrderJob orderJobDb = orderJobRepository.getByProperty(
                new String[]{MesPcnExtConstWords.ORGANIZE_CODE, MesPcnExtConstWords.IS_DELETED, MesPcnExtConstWords.IS_VALID, MesPcnExtConstWords.ORDER_NO},
                new Object[]{organizeCode, CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), CommonEnumUtil.IS_VAILD.VAILD.getValue(), orderNo});

        if (null == orderJobDb) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_NOT_EXIT.getCode())
                    .setErrorDetail("单据[%s]无效", orderNo)
                    .build();
        }

        if (!StringUtils.isEmpty(orderJobDb.getSerialNumber())) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                    .setErrorDetail("单据[%s]已经绑定条码[%s],不可再次执行绑定", orderNo, orderJobDb.getSerialNumber())
                    .build();
        }

        MesWorkOrderExt workOrderExt = workOrderExtService.getWorkOrderExtByOrderNo(organizeCode, workOrderNo);
        if (null == workOrderExt) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_NOT_EXIT.getCode())
                    .setErrorDetail("生产工单号[%s]无效", workOrderNo)
                    .build();
        }

        if (workOrderExt.getWorkOrderType() != MesPcnExtEnumUtil.WORK_ORDER_TYPE.STANDARD_ORDER.getValue()) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_NOT_EXIT.getCode())
                    .setErrorDetail("工单号[%s]不为正常工单", workOrderNo)
                    .build();
        }

        MesOrderJob orderJobExist = orderJobRepository.getByProperty(
                new String[]{MesPcnExtConstWords.ORGANIZE_CODE, MesPcnExtConstWords.IS_DELETED, MesPcnExtConstWords.IS_VALID, MesPcnExtConstWords.SERIAL_NUMBER},
                new Object[]{organizeCode, CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), CommonEnumUtil.IS_VAILD.VAILD.getValue(), produceSnMcRecordDb.getSerialNumber()});
        if (null != orderJobExist) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                    .setErrorDetail("条码[%s]已经绑定单据[%s],不可再次执行绑定", serialNumber, orderJobExist.getOrderNo())
                    .build();
        }

        orderJobDb.setSerialNumber(produceSnMcRecordDb.getSerialNumber());
        ConvertBean.serviceModelUpdate(orderJobDb, modifyUser);
        orderJobRepository.save(orderJobDb);
    }

    @Override
    public List<MesFirstOrderDetail> findMesFirstOrderDetail(String orderNo, String organizeCode) {
        if(StringUtils.isEmpty(orderNo)){
            log.info("BuFirstOrderService-findMesFirstOrderDetail exec 单号为空 - 工厂代码：{}", organizeCode);
            return null;
        }
        DdlPackBean packBean = DdlPackBean.getDdlPackBean(organizeCode);
        DdlPreparedPack.getStringEqualPack(orderNo, "orderNo", packBean);
        return mesFirstOrderDetailRDao.findByHqlWhere(packBean);
    }

    @Override
    public String updateMesFirstOrderDetail(MesFirstOrderDetail mesFirstOrderDetail, String userName) {

        //上下限有值时，结果值为必填
        if (!StringUtils.isEmpty(mesFirstOrderDetail.getUpLimit()) && !StringUtils.isEmpty(mesFirstOrderDetail.getDownLimit()) && StringUtils.isEmpty(mesFirstOrderDetail.getResultValue())){
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_EXIT.getCode())
                    .setErrorDetail("上下限有值，结果值为必填")
                    .build();
        }

        //根据单号查询任务主表信息
        String orderNo = mesFirstOrderDetail.getOrderNo();
        MesOrderJob mesOrderJob = orderJobRepository.getByProperty(
                new String[]{MesPcnExtConstWords.ORGANIZE_CODE, MesPcnExtConstWords.IS_DELETED, MesPcnExtConstWords.IS_VALID, MesPcnExtConstWords.ORDER_NO},
                new Object[]{mesFirstOrderDetail.getOrganizeCode(), CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(),
                        MesPcnExtEnumUtil.IS_VAILD.VAILD.getValue(), orderNo});

        if(null == mesOrderJob){
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_EXIT.getCode())
                    .setErrorDetail("单据【%s】不存在",orderNo)
                    .build();
        }

        if (!StringUtils.isEmpty(mesFirstOrderDetail.getUpLimit()) && !StringUtils.isEmpty(mesFirstOrderDetail.getDownLimit()) && StringUtils.isEmpty(mesFirstOrderDetail.getResultValue())){
            Double resultValue = Double.valueOf(mesFirstOrderDetail.getResultValue());
            if (!StringUtils.isEmpty(mesFirstOrderDetail.getUpLimit()) && StringUtils.isEmpty(mesFirstOrderDetail.getDownLimit())){
                Double upLimit = Double.valueOf(mesFirstOrderDetail.getUpLimit());
                if (resultValue > upLimit && mesFirstOrderDetail.getCheckResult().equals("10")){
                    mesFirstOrderDetail.setCheckResult("20");
                }else if (resultValue <= upLimit && mesFirstOrderDetail.getCheckResult().equals("20")){
                    mesFirstOrderDetail.setCheckResult("10");
                }
            }else if (StringUtils.isEmpty(mesFirstOrderDetail.getUpLimit()) && !StringUtils.isEmpty(mesFirstOrderDetail.getDownLimit())){
                Double downLimit = Double.valueOf(mesFirstOrderDetail.getDownLimit());
                if (resultValue < downLimit && mesFirstOrderDetail.getCheckResult().equals("10")){
                    mesFirstOrderDetail.setCheckResult("20");
                }else if (resultValue >= downLimit && mesFirstOrderDetail.getCheckResult().equals("20")){
                    mesFirstOrderDetail.setCheckResult("10");
                }
            }else if (!StringUtils.isEmpty(mesFirstOrderDetail.getUpLimit()) && !StringUtils.isEmpty(mesFirstOrderDetail.getDownLimit())){
                Double upLimit = Double.valueOf(mesFirstOrderDetail.getUpLimit());
                Double downLimit = Double.valueOf(mesFirstOrderDetail.getDownLimit());
                if ((upLimit >= resultValue && resultValue >= downLimit) && mesFirstOrderDetail.getCheckResult().equals("20")){
                    mesFirstOrderDetail.setCheckResult("10");
                }else if (!(upLimit >= resultValue && resultValue >= downLimit) && mesFirstOrderDetail.getCheckResult().equals("10")){
                    mesFirstOrderDetail.setCheckResult("20");
                }
            }
        }

        if (mesFirstOrderDetail.getManageType().equals(MesPcnExtEnumUtil.Q_MANAGE_MANAGE_TYPE.RESULT_TYPE.getValue()) && !StringUtils.isEmpty(mesFirstOrderDetail.getImportanceSafePartNo())){
            if (!mesFirstOrderDetail.getImportanceSafePartNo().equals(mesFirstOrderDetail.getResultValue())) {

                String requestUrl = pcnHttpService.getRequestUrl(mesFirstOrderDetail.getOrganizeCode(), MesPcnExtConstWords.FIND_PART_NO);
                Map<String, String> params = new HashMap<>();
                params.put(MesPcnExtConstWords.SN, mesFirstOrderDetail.getResultValue());
                params.put(MesPcnExtConstWords.ORGANIZE_CODE, mesFirstOrderDetail.getOrganizeCode());
                WmsSnInfoModel wmsSnInfoModel = null;
                try {
                    String data = PcnHttpUtil.doGet(requestUrl, params);
                    BaseResultBean baseResultBean = null;

                    if (!StringUtils.isEmpty(data)) {
                        baseResultBean = JsonUtilTool.decode(data, BaseResultBean.class);
                    } else {
                        log.error("updateMesFirstOrderDetail --- HTTP[{}]调用主接口失败", requestUrl);
                    }

                    log.error("updateMesFirstOrderDetail --- Q管理校验物料时获取WMS数据[{}]", data);

                    if (null != baseResultBean && baseResultBean.success) {
                        LinkedHashMap resultObject = (LinkedHashMap) baseResultBean.getResultObject();
                        wmsSnInfoModel= JsonUtilTool.decode(JSONObject.toJSONString(resultObject), WmsSnInfoModel.class);
                    }
                    if (wmsSnInfoModel == null) {
                        log.error("updateMesFirstOrderDetail --- Q管理校验物料时获取WMS数据失败 HTTP[{}]调用主接口 无法获取此条码信息", requestUrl);
                    }
                } catch (UnsupportedEncodingException e) {
                    log.error("updateMesFirstOrderDetail --- Q管理校验物料时获取WMS数据失败 HTTP[{}]调用主接口失败", requestUrl);
                }

                if ((wmsSnInfoModel == null) || (!wmsSnInfoModel.getPartNo().equals(mesFirstOrderDetail.getImportanceSafePartNo()))) {
                    log.info("updateMesFirstOrderDetail --- 条码为空或条码的重要安全部品编码不一致");
                    mesFirstOrderDetail.setCheckResult("20");
                } else {
                    mesFirstOrderDetail.setCheckResult("10");
                }
            } else {
                mesFirstOrderDetail.setCheckResult("10");
            }
        }

        //修改首检单明细数据
        mesFirstOrderDetail.setSpotCheckUser(userName);
        ConvertBean.serviceModelUpdate(mesFirstOrderDetail, userName);
        mesFirstOrderDetail.setSpotCheckTime(mesFirstOrderDetail.getModifyDatetime());
        mesFirstOrderDetailRDao.save(mesFirstOrderDetail);

        mesOrderJob.setOrderStatus(MesPcnExtEnumUtil.MES_ORJ_ORDER_STATUS.CHECKING.getValue());
        ConvertBean.serviceModelUpdate(mesOrderJob, userName);

        orderJobRepository.save(mesOrderJob);

        return mesFirstOrderDetail.getCheckResult();
    }
}
