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

import cn.estsh.i3plus.ext.mes.api.base.bu.IBusiConfigService;
import cn.estsh.i3plus.ext.mes.pojo.bean.MesBusiConfig;
import cn.estsh.i3plus.ext.mes.pojo.repository.MesBusiConfigRepository;
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.TimeTool;
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.impp.framework.boot.auth.AuthUtil;
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.*;
import java.util.stream.Collectors;

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

    @Autowired
    private MesBusiConfigRepository busiConfigRepository;

    @Override
    public ListPager<MesBusiConfig> queryBusiConfigByPager(MesBusiConfig busiConfig, Pager pager) {
        DdlPackBean hqlPack = MesExtHqlPack.getBusiConfigSelectQuery(busiConfig);
        pager = PagerHelper.getPager(pager, busiConfigRepository.findByHqlWhereCount(hqlPack));
        hqlPack.setOrderByStr(busiConfig.orderBy());
        List<MesBusiConfig> busiConfigList = busiConfigRepository.findByHqlWherePage(hqlPack, pager);
        return new ListPager(busiConfigList, pager);
    }

    @Override
    public MesBusiConfig insertBusiConfig(MesBusiConfig busiConfig) {
//        DdlPackBean packBean = DdlPackBean.getDdlPackBean(busiConfig.getOrganizeCode());
//        DdlPreparedPack.getStringLikerPack(busiConfig.getCfgCode(), MesExtConstWords.CFG_CODE, packBean);
//        MesBusiConfig busiConfigDb = busiConfigRepository.getByProperty(packBean);
//        if(busiConfigDb != null){
//            throw ImppExceptionBuilder.newInstance()
//                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
//                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_NOT_EXIT.getCode())
//                    .setErrorDetail("业务配置代码[%s]记录已存在", busiConfig.getCfgCode())
//                    .build();
//        }

        if (busiConfigRepository.isExitByProperty(
                new String[]{"organizeCode", "cfgCode", "cfgValue", "isDeleted", "isValid"},
                new Object[]{AuthUtil.getOrganize().getOrganizeCode(), busiConfig.getCfgCode(), busiConfig.getCfgValue(), CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue()})) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                    .setErrorCode(cn.estsh.impp.framework.boot.exception.ImppExceptionEnum.VARIFY_EXCEPTION_DATA_EXIT.getCode())
                    .setErrorDetail("工厂代码为【%s】,配置代码为【%s】，配置值为【%s】的配置项已存在",
                            AuthUtil.getOrganize().getOrganizeCode(), busiConfig.getCfgCode(), busiConfig.getCfgValue())
                    .setErrorSolution("请重新操作！")
                    .build();
        }

        if (busiConfigRepository.isExitByProperty(
                new String[]{"organizeCode", "cfgCode", "cfgValueSeq", "isDeleted", "isValid"},
                new Object[]{AuthUtil.getOrganize().getOrganizeCode(), busiConfig.getCfgCode(), busiConfig.getCfgValueSeq(), CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue()})) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                    .setErrorCode(cn.estsh.impp.framework.boot.exception.ImppExceptionEnum.VARIFY_EXCEPTION_DATA_EXIT.getCode())
                    .setErrorDetail("工厂代码为【%s】,配置代码为【%s】，配置值序号为【%s】的配置项已存在",
                            AuthUtil.getOrganize().getOrganizeCode(), busiConfig.getCfgCode(), busiConfig.getCfgValueSeq())
                    .setErrorSolution("请重新操作！")
                    .build();
        }

        ConvertBean.serviceModelInitialize(busiConfig, busiConfig.getCreateUser());
        return busiConfigRepository.insert(busiConfig);
    }

    @Override
    public MesBusiConfig updateBusiConfig(MesBusiConfig busiConfig) {
        MesBusiConfig existed = busiConfigRepository.getById(busiConfig.getId());
        if (existed == null) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_NOT_EXIT.getCode())
                    .setErrorDetail("业务配置[%s]记录不存在", busiConfig.getCfgCode())
                    .build();
        }

        //唯一性校验
        MesBusiConfig busiConfigDb = busiConfigRepository.getByProperty(new String[]{"organizeCode", "cfgCode", "cfgValue", "isDeleted", "isValid"},
                new Object[]{AuthUtil.getOrganize().getOrganizeCode(), busiConfig.getCfgCode(), busiConfig.getCfgValue(), CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue()});

        if (busiConfigDb != null && !busiConfigDb.getId().equals(existed.getId())) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                    .setErrorCode(cn.estsh.impp.framework.boot.exception.ImppExceptionEnum.VARIFY_EXCEPTION_DATA_EXIT.getCode())
                    .setErrorDetail("工厂代码为【%s】,配置代码为【%s】，配置值为【%s】的配置项已存在",
                            AuthUtil.getOrganize().getOrganizeCode(), busiConfigDb.getCfgCode(), busiConfigDb.getCfgValue())
                    .setErrorSolution("请重新操作！")
                    .build();
        }

        MesBusiConfig busiConfigDbBySeq = busiConfigRepository.getByProperty(new String[]{"organizeCode", "cfgCode", "cfgValueSeq", "isDeleted", "isValid"},
                new Object[]{AuthUtil.getOrganize().getOrganizeCode(), busiConfig.getCfgCode(), busiConfig.getCfgValueSeq(), CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue()});

        if(busiConfigDbBySeq != null && !busiConfigDbBySeq.getId().equals(existed.getId())){
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                    .setErrorCode(cn.estsh.impp.framework.boot.exception.ImppExceptionEnum.VARIFY_EXCEPTION_DATA_EXIT.getCode())
                    .setErrorDetail("工厂代码为【%s】,配置代码为【%s】，配置值序号为【%s】的配置项已存在",
                            AuthUtil.getOrganize().getOrganizeCode(), busiConfig.getCfgCode(), busiConfig.getCfgValueSeq())
                    .setErrorSolution("请重新操作！")
                    .build();
        }

