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.ISysDepartmentService;
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.SysDepartment;
import cn.estsh.i3plus.pojo.platform.bean.SysOrganize;
import cn.estsh.i3plus.pojo.platform.repository.SysDepartmentRepository;
import cn.estsh.i3plus.pojo.platform.repository.SysOrganizeRepository;
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-24 20:47
 * @Modify :
 **/
@Service
public class SysDepartmentService implements ISysDepartmentService {

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

    @Autowired
    private SysDepartmentRepository departmentRDao;

    @Autowired
    private SysOrganizeRepository organizeRDao;

    @Autowired
    private CoreTreeService coreTreeService;

    @Autowired
    private IPersonnelService personnelService;

    @Override
    @ApiOperation(value = "新增部门信息")
    public SysDepartment insertSysDepartment(SysDepartment department) {
        LOGGER.info("部门信息 SysDepartment department:{}", department);
        // 代码唯一校验
        long count = departmentRDao.findByPropertyCount("departmentCode", department.getDepartmentCode());
        if(count <= 0){

            //冗余父节点信息
            if (department.getParentId() != null  && department.getParentId() > 0) {
                LOGGER.info("部门信息 DEPARTMENT :{}", department.getParentId());
                SysDepartment parentPosition = departmentRDao.getById(department.getParentId());
                ValidatorBean.checkNotNull(parentPosition,"上级部门信息不存在");

                department.setParentNameRdd(parentPosition.getName());
            }

            LOGGER.info("组织信息 ORGANIZE :{}", department.getOrganizeId());
            SysOrganize organize = organizeRDao.getById(department.getOrganizeId());
            ValidatorBean.checkNotNull(organize);

            department.setOrganizeNameRdd(organize.getName());

            LOGGER.info("部门信息 DEPARTMENT {}",department);
            return departmentRDao.insert(department);
        } else {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.CORE.getCode())
                    .setErrorCode(ImppExceptionEnum.IO_EXCEPTION.getCode())
                    .setErrorDetail("部门代码已存在")
                    .setErrorSolution("请重新输入部门代码")
                    .build();
        }
    }

    @Override
    @ApiOperation(value = "删除部门信息",notes = "根据ID 删除部门信息")
    public void deleteSysDepartmentById(Long id) {
        LOGGER.info("部门信息 SysDepartment id :{}", id);
        // 查询是否存在子级
        LOGGER.info("部门信息 DEPARTMENT :{}", id);
        if (departmentRDao.findByPropertyCount("parentId",id) > 0) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.WMS.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                    .setErrorDetail("存在相关部门信息无法删除！")
                    .setErrorSolution("请先删除子集信息在操作")
                    .build();
        }
        // 检查部门引用管理
        personnelService.checkSysDepartmentRef(id);
        // 删除数据
        departmentRDao.deleteById(id);
    }

    @Override
    @ApiOperation(value = "删除部门信息",notes = "根据ID 批量删除部门信息")
    public void deleteSysDepartmentByIds(Long[] ids) {
        LOGGER.info("部门信息 DEPARTMENT ids :{}", ids);
        List<SysDepartment> list = departmentRDao.findByHqlWhere(CoreHqlPack.packHqlIds("parentId", ids));
        if (list != null && list.size() >= 1) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.CORE.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                    .setErrorDetail("["+list.get(0).getName()+"]存在相关部门信息无法删除！")
                    .setErrorSolution("请先删除子集信息在操作")
                    .build();
        }else {
            for (Long id : ids) {
                personnelService.checkSysDepartmentRef(id);
            }

            departmentRDao.deleteByIds(ids);
        }
    }

    @Override
    @ApiOperation(value = "更新部门信息")
    public void updateSysDepartment(SysDepartment department) {
        LOGGER.info("部门信息 DEPARTMENT department :{}", department);
        // 唯一校验 CODE 相同 ID 不同 则视为相同
        List<SysDepartment> list = departmentRDao.findByProperty("departmentCode", department.getDepartmentCode());
        if(list != null && list.size() > 0){
            for (SysDepartment dep : list) {
                if(!dep.getId().equals(department.getId())){
                    throw ImppExceptionBuilder.newInstance()
                            .setSystemID(CommonEnumUtil.SOFT_TYPE.CORE.getCode())
                            .setErrorCode(ImppExceptionEnum.IO_EXCEPTION.getCode())
                            .setErrorDetail("部门代码已存在")
                            .setErrorSolution("请重新输入部门代码")
                            .build();
                }
            }
        }

        // 父节点检查
        coreTreeService.doValidatorSysDepartmentParentId(department);

        // 查询父级部门名称
        if (department.getParentId() != null  && department.getParentId() > 0) {
            LOGGER.info("部门信息 DEPARTMENT :{}", department.getParentId());
            SysDepartment parentPosition = departmentRDao.getById(department.getParentId());
            ValidatorBean.checkNotNull(parentPosition,"上级部门信息不存在");

            department.setParentNameRdd(parentPosition.getName());
        }

        // 查询所属组织名称
        LOGGER.info("组织信息 ORGANIZE organizeId:{}", department.getOrganizeId());
        SysOrganize organize = organizeRDao.getById(department.getOrganizeId());
        ValidatorBean.checkNotNull(organize);

        department.setOrganizeNameRdd(organize.getName());

        // 新增部门
        LOGGER.info("部门信息 DEPARTMENT department:{}",department);
        departmentRDao.update(department);
        // 修改冗余信息
        personnelService.refreshDepartmentRdd(department.getId());
        personnelService.refreshUpdateRefSysUserDepartmentRdd(department.getId());
        personnelService.refreshUpdateRefSysUserInfoDepartmentRdd(department.getId());
    }

    @Override
    @ApiOperation(value = "查询部门信息",notes = "查询所有部门信息")
    public List<SysDepartment> listSysDepartment() {
        LOGGER.info("部门信息 DEPARTMENT list");
        return  departmentRDao.list();
    }

    @Override
    @ApiOperation(value = "查询部门信息",notes = "查询部门信息(分页、组合)")
    public ListPager<SysDepartment> querySysDepartment(SysDepartment department, Pager pager) {
        LOGGER.info("部门 SysDepartment find  department :{} page:{}", department, pager);
        if (department == null) {
            //不传入实体对象，查询所有
            int count = departmentRDao.listCount();
            pager = PagerHelper.getPager(pager, count);
            return new ListPager(departmentRDao.listPager(pager), pager);
        } else {
            //生成hql查询语句
            String hqlPack = CoreHqlPack.packHqlSysDepartment(department);
            pager = PagerHelper.getPager(pager, departmentRDao.findByHqlWhereCount(hqlPack));
            return new ListPager(departmentRDao.findByHqlWherePage(hqlPack + department.orderBy(), pager), pager);
        }
    }

    @Override
    @ApiOperation(value = "查询部门信息",notes = "根据ID查询部门信息")
    public SysDepartment getSysDepartmentById(Long id) {
        LOGGER.info("部门信息 DEPARTMENT id:{}",id);
        return departmentRDao.getById(id);
    }

    @Override
    @ApiOperation(value = "查询部门信息",notes = "查询部门信息(分页、组合)")
    public ListPager<SysDepartment> findSysDepartmentByPager(SysDepartment department, Pager pager) {
        LOGGER.info("部门信息 DEPARTMENT department :{}", department);
        LOGGER.info("部门信息 DEPARTMENT pager :{}", pager);

        if (department == null) {
            pager = PagerHelper.getPager(pager, departmentRDao.listCount());
            return new ListPager(departmentRDao.listPager(pager),pager);
        } else {
            String hqlPack = CoreHqlPack.packHqlSysDepartment(department);
            pager = PagerHelper.getPager(pager, departmentRDao.findByHqlWhereCount(hqlPack));
            return new ListPager(departmentRDao.findByHqlWherePage(
                    hqlPack + department.orderBy(),pager),pager);
        }
    }

    @Override
    public ListPager<SysDepartment> findSysDepartmentByPager(SysDepartment department, List<Long> organizeIdList, Pager pager) {
        LOGGER.info("部门信息 DEPARTMENT department :{} organizeIdList:{}", department,organizeIdList);

        if (department == null) {
            pager = PagerHelper.getPager(pager, departmentRDao.listCount());
            return new ListPager(departmentRDao.listPager(pager),pager);
        } else {

            String hqlPack = CoreHqlPack.packHqlSysDepartment(department);
            hqlPack += CoreHqlPack.packHqlIds("organizeId",organizeIdList.toArray(new Long[organizeIdList.size()]));

            pager = PagerHelper.getPager(pager, departmentRDao.findByHqlWhereCount(hqlPack));
            return new ListPager(departmentRDao.findByHqlWherePage(hqlPack + department.orderBy(),pager),pager);
        }
    }

    @Override
    public long getSysDepartmentCount() {
        return departmentRDao.listCount();
    }

}
