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

import cn.estsh.i3plus.core.api.iservice.busi.IPersonnelService;
import cn.estsh.i3plus.core.api.iservice.busi.ISysMenuService;
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.HqlPack;
import cn.estsh.i3plus.pojo.platform.bean.SessionUser;
import cn.estsh.i3plus.pojo.platform.bean.SysMenu;
import cn.estsh.i3plus.pojo.platform.repository.SysRefRoleMenuRepository;
import cn.estsh.i3plus.pojo.platform.repository.SysMenuRepository;
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.apache.commons.lang3.StringUtils;
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      : wei.peng
 * @Date        : 2018-10-22 15:18:14.969
 * @Modify      :
 **/
@Service
public class SysMenuService implements ISysMenuService {

    public static final Logger LOGGER = LoggerFactory.getLogger(SysMenuService.class);

    @Autowired
    private SysMenuRepository sysMenuRDao;

    @Autowired
    private CoreTreeService coreTreeService;

    @Autowired
    private SysRefRoleMenuRepository refRoleMenuRDao;

    @Autowired
    private IPersonnelService personnelService;

    @Override
    @ApiOperation(value = "更新菜单信息")
    public void updateSysMenu(SysMenu menu) {
        LOGGER.info("系统功能 SYS_MENU :{}", menu);

        // 唯一校验 CODE 相同 ID 不同 则视为相同
        StringBuffer countWhere = new StringBuffer();

        HqlPack.getStringEqualPack( menu.getMenuCode(),"menuCode",countWhere);
        HqlPack.getNumNOEqualPack(menu.getId().toString(),"id",countWhere);


        int count = sysMenuRDao.findByHqlWhereCount(countWhere.toString());
        if(count > 0){
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.CORE.getCode())
                    .setErrorCode(ImppExceptionEnum.IO_EXCEPTION.getCode())
                    .setErrorDetail("权限代码已存在")
                    .setErrorSolution("请重新输入权限代码")
                    .build();
        }

        // 父节点检查
        coreTreeService.doValidatorSysMenuParentId(menu);

        if (menu.getParentId() != null  && menu.getParentId() > 0) {
            SysMenu parent = sysMenuRDao.getById(menu.getParentId());
            ValidatorBean.checkNotNull(parent,"上级权限信息不存在");
            menu.setParentNameRdd(parent.getName());
        }