//        if ((busiConfigRepository.isExitByProperty(
//                new String[]{"organizeCode", "cfgCode", "cfgValueSeq" , "isDeleted", "isValid"},
//                new Object[]{AuthUtil.getOrganize().getOrganizeCode(), busiConfig.getCfgCode(), busiConfig.getCfgValueSeq(), CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue()})) && (busiConfigDb.getCfgValue().equals(busiConfig.getCfgValue()))) {
//            throw ImppExceptionBuilder.newInstance()
//                    .setSystemID(CommonEnumUtil.SOFT_TYPE.WMS.getCode())
//                    .setErrorCode(cn.estsh.impp.framework.boot.exception.ImppExceptionEnum.VARIFY_EXCEPTION_DATA_EXIT.getCode())
//                    .setErrorDetail("工厂代码为【%s】,配置代码为【%s】，配置值序号为【%s】的配置项已存在",
//                            AuthUtil.getOrganize().getOrganizeCode(), busiConfig.getCfgCode(), busiConfig.getCfgValueSeq())
//                    .setErrorSolution("请重新操作！")
//                    .build();
//        }

        existed.setCfgValueSeq(busiConfig.getCfgValueSeq());
        existed.setCfgName(busiConfig.getCfgName());
        existed.setCfgValue(busiConfig.getCfgValue());
        ConvertBean.serviceModelUpdate(existed, busiConfig.getModifyUser());
        return busiConfigRepository.save(existed);
    }

    @Override
    public int updateBusiConfigValidById(Long id, Integer status, String organizeCode, 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();
        }
        MesBusiConfig busiConfigDb = busiConfigRepository.getById(id);

        if (busiConfigDb == null || CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue() == busiConfigDb.getIsDeleted()) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_NOT_EXIT.getCode())
                    .setErrorDetail("ID[%s]记录不存在", id)
                    .build();
        }

        DdlPackBean packBean = DdlPackBean.getDdlPackBean(organizeCode);
        DdlPreparedPack.getStringEqualPack(busiConfigDb.getCfgCode(),MesExtConstWords.CFG_CODE,packBean);
        MesBusiConfig busiConfig = busiConfigRepository.getByProperty(packBean);

        if(busiConfig != null && status == MesExtEnumUtil.IS_VAILD.VAILD.getValue()){
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_NOT_EXIT.getCode())
                    .setErrorDetail("配置代码存在", id)
                    .build();
        }

        return busiConfigRepository.updateByProperties(new String[]{MesExtConstWords.ID}, new Object[]{id},
                new String[]{MesExtConstWords.IS_VALID, MesExtConstWords.MODIFY_USER, MesExtConstWords.MODIFY_DATE_TIME},
                new Object[]{status, userName, TimeTool.getNowTime(true)});
    }

    @Override
    public MesBusiConfig getBusiConfigByCfgCode(String organizeCode, String cfgCode) {
        if (StringUtils.isEmpty(organizeCode) || StringUtils.isEmpty(cfgCode)) return null;
        return busiConfigRepository.getByProperty(
                new String[]{MesExtConstWords.ORGANIZE_CODE, MesExtConstWords.IS_DELETED, MesExtConstWords.IS_VALID, MesExtConstWords.CFG_CODE},
                new Object[]{organizeCode, CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), CommonEnumUtil.IS_VAILD.VAILD.getValue(), cfgCode});
    }

    @Override
    public Map<String, String> getConfigMap(String organizeCode, String cfgCode) {
        List<MesBusiConfig> busiConfigList = busiConfigRepository.findByProperty(
                new String[]{MesExtConstWords.ORGANIZE_CODE, MesExtConstWords.IS_DELETED, MesExtConstWords.IS_VALID, MesExtConstWords.CFG_CODE},
                new Object[]{organizeCode, CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), CommonEnumUtil.IS_VAILD.VAILD.getValue(), cfgCode});
        busiConfigList = CollectionUtils.isEmpty(busiConfigList) ? null :
                busiConfigList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getCfgValue()) && !StringUtils.isEmpty(o.getCfgValueSeq()))).collect(Collectors.collectingAndThen(
                        Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(MesBusiConfig::getCfgValueSeq))), ArrayList::new)
                );
        return CollectionUtils.isEmpty(busiConfigList) ? null :
                busiConfigList.stream().filter(o -> null != o).collect(Collectors.toMap(MesBusiConfig::getCfgValueSeq, MesBusiConfig::getCfgValue));
    }

    @Override
    public List<MesBusiConfig> getConfigListSortSeq(String organizeCode, String cfgCode) {
        List<MesBusiConfig> busiConfigList = busiConfigRepository.findByProperty(
                new String[]{MesExtConstWords.ORGANIZE_CODE, MesExtConstWords.IS_DELETED, MesExtConstWords.IS_VALID, MesExtConstWords.CFG_CODE},
                new Object[]{organizeCode, CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), CommonEnumUtil.IS_VAILD.VAILD.getValue(), cfgCode});
        return CollectionUtils.isEmpty(busiConfigList) ? null :
                busiConfigList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getCfgValueSeq()) && !StringUtils.isEmpty(o.getCfgValue()))).sorted(Comparator.comparing(MesBusiConfig::getCfgValueSeq)).collect(Collectors.toList());
    }

}
