package cn.estsh.i3plus.core.apiservice.serviceimpl.busi;

import cn.estsh.i3plus.core.api.iservice.busi.ISysDictionaryService;
import cn.estsh.i3plus.platform.common.tool.StringTool;
import cn.estsh.i3plus.pojo.base.bean.BaseConstWords;
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.platform.bean.SysDictionary;
import cn.estsh.i3plus.pojo.platform.repository.SysDictionaryRepository;
import cn.estsh.i3plus.pojo.platform.sqlpack.CoreHqlPack;
import cn.estsh.impp.framework.boot.exception.ImppExceptionBuilder;
import cn.estsh.impp.framework.boot.exception.ImppExceptionEnum;
import cn.estsh.impp.framework.boot.util.ValidatorBean;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * @Description : 字典服务接口实现
 * @Reference :
 * @Author : yunhao
 * @Date : 2018-10-28 23:44
 * @Modify :
 **/
@Service
public class SysDictionaryService implements ISysDictionaryService {
    public static final Logger LOGGER = LoggerFactory.getLogger(SysDictionaryService.class);

    @Autowired
    private SysDictionaryRepository sysDictionaryRDao;

    @Override
    @ApiOperation(value = "添加字典")
    public void insertSysDictionary(SysDictionary sysDictionary) {
        long repeatCodeCount = sysDictionaryRDao.findByPropertyCount(new String[]{"dictionaryCode", "dictionarySoftType"},
                new Object[]{sysDictionary.getDictionaryCode(), sysDictionary.getDictionarySoftType()});
        long repeatValueCount = sysDictionaryRDao.findByPropertyCount(new String[]{"parentId", "dictionaryValue", "dictionarySoftType"},
                new Object[]{sysDictionary.getParentId(), sysDictionary.getDictionaryValue(), sysDictionary.getDictionarySoftType()});
        if (repeatCodeCount > 0 || repeatValueCount > 0) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.CORE.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_EXIT.getCode())
                    .setErrorDetail("字典代码或字典值已存在")
                    .setErrorSolution("请重新输入字典代码或字典值")
                    .build();
        }

        // 查询父级字典名称
        if (sysDictionary.getParentId() != null && sysDictionary.getParentId() > 0) {
            LOGGER.info("字典 SYS_DICTIONARY parentId:{}", sysDictionary.getParentId());
            SysDictionary parentSysDictionary = sysDictionaryRDao.getById(sysDictionary.getParentId());
            ValidatorBean.checkNotNull(parentSysDictionary);

            sysDictionary.setParentNameRdd(parentSysDictionary.getName());
            sysDictionary.setParentCodeRdd(parentSysDictionary.getDictionaryCode());
        } else {
            sysDictionary.setParentId(CommonEnumUtil.PARENT.DEFAULT.getValue());
        }

        LOGGER.info("字典 SYS_DICTIONARY sysDictionary:{}", sysDictionary);
        sysDictionaryRDao.insert(sysDictionary);
    }

    @Override
    @ApiOperation(value = "根据id删除字典")
    public void deleteSysDictionaryById(Long id) {
        LOGGER.info("字典 SYS_DICTIONARY id:{}", id);
        sysDictionaryRDao.deleteById(id);
    }

    @Override
    @ApiOperation(value = "修改字典")
    public void updateSysDictionary(SysDictionary sysDictionary) {
        // 校验唯一
        String hqlPack = CoreHqlPack.packHqlSysDictionaryCode(sysDictionary);
        long  repeatCodeCount = sysDictionaryRDao.findByHqlWhereCount(hqlPack);
        hqlPack = CoreHqlPack.packHqlSysDictionaryValue(sysDictionary);
        long  repeatValueCount = sysDictionaryRDao.findByHqlWhereCount(hqlPack);
        if (repeatCodeCount > 0 || repeatValueCount > 0) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.CORE.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_EXIT.getCode())
                    .setErrorDetail("字典代码或字典值已存在")
                    .setErrorSolution("请重新输入字典代码或字典值")
                    .build();
        }

        // 数据反填
        SysDictionary newSysDict = sysDictionaryRDao.getById(sysDictionary.getId());
        newSysDict.setName(sysDictionary.getName());
        newSysDict.setDictionarySoftType(sysDictionary.getDictionarySoftType());
        newSysDict.setDictionaryCode(sysDictionary.getDictionaryCode());
        newSysDict.setParentId(sysDictionary.getParentId());
        newSysDict.setDictionarySort(sysDictionary.getDictionarySort());
        newSysDict.setDictionaryValueType(sysDictionary.getDictionaryValueType());
        newSysDict.setDictionaryValue(sysDictionary.getDictionaryValue());
        newSysDict.setDictionaryDescription(sysDictionary.getDictionaryDescription());

        // 查询父级字典名称
        if (sysDictionary.getParentId() != null && sysDictionary.getParentId() > 0) {
            LOGGER.info("字典 SYS_DICTIONARY parentId:{}", sysDictionary.getParentId());
            SysDictionary parentSysDictionary = sysDictionaryRDao.getById(sysDictionary.getParentId());
            ValidatorBean.checkNotNull(parentSysDictionary);

            newSysDict.setParentNameRdd(parentSysDictionary.getName());
            newSysDict.setParentCodeRdd(parentSysDictionary.getDictionaryCode());
        }

        LOGGER.info("字典 SYS_DICTIONARY sysDictionary:{}", newSysDict);
        sysDictionaryRDao.update(newSysDict);
    }

    @Override
    @ApiOperation(value = "查询所有字典信息")
    public List<SysDictionary> listSysDictionary() {
        LOGGER.info("字典 SYS_DICTIONARY list");
        return sysDictionaryRDao.list();
    }

    @Override
    @ApiOperation(value = "根据id查询字典信息")
    public SysDictionary getSysDictionaryById(Long id) {
        LOGGER.info("字典 SYS_DICTIONARY id:{}", id);
        return sysDictionaryRDao.getById(id);
    }

    @Override
    @ApiOperation(value = "根据父级代码查询字典项信息")
    public List<SysDictionary> findSysDictionaryBySoftTypeAndParentCode(Integer softType, String parentCode) {
        LOGGER.info("字典 SYS_DICTIONARY parentCode:{}", parentCode);
        return sysDictionaryRDao.findByProperty(new String[]{"softType", "parentCodeRdd"}, new Object[]{softType, parentCode});
    }

    @Override
    @ApiOperation(value = "字典复杂查询，分页，排序", notes = "默认查询非顶级字典")
    public ListPager querySysDictionaryByPager(SysDictionary sysDictionary, Pager pager) {
        sysDictionary = sysDictionary == null ? new SysDictionary() : sysDictionary;

        String hqlPack = CoreHqlPack.packHqlSysDictionary(sysDictionary);
        pager = PagerHelper.getPager(pager, sysDictionaryRDao.findByHqlWhereCount(hqlPack));
        return new ListPager(sysDictionaryRDao.findByHqlWherePage(hqlPack + sysDictionary.orderBy(), pager), pager);
    }

    @Override
    @ApiOperation(value = "查询顶级字典")
    public List<SysDictionary> findSysDictionaryByTop() {
        LOGGER.info("字典 SYS_DICTIONARY parentId:{}", CommonEnumUtil.PARENT.DEFAULT.getValue());
        return sysDictionaryRDao.findByProperty("parentId", (long) CommonEnumUtil.PARENT.DEFAULT.getValue());
    }

    @Override
    @ApiOperation(value = "批量删除字典")
    public void deleteSysDictionaryByIds(Long[] ids) {
        if (sysDictionaryRDao.findByHqlWhereCount(CoreHqlPack.packHqlSysDictionaryByIdsAndIsDefault(ids)) > 0) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.CORE.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_EXIT.getCode())
                    .setErrorDetail("默认字典不可删除")
                    .setErrorSolution("请重新选择")
                    .build();
        }

        LOGGER.info("字典 SYS_DICTIONARY ids:{}", ids);
        sysDictionaryRDao.deleteByIds(ids);
    }

    @Override
    @ApiOperation(value = "检出文件名称是否符合系统规范")
    public boolean checkFileName(String fileName) {
        List<SysDictionary> list = findSysDictionaryBySoftTypeAndParentCode(CommonEnumUtil.SOFT_TYPE.CORE.getValue(),
                                        BaseConstWords.DICTIONARY_FILE_TYPE);

        if (list != null && list.size() > 0) {
            String suffix = StringTool.getStringFileSuffix(fileName, true);

            for (SysDictionary dictionary : list) {
                if (suffix.toUpperCase().equals(dictionary.getDictionaryValue().toUpperCase())) {
                    return true;
                }
            }
        }
        return false;
    }

    @Override
    @ApiOperation(value = "根据父节点 以及当前节点CODE 获取字典信息")
    public SysDictionary getSysDictionaryByParentCodeAndCode(String parentCode, String code) {
        return sysDictionaryRDao.getByProperty(new String[]{"parentCodeRdd", "dictionaryCode"},
                new Object[]{parentCode, code});
    }

    @Override
    @ApiOperation(value = "设置默认字典项", notes = "根据id设置默认字典项")
    public void updateSysDictionaryDefaultById(Long id) {
        SysDictionary sysDictionary = sysDictionaryRDao.getById(id);
        sysDictionaryRDao.updateByProperties("parentId", sysDictionary.getParentId(),
                "isDefault", CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue());

        sysDictionaryRDao.updateByProperties("id", id,
                "isDefault", CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue());
    }

    @Override
    @ApiOperation(value = "根据父节点 以及当前节点值 获取字典信息")
    public SysDictionary getSysDictionaryByParentCodeAndValue(String parentCode, String value) {
        return sysDictionaryRDao.getByProperty(new String[]{"parentCodeRdd", "dictionaryValue"},
                new Object[]{parentCode, value});
    }

    @Override
    @ApiOperation(value = "根据父节点 以及当前节点名称 获取字典信息")
    public SysDictionary getSysDictionaryByParentCodeAndName(String parentCode, String name) {
        return sysDictionaryRDao.getByProperty(new String[]{"parentCodeRdd", "name"},
                new Object[]{parentCode, name});
    }

    @Override
    @ApiOperation(value = "根据模块查询顶级字典")
    public List<SysDictionary> findSysDictionaryByTopBySoftType(Integer softType) {
        return sysDictionaryRDao.findByProperty(new String[]{"parentId", "dictionarySoftType"},
                        new Object[]{(long) CommonEnumUtil.PARENT.DEFAULT.getValue(), softType});
    }
}