        sysMenuRDao.update(menu);
        // 更新冗余信息
        personnelService.refreshMenuRdd(menu.getId());
        personnelService.refreshUpdateMenuRdd(menu.getId());
    }

    @Override
    @ApiOperation(value = "更新菜单信息",notes = "根据ID 更新菜单状态信息")
    public void updateSysMenuStatus(Long id, int status, SessionUser user) {
        LOGGER.info("系统功能 SYS_MENU  id:{} status:{} user:{}", id,status,user);
        SysMenu menu = sysMenuRDao.getById(id);
        if(menu != null){
            menu.setMenuStatus(status);
            menu.setModifyUser(user.getUserName());
            sysMenuRDao.update(menu);
        }else {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.IMPP.getCode())
                    .setErrorCode(ImppExceptionEnum.BUSINESS_EXCEPTION_DATA_ERROR.getCode())
                    .setErrorDetail("数据不存在")
                    .setErrorSolution("请重新操作")
                    .build();
        }
    }

    @Override
    @ApiOperation(value = "更新菜单信息",notes = "根据ID 批量更新菜单状态信息")
    public void updateSysMenuStatusByIds(Long[] ids, int status, SessionUser user) {
        LOGGER.info("系统功能 SYS_MENU  ids:{}  status:{} user:{}", ids, status, user);
        StringBuffer where = new StringBuffer();

        HqlPack.getInPack(StringUtils.join( ids,","), "id", where);
        sysMenuRDao.updateByHqlWhere(where.toString(), "menuStatus", status);
    }

    @Override
    @ApiOperation(value = "删除菜单信息",notes = "根据ID 删除菜单信息")
    public void deleteSysMenuById(Long id) {
        LOGGER.info("系统功能 SYS_MENU Key:{}", id);
        long count = sysMenuRDao.findByPropertyCount("parentId",id);
        if(count >= 1){
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.IMPP.getCode())
                    .setErrorCode(ImppExceptionEnum.BUSINESS_EXCEPTION_DATA_ERROR.getCode())
                    .setErrorDetail("该数据有子集")
                    .setErrorSolution("请先删除子集在操作")
                    .build();

        }

        refRoleMenuRDao.deleteById(id);
        sysMenuRDao.deleteById(id);
    }

    @Override
    @ApiOperation(value = "删除菜单信息",notes = "根据ID 批量删除菜单信息")
    public void deleteSysMenuByIds(Long[] ids) {
        LOGGER.info("系统功能 SYS_MENU ids :{}", ids);
        long positionCount = sysMenuRDao.findByHqlWhereCount(CoreHqlPack.packHqlIds("parentId",ids));
        if (positionCount >= 1) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.CORE.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                    .setErrorDetail("存在相关系统功能信息无法删除！")
                    .setErrorSolution("请先删除子集信息在操作")
                    .build();
        }else {
            refRoleMenuRDao.deleteByPropertyIn("menuId",ids);
            sysMenuRDao.deleteByIds(ids);
        }
    }

    @Override
    @ApiOperation(value = "新增菜单信息")
    public SysMenu insertSysMenu(SysMenu sysMenu) {
        LOGGER.info("系统功能 SYS_MENU :{}", sysMenu);

        // 代码唯一校验
        long count = sysMenuRDao.findByPropertyCount("menuCode", sysMenu.getMenuCode());
        if(count <= 0){
            if (sysMenu.getParentId() != null  && sysMenu.getParentId() > 0) {
                SysMenu parent = sysMenuRDao.getById(sysMenu.getParentId());
                ValidatorBean.checkNotNull(parent,"上级权限信息不存在");
                sysMenu.setParentNameRdd(parent.getName());
            }
            return sysMenuRDao.insert(sysMenu);
        }else {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.CORE.getCode())
                    .setErrorCode(ImppExceptionEnum.IO_EXCEPTION.getCode())
                    .setErrorDetail("功能代码已存在")
                    .setErrorSolution("请重新输入功能代码")
                    .build();
        }
    }

    @Override
    @ApiOperation(value = "查询菜单信息",notes = "查询所有菜单信息")
    public List<SysMenu> findSysMenuAll() {
        LOGGER.info("系统功能 SYS_MENU find All");
        return sysMenuRDao.findByProperty(new String[]{"menuStatus"},new Object[]{CommonEnumUtil.DATA_STATUS.ENABLE.getValue()});
    }

    @Override
    @ApiOperation(value = "查询菜单信息",notes = "根据父节点 ID 查询所有菜单信息")
    public List<SysMenu> findSysMenuByParentId(Long parentId) {
        return sysMenuRDao.findByProperty(new String[]{"parentId"},new Object[]{parentId});
    }

    @Override
    @ApiOperation(value = "查询菜单信息",notes = "根据ID查询菜单信息")
    public SysMenu getSysMenuById(Long id) {
        LOGGER.info("系统功能 SYS_MENU find id:{}", id);
        return sysMenuRDao.getOne(id);
    }

    @Override
    @ApiOperation(value = "查询菜单信息",notes = "查询菜单信息(分页、组合)")
    public ListPager<SysMenu> querySysMenu(SysMenu menu, Pager pager) {
        LOGGER.info("系统权限 SysMenu find menu :{} page :{}", menu, pager);

        if (menu == null) {
            //不传入实体对象，查询所有
            int count = sysMenuRDao.listCount();
            pager = PagerHelper.getPager(pager, count);
            return new ListPager(sysMenuRDao.listPager(pager), pager);
        } else {
            //生成hql查询语句
            String hqlPack = CoreHqlPack.packHqlSysMenu(menu);
            pager = PagerHelper.getPager(pager, sysMenuRDao.findByHqlWhereCount(hqlPack));
            return new ListPager(sysMenuRDao.findByHqlWherePage(hqlPack + menu.orderBy(), pager), pager);
        }
    }
}
