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

import cn.estsh.i3plus.ext.mes.api.base.bu.IMesTravelMenuFieldConfigService;
import cn.estsh.i3plus.ext.mes.pojo.bean.MesTravelMenuFieldConfig;
import cn.estsh.i3plus.ext.mes.pojo.repository.MesTravelMenuFieldConfigRepository;
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 java.util.List;
import java.util.Map;
import java.util.StringJoiner;
import java.util.function.Function;
import java.util.stream.Collectors;

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

    @Autowired
    private MesTravelMenuFieldConfigRepository travelMenuFieldConfigRepository;

    @Override
    public ListPager<MesTravelMenuFieldConfig> queryTravelMenuFieldConfigByPager(MesTravelMenuFieldConfig travelMenuFieldConfig, Pager pager) {
        DdlPackBean hqlPack = MesExtHqlPack.getTravelMenuFieldConfigSelectQuery(travelMenuFieldConfig);
        pager = PagerHelper.getPager(pager, travelMenuFieldConfigRepository.findByHqlWhereCount(hqlPack));
        hqlPack.setOrderByStr(travelMenuFieldConfig.orderBy());
        List<MesTravelMenuFieldConfig> travelMenuFieldConfigList = travelMenuFieldConfigRepository.findByHqlWherePage(hqlPack, pager);
        return new ListPager(travelMenuFieldConfigList, pager);
    }

    @Override
    public MesTravelMenuFieldConfig insertTravelMenuFieldConfig(MesTravelMenuFieldConfig travelMenuFieldConfig) {
        if (travelMenuFieldConfigRepository.isExitByProperty(
                new String[]{MesExtConstWords.ORGANIZE_CODE, MesExtConstWords.MENU_CODE, MesExtConstWords.FIELD_CODE, MesExtConstWords.IS_DELETED,MesExtConstWords.IS_VALID},
                new Object[]{AuthUtil.getOrganize().getOrganizeCode(), travelMenuFieldConfig.getMenuCode(), travelMenuFieldConfig.getFieldCode(), 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(), MesExtEnumUtil.FIELD_MENU_TYPE.valueOfDescription(travelMenuFieldConfig.getMenuCode()), travelMenuFieldConfig.getFieldCode())
                    .setErrorSolution("请重新操作！")
                    .build();
        }

        ConvertBean.serviceModelInitialize(travelMenuFieldConfig, travelMenuFieldConfig.getCreateUser());
        return travelMenuFieldConfigRepository.insert(travelMenuFieldConfig);
    }

    @Override
    public MesTravelMenuFieldConfig updateTravelMenuFieldConfig(MesTravelMenuFieldConfig travelMenuFieldConfig) {
        MesTravelMenuFieldConfig existed = travelMenuFieldConfigRepository.getById(travelMenuFieldConfig.getId());
        if (existed == null) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_NOT_EXIT.getCode())
                    .setErrorDetail("履历菜单字段配置记录不存在")
                    .build();
        }

        //唯一性校验
        MesTravelMenuFieldConfig travelMenuFieldConfigDb = travelMenuFieldConfigRepository.getByProperty(new String[]{MesExtConstWords.ORGANIZE_CODE, MesExtConstWords.MENU_CODE, MesExtConstWords.FIELD_CODE, MesExtConstWords.IS_DELETED,MesExtConstWords.IS_VALID},
                new Object[]{AuthUtil.getOrganize().getOrganizeCode(), travelMenuFieldConfig.getMenuCode(), travelMenuFieldConfig.getFieldCode(), CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue()});

        if (travelMenuFieldConfigDb != null && !travelMenuFieldConfigDb.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(), MesExtEnumUtil.FIELD_MENU_TYPE.valueOfDescription(travelMenuFieldConfig.getMenuCode()), travelMenuFieldConfig.getFieldCode())
                    .setErrorSolution("请重新操作！")
                    .build();
        }

        existed.setMenuCode(travelMenuFieldConfig.getMenuCode());
        existed.setFieldCode(travelMenuFieldConfig.getFieldCode());
        existed.setFieldName(travelMenuFieldConfig.getFieldName());
        existed.setFieldEnumClazz(travelMenuFieldConfig.getFieldEnumClazz());
        ConvertBean.serviceModelUpdate(existed, travelMenuFieldConfig.getModifyUser());
        return travelMenuFieldConfigRepository.save(existed);
    }

    @Override
    public int updateTravelMenuFieldConfigValidById(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();
        }
        MesTravelMenuFieldConfig travelMenuFieldConfigDb = travelMenuFieldConfigRepository.getById(id);

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

        if(status == CommonEnumUtil.IS_VAILD.VAILD.getValue()){
            if (travelMenuFieldConfigRepository.isExitByProperty(
                    new String[]{"organizeCode", "menuCode", "fieldCode", "isDeleted", "isValid"},
                    new Object[]{AuthUtil.getOrganize().getOrganizeCode(), travelMenuFieldConfigDb.getMenuCode(), travelMenuFieldConfigDb.getFieldCode(), CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue()})) {
                throw ImppExceptionBuilder.newInstance()
                        .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                        .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_EXIT.getCode())
                        .setErrorDetail("工厂代码为【%s】,菜单代码为【%s】，字段代码为【%s】的配置项已存在",
                                AuthUtil.getOrganize().getOrganizeCode(), MesExtEnumUtil.FIELD_MENU_TYPE.valueOfDescription(travelMenuFieldConfigDb.getMenuCode()), travelMenuFieldConfigDb.getFieldCode())
                        .setErrorSolution("请重新操作！")
                        .build();
            }
        }

        return travelMenuFieldConfigRepository.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 List<MesTravelMenuFieldConfig> getTravelMenuFieldConfigList(String organizeCode, Integer menuCode) {
        DdlPackBean packBean = DdlPackBean.getDdlPackBean(organizeCode);
        DdlPreparedPack.getNumEqualPack(menuCode, MesExtConstWords.MENU_CODE, packBean);
        return travelMenuFieldConfigRepository.findByHqlWhere(packBean);
    }

    @Override
    public Map<String, MesTravelMenuFieldConfig> getTravelMenuFieldConfig(String organizeCode) {
        List<MesTravelMenuFieldConfig> travelMenuFieldConfigList = travelMenuFieldConfigRepository.findByProperty(
                new String[]{MesExtConstWords.ORGANIZE_CODE, MesExtConstWords.IS_DELETED, MesExtConstWords.IS_VALID},
                new Object[]{organizeCode, CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), CommonEnumUtil.IS_VAILD.VAILD.getValue()});

        if(!CollectionUtils.isEmpty(travelMenuFieldConfigList)){
            return travelMenuFieldConfigList.stream().collect(Collectors.toMap(o -> new StringJoiner(MesExtConstWords.AND).add(o.getMenuCode().toString()).add(o.getFieldCode()).toString(), Function.identity()));
        }
        return null;
    }

}
