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

import cn.estsh.i3plus.ext.mes.api.base.IProdOrgExtService;
import cn.estsh.i3plus.ext.mes.api.base.bu.IBusiConfigService;
import cn.estsh.i3plus.ext.mes.api.base.bu3.ISxCareerCorrelationCfgService;
import cn.estsh.i3plus.ext.mes.api.base.bu3.ISxPartCategoryPlanRateService;
import cn.estsh.i3plus.ext.mes.pojo.bean.MesCareerCorrelationCfg;
import cn.estsh.i3plus.ext.mes.pojo.repository.MesCareerCorrelationCfgRepository;
import cn.estsh.i3plus.ext.mes.pojo.sqlpack.MesExtHqlPack;
import cn.estsh.i3plus.ext.mes.pojo.util.MesExtConstWords;
import cn.estsh.i3plus.ext.mes.pojo.util.MesExtEnumUtil;
import cn.estsh.i3plus.platform.common.convert.ConvertBean;
import cn.estsh.i3plus.platform.common.exception.ImppExceptionEnum;
import cn.estsh.i3plus.platform.common.tool.MathOperation;
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.mes.bean.MesWorkCenter;
import cn.estsh.impp.framework.boot.exception.ImppExceptionBuilder;
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.List;
import java.util.Map;

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

    @Autowired
    private MesCareerCorrelationCfgRepository careerCorrelationCfgRepository;

    @Autowired
    private IBusiConfigService busiConfigService;

    @Autowired
    private ISxPartCategoryPlanRateService partCategoryPlanRateService;

    @Autowired
    private IProdOrgExtService prodOrgExtService;

    @Override
    public ListPager<MesCareerCorrelationCfg> queryCareerCorrelationCfgByPager(MesCareerCorrelationCfg careerCorrelationCfg, Pager pager) {
        DdlPackBean hqlPack = MesExtHqlPack.getCareerCorrelationCfg(careerCorrelationCfg);
        pager = PagerHelper.getPager(pager, careerCorrelationCfgRepository.findByHqlWhereCount(hqlPack));
        hqlPack.setOrderByStr(" order by dataKey, modifyDatetime ");
        List<MesCareerCorrelationCfg> careerCorrelationCfgList = careerCorrelationCfgRepository.findByHqlWherePage(hqlPack, pager);
        if (!StringUtils.isEmpty(careerCorrelationCfgList)) {
            Map<String, String> careerMap = busiConfigService.getConfigMap(careerCorrelationCfg.getOrganizeCode(), MesExtConstWords.SX_CAREER_CFG);
            Map<String, String> categoryMap = partCategoryPlanRateService.getCategoryMap(careerCorrelationCfg.getOrganizeCode());
            Map<String, MesWorkCenter> workCenterMap = prodOrgExtService.queryWorkCenterMap(careerCorrelationCfg.getOrganizeCode());
            for (MesCareerCorrelationCfg item : careerCorrelationCfgList) {
                if (null == item) continue;
                item.setCareerName((!StringUtils.isEmpty(item.getCareerCode()) && !CollectionUtils.isEmpty(careerMap) && careerMap.containsKey(item.getCareerCode())) ? careerMap.get(item.getCareerCode()) : null);
                item.setCategoryName((!StringUtils.isEmpty(item.getCategoryCode()) && !CollectionUtils.isEmpty(categoryMap)) ? categoryMap.get(item.getCategoryCode()) : null);
                item.setWorkCenterName((!StringUtils.isEmpty(item.getWorkCenterCode()) && !CollectionUtils.isEmpty(workCenterMap)) ? workCenterMap.get(item.getWorkCenterCode()).getWorkCenterName() : null);
                if (MesExtEnumUtil.CAREER_CORRELATION_CFG_DATA_TYPE.COMPOSITE_RATE_TARGET.getValue().equals(item.getDataType())) item.splitValue();
            }
        }
        return new ListPager(careerCorrelationCfgList, pager);
    }

    @Override
    public MesCareerCorrelationCfg insertCareerCorrelationCfg(MesCareerCorrelationCfg careerCorrelationCfg) {
        checkParams(careerCorrelationCfg);
        checkValue(careerCorrelationCfg.getCfgValue());
        MesCareerCorrelationCfg careerCorrelationCfgDb = getCareerCorrelationCfg(careerCorrelationCfg);
        if (null != careerCorrelationCfgDb && CommonEnumUtil.IS_VAILD.VAILD.getValue() == careerCorrelationCfgDb.getIsValid()) throwExp(careerCorrelationCfg);
        if (null == careerCorrelationCfgDb) careerCorrelationCfgDb = new MesCareerCorrelationCfg();
        careerCorrelationCfgDb.setCareerCode(careerCorrelationCfg.getCareerCode());
        careerCorrelationCfgDb.setCategoryCode(careerCorrelationCfg.getCategoryCode());
        careerCorrelationCfgDb.setWorkCenterCode(careerCorrelationCfg.getWorkCenterCode());
        careerCorrelationCfgDb.setDataType(careerCorrelationCfg.getDataType());
        careerCorrelationCfgDb.setDataKey(careerCorrelationCfg.getDataKey());
        careerCorrelationCfgDb.setCfgValue(careerCorrelationCfg.getCfgValue());
        careerCorrelationCfgDb.setDataDimension(careerCorrelationCfg.getDataDimension());
        careerCorrelationCfgDb.setSystemSyncStatus(MesExtEnumUtil.IF_SYNC_STATUS.NO_SYNC.getValue());
        if (StringUtils.isEmpty(careerCorrelationCfgDb.getId())) {
            careerCorrelationCfgDb.setOrganizeCode(careerCorrelationCfg.getOrganizeCode());
            ConvertBean.serviceModelInitialize(careerCorrelationCfgDb, careerCorrelationCfg.getCreateUser());
            careerCorrelationCfgDb = careerCorrelationCfgRepository.insert(careerCorrelationCfgDb);
        } else {
            careerCorrelationCfgDb.setIsValid(CommonEnumUtil.IS_VAILD.VAILD.getValue());
            ConvertBean.serviceModelUpdate(careerCorrelationCfgDb, careerCorrelationCfg.getCreateUser());
            careerCorrelationCfgDb = careerCorrelationCfgRepository.save(careerCorrelationCfgDb);
        }
        return careerCorrelationCfgDb;
    }

    private void throwExp(MesCareerCorrelationCfg careerCorrelationCfg) {
        if (!StringUtils.isEmpty(careerCorrelationCfg.getCategoryCode()))
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_EXIT.getCode())
                    .setErrorDetail("产品别[%s]配置键[%s]记录已存在,操作失败", careerCorrelationCfg.getCategoryCode(), careerCorrelationCfg.getDataKey())
                    .build();
        else if (!StringUtils.isEmpty(careerCorrelationCfg.getCareerCode()))
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_EXIT.getCode())
                    .setErrorDetail("事业别[%s]配置键[%s]记录已存在,操作失败", careerCorrelationCfg.getCareerCode(), careerCorrelationCfg.getDataKey())
                    .build();
        else
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_EXIT.getCode())
                    .setErrorDetail("产线别[%s]配置键[%s]记录已存在,操作失败", careerCorrelationCfg.getWorkCenterCode(), careerCorrelationCfg.getDataKey())
                    .build();
    }

    private void checkParams(MesCareerCorrelationCfg careerCorrelationCfg) {
        if (MesExtEnumUtil.CAREER_CORRELATION_CFG_DATA_TYPE.COMPOSITE_RATE_TARGET.getValue().equals(careerCorrelationCfg.getDataType())) {
            if (StringUtils.isEmpty(careerCorrelationCfg.getCareerCode()) && StringUtils.isEmpty(careerCorrelationCfg.getCategoryCode()) && StringUtils.isEmpty(careerCorrelationCfg.getWorkCenterCode()))
                throw ImppExceptionBuilder.newInstance()
                        .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                        .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                        .setErrorDetail("事业别与产品别与产线别至少必填一个")
                        .build();
        } else {
            if (StringUtils.isEmpty(careerCorrelationCfg.getCareerCode()))
                throw ImppExceptionBuilder.newInstance()
                        .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                        .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                        .setErrorDetail("事业别必填")
                        .build();
            if (StringUtils.isEmpty(careerCorrelationCfg.getCategoryCode()))
                throw ImppExceptionBuilder.newInstance()
                        .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                        .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                        .setErrorDetail("产品别必填")
                        .build();
        }
    }

    private MesCareerCorrelationCfg getCareerCorrelationCfg(MesCareerCorrelationCfg careerCorrelationCfg) {
        DdlPackBean packBean = DdlPackBean.getDdlPackBean(careerCorrelationCfg.getOrganizeCode());
        if (MesExtEnumUtil.CAREER_CORRELATION_CFG_DATA_TYPE.COMPOSITE_RATE_TARGET.getValue().equals(careerCorrelationCfg.getDataType())) {
            DdlPreparedPack.getStringEqualPack(careerCorrelationCfg.getDataDimension(), MesExtConstWords.DATA_DIMENSION, packBean);
            DdlPreparedPack.getStringEqualPack(careerCorrelationCfg.getCategoryCode(), MesExtConstWords.CATEGORY_CODE, packBean);
            DdlPreparedPack.getStringEqualPack(careerCorrelationCfg.getCareerCode(), MesExtConstWords.CAREER_CODE, packBean);
            DdlPreparedPack.getStringEqualPack(careerCorrelationCfg.getWorkCenterCode(), MesExtConstWords.WORK_CENTER_CODE, packBean);
        } else {
            if (!StringUtils.isEmpty(careerCorrelationCfg.getCategoryCode()))
                DdlPreparedPack.getStringEqualPack(careerCorrelationCfg.getCategoryCode(), MesExtConstWords.CATEGORY_CODE, packBean);
            else {
                DdlPreparedPack.getStringEqualPack(careerCorrelationCfg.getCareerCode(), MesExtConstWords.CAREER_CODE, packBean);
                DdlPreparedPack.getIsNull(MesExtConstWords.CATEGORY_CODE, packBean);
            }
        }

        DdlPreparedPack.getStringEqualPack(careerCorrelationCfg.getDataType(), MesExtConstWords.DATA_TYPE, packBean);
        DdlPreparedPack.getStringEqualPack(careerCorrelationCfg.getDataKey(), MesExtConstWords.DATA_KEY, packBean);
        return careerCorrelationCfgRepository.getByProperty(packBean);
    }

    private void checkValue(String cfgValue) {
        String[] values = cfgValue.split(MesExtConstWords.COMMA);
        for (String value : values) {
            checkDoubleValue(value);
        }
    }

    private void checkDoubleValue(String cfgValue) {
        try {
            if (MathOperation.compareTo(Double.parseDouble(cfgValue), new Double(0)) < 0)
                throw ImppExceptionBuilder.newInstance()
                        .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                        .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                        .setErrorDetail("配置值[%s]必须是正数,最多四位小数", cfgValue)
                        .build();
        } catch (NumberFormatException e) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                    .setErrorDetail("配置值[%s]必须是正数,最多四位小数", cfgValue)
                    .build();
        }
        String[] remainArr = cfgValue.split(MesExtConstWords.DECIMAL_POINT);
        if (remainArr.length == 2 && remainArr[1].length() > 4)
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                    .setErrorDetail("配置值[%s]必须是正数,最多四位小数", cfgValue)
                    .build();
    }

    @Override
    public MesCareerCorrelationCfg updateCareerCorrelationCfg(MesCareerCorrelationCfg careerCorrelationCfg) {
        checkParams(careerCorrelationCfg);
        checkValue(careerCorrelationCfg.getCfgValue());
        MesCareerCorrelationCfg careerCorrelationCfgDb = careerCorrelationCfgRepository.getById(Long.parseLong(careerCorrelationCfg.getIdStr()));
        if (null == careerCorrelationCfgDb)
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_NOT_EXIT.getCode())
                    .setErrorDetail("ID[%s]记录不存在", careerCorrelationCfg.getIdStr())
                    .build();
        MesCareerCorrelationCfg careerCorrelationCfgDbIsExist = getCareerCorrelationCfg(careerCorrelationCfg);
        if (null != careerCorrelationCfgDbIsExist && careerCorrelationCfgDbIsExist.getId().compareTo(careerCorrelationCfgDb.getId()) != 0) {
            if (CommonEnumUtil.IS_VAILD.VAILD.getValue() == careerCorrelationCfgDb.getIsValid()) throwExp(careerCorrelationCfg);
            else {
                careerCorrelationCfgDbIsExist.setIsDeleted(CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue());
                careerCorrelationCfgDbIsExist.setSystemSyncStatus(MesExtEnumUtil.IF_SYNC_STATUS.NO_SYNC.getValue());
                ConvertBean.serviceModelUpdate(careerCorrelationCfgDbIsExist, careerCorrelationCfg.getModifyUser());
                careerCorrelationCfgRepository.save(careerCorrelationCfgDbIsExist);
            }
        }

        careerCorrelationCfgDb.setCareerCode(careerCorrelationCfg.getCareerCode());
        careerCorrelationCfgDb.setCategoryCode(careerCorrelationCfg.getCategoryCode());
        careerCorrelationCfgDb.setWorkCenterCode(careerCorrelationCfg.getWorkCenterCode());
        careerCorrelationCfgDb.setDataDimension(careerCorrelationCfg.getDataDimension());
        careerCorrelationCfgDb.setDataType(careerCorrelationCfg.getDataType());
        careerCorrelationCfgDb.setDataKey(careerCorrelationCfg.getDataKey());
        careerCorrelationCfgDb.setCfgValue(careerCorrelationCfg.getCfgValue());
        careerCorrelationCfgDb.setSystemSyncStatus(MesExtEnumUtil.IF_SYNC_STATUS.NO_SYNC.getValue());
        careerCorrelationCfgDb.setIsValid(CommonEnumUtil.IS_VAILD.VAILD.getValue());
        ConvertBean.serviceModelUpdate(careerCorrelationCfgDb, careerCorrelationCfg.getModifyUser());
        return careerCorrelationCfgRepository.save(careerCorrelationCfgDb);
    }

    @Override
    public void updateCareerCorrelationCfgValidById(String idStr, Integer status, String userName) {
        if (status != CommonEnumUtil.IS_VAILD.INVAILD.getValue() && status != CommonEnumUtil.IS_VAILD.VAILD.getValue()) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                    .setErrorDetail("启用，禁用枚举状态值【%s】未被定义", status)
                    .build();
        }
        MesCareerCorrelationCfg careerCorrelationCfgDb = careerCorrelationCfgRepository.getById(Long.parseLong(idStr));
        if (null == careerCorrelationCfgDb)
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_NOT_EXIT.getCode())
                    .setErrorDetail("事业别配置ID[%s]对应的记录不存在", idStr)
                    .build();
        careerCorrelationCfgDb.setIsValid(status);
        careerCorrelationCfgDb.setSystemSyncStatus(MesExtEnumUtil.IF_SYNC_STATUS.NO_SYNC.getValue());
        ConvertBean.serviceModelUpdate(careerCorrelationCfgDb, userName);
        careerCorrelationCfgRepository.save(careerCorrelationCfgDb);
    }

    @Override
    public void deleteCareerCorrelationCfgById(String idStr, String userName) {
        MesCareerCorrelationCfg careerCorrelationCfgDb = careerCorrelationCfgRepository.getById(Long.parseLong(idStr));
        if (null == careerCorrelationCfgDb)
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_NOT_EXIT.getCode())
                    .setErrorDetail("事业别配置ID[%s]对应的记录不存在", idStr)
                    .build();
        careerCorrelationCfgDb.setIsDeleted(CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue());
        careerCorrelationCfgDb.setSystemSyncStatus(MesExtEnumUtil.IF_SYNC_STATUS.NO_SYNC.getValue());
        ConvertBean.serviceModelUpdate(careerCorrelationCfgDb, userName);
        careerCorrelationCfgRepository.save(careerCorrelationCfgDb);
    }

    @Override
    public List<MesCareerCorrelationCfg> getCareerCorrelationCfgListOnlyByDataType(String organizeCode, String dataType, String dataKeyStart, String dataKeyEnd) {
        DdlPackBean packBean = DdlPackBean.getDdlPackBean(organizeCode);
        DdlPreparedPack.getStringEqualPack(dataType, MesExtConstWords.DATA_TYPE, packBean);
        DdlPreparedPack.timeBuilder(dataKeyStart, dataKeyEnd, MesExtConstWords.DATA_KEY, packBean, false);
        return careerCorrelationCfgRepository.findByHqlWhere(packBean);
    }

    @Override
    public List<MesCareerCorrelationCfg> getCareerCorrelationCfgList(String organizeCode, String dataDimension, String dataType, String dataKeyStart, String dataKeyEnd) {
        DdlPackBean packBean = DdlPackBean.getDdlPackBean(organizeCode);
        DdlPreparedPack.getStringEqualPack(dataDimension, MesExtConstWords.DATA_DIMENSION, packBean);
        DdlPreparedPack.getStringEqualPack(dataType, MesExtConstWords.DATA_TYPE, packBean);
        DdlPreparedPack.timeBuilder(dataKeyStart, dataKeyEnd, MesExtConstWords.DATA_KEY, packBean, false);
        return careerCorrelationCfgRepository.findByHqlWhere(packBean);
    }

    @Override
    public List<MesCareerCorrelationCfg> getCareerCorrelationCfgListByCategoryCode(String organizeCode, String dataDimension, String dataType, String categoryCode) {
        DdlPackBean packBean = DdlPackBean.getDdlPackBean(organizeCode);
        DdlPreparedPack.getStringEqualPack(dataDimension, MesExtConstWords.DATA_DIMENSION, packBean);
        DdlPreparedPack.getStringEqualPack(dataType, MesExtConstWords.DATA_TYPE, packBean);
        DdlPreparedPack.getStringEqualPack(categoryCode, MesExtConstWords.CATEGORY_CODE, packBean);
        return careerCorrelationCfgRepository.findByHqlWhere(packBean);
    }

}
