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

import cn.estsh.i3plus.core.api.iservice.busi.ICoreTreeService;
import cn.estsh.i3plus.core.api.iservice.busi.ISysUserInfoService;
import cn.estsh.i3plus.platform.common.tool.StringTool;
import cn.estsh.i3plus.platform.common.tool.TimeTool;
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.model.platform.UserDetailModel;
import cn.estsh.i3plus.pojo.platform.bean.*;
import cn.estsh.i3plus.pojo.platform.repository.*;
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 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.ArrayList;
import java.util.List;

/**
 * @Description : 用户信息 服务
 * @Reference :
 * @Author : wei.peng
 * @Date : 2018-11-08 19:44
 * @Modify :
 **/
@Service
public class SysUserInfoService implements ISysUserInfoService {

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


    @Autowired
    private SysUserInfoRepository sysUserInfoRDao;

    @Autowired
    private SysUserRepository sysUserRepository;

    @Autowired
    private SysDepartmentRepository departmentRDao;

    @Autowired
    private SysRefUserDepartmentRepository refUserDepartmentRDao;

    @Autowired
    private SysPositionRepository positionRDao;

    @Autowired
    private SysRefUserPositionRepository refUserPositionRDao;

    @Autowired
    private SysOrganizeRepository organizeRDao;

    @Autowired
    private ICoreTreeService coreTreeService;

    /***
     * @param userInfo
     * @return
     */
    @Override
    @ApiOperation(value = "新增用户",notes = "新增一个用户信息")
    public SysUserInfo insertSysUserInfo(SysUserInfo userInfo) {
        LOGGER.info("用户信息 SysUserInfo userInfo:{}",userInfo);

        return sysUserInfoRDao.insert(userInfo);
    }

    @Override
    @ApiOperation(value = "修改用户",notes = "修改一个用户信息")
    public void updateSysUserInfo(SysUserInfo userInfo) {
        LOGGER.info("用户信息 SysUserInfo userInfo:{}",userInfo);
        sysUserInfoRDao.update(userInfo);
    }

    @Override
    @ApiOperation(value = "刷新用户关系",notes = "刷新用户部门关系")
    public void refreshRefUserDepartment(Long userInfoId, Long[] departmentIds, String userName) {
        LOGGER.info("用户信息 SysUserInfo userInfoId:{} departmentIds:{} userName:{}",userInfoId,departmentIds,userName);

        SysUserInfo userInfo = sysUserInfoRDao.getById(userInfoId);
        if(userInfo != null ){

            // 删除用户部门关系
            refUserDepartmentRDao.deleteByProperty("userId",userInfo.getId());

            if(departmentIds.length > 0){
                // 查询部门信息
                StringBuffer where = new StringBuffer();
                HqlPack.getInPack(StringUtils.join(departmentIds,","),"id",where);
                List<SysDepartment> departmentList = departmentRDao.findByHqlWhere(where.toString());

                if(departmentList != null && departmentList.size() >0){
                    List<SysRefUserDepartment> list = new ArrayList<>();
                    List<String> nameList = new ArrayList<>();
                    SysRefUserDepartment ref = null;
                    for (SysDepartment department : departmentList) {
                        ref = new SysRefUserDepartment();
                        ref.setOrganizeId(department.getOrganizeId());
                        ref.setOrganizeNameRdd(department.getOrganizeNameRdd());
                        ref.setDepartmentId(department.getId());
                        ref.setDepartmentNameRdd(department.getName());
                        ref.setUserId(userInfo.getId());
                        ref.setUserNameRdd(userInfo.getName());
                        ref.setCreateUser(userName);
                        ref.setCreateDatetime(TimeTool.getNowTime(true));
                        list.add(ref);

                        nameList.add(department.getName());
                    }

                    userInfo.setDepartmentNamesRdd(String.join(",",nameList));

                    refUserDepartmentRDao.saveAll(list);
                    sysUserInfoRDao.save(userInfo);

                    LOGGER.info("用户信息 SysUserInfo RefUserDepartmentRDao Insert Size :{}",list.size());
                }
            }
        }else {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.CORE.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_NOT_EXIT.getCode())
                    .setErrorDetail("用户信息不存在")
                    .setErrorSolution("请重新操作")
                    .build();
        }
    }

    @Override
    @ApiOperation(value = "刷新用户关系",notes = "刷新用户岗位关系")
    public void refreshRefUserPosition(Long userInfoId, Long[] positionIds , String userName) {
        LOGGER.info("用户信息 SysUserInfo userInfoId:{} positionIds:{} userName:{}",userInfoId,positionIds,userName);

        SysUserInfo userInfo = sysUserInfoRDao.getById(userInfoId);
        if(userInfo != null ){
            // 删除用户岗位关系
            refUserPositionRDao.deleteByProperty("userId",userInfo.getId());

            if(positionIds.length > 0){
                StringBuffer where = new StringBuffer();
                HqlPack.getInPack(StringUtils.join(positionIds,","),"id",where);  // 查询部门信息
                List<SysPosition> positionList = positionRDao.findByHqlWhere(where.toString());

                if(positionList != null && positionList.size() >0){
                    List<SysRefUserPosition> list = new ArrayList<>();
                    List<String> nameList = new ArrayList<>();
                    SysRefUserPosition ref = null;
                    for (SysPosition position : positionList) {
                        ref = new SysRefUserPosition();
                        ref.setUserId(userInfo.getId());
                        ref.setUserNameRdd(userInfo.getName());
                        ref.setPositionId(position.getId());
                        ref.setPositionNameRdd(position.getName());
                        ref.setCreateUser(userName);
                        ref.setCreateDatetime(TimeTool.getNowTime(true));
                        list.add(ref);

                        nameList.add(position.getName());
                    }

                    userInfo.setPositionNamesRdd(String.join(",",nameList));

                    refUserPositionRDao.saveAll(list);
                    sysUserInfoRDao.save(userInfo);

                    LOGGER.info("用户信息 SysUserInfo RefUserPositionRDao Insert Size :{}",list.size());
                }
            }
        }else {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.CORE.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_NOT_EXIT.getCode())
                    .setErrorDetail("用户信息不存在")
                    .setErrorSolution("请重新操作")
                    .build();
        }
    }

    @Override
    @ApiOperation(value = "刷新用户关系",notes = "刷新用户组织关系")
    public void refreshRefUserOrganize(Long userInfoId, Long organizeId, String userName) {
        LOGGER.info("用户信息 SysUserInfo userInfoId:{} organizeId:{} userName:{}",userInfoId,organizeId,userName);
        SysUserInfo userInfo = sysUserInfoRDao.getById(userInfoId);
        if(userInfo != null ){
            SysOrganize organize = organizeRDao.getById(organizeId);
            if(organize != null ){

                userInfo.setOrganizeId(organize.getId());
                userInfo.setOrganizeNameRdd(organize.getName());
                userInfo.setOrganizeCode(organize.getOrganizeCode());
                userInfo.setModifyUser(userName);
                userInfo.setModifyDatetime(TimeTool.getNowTime(true));

                sysUserInfoRDao.update(organize);
            }
        }else {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.CORE.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_NOT_EXIT.getCode())
                    .setErrorDetail("用户信息不存在")
                    .setErrorSolution("请重新操作")
                    .build();
        }
    }

    @Override
    @ApiOperation(value = "刷新用户账号信息",notes = "根据UserInfoId 刷新用户账号信息")
    public void refreshUserInfoUserNum(Long userInfoId) {
        LOGGER.info("用户信息 SysUserInfo userInfoId:{}",userInfoId);
        SysUserInfo userInfo = sysUserInfoRDao.getById(userInfoId);
        if(userInfo != null){
            sysUserRepository.findByPropertyCount(
                    new String[]{"userInfoId","isValid"},
                    new Object[]{userInfo.getId(),CommonEnumUtil.IS_VAILD.VAILD.getValue()});
//            userInfo.setUserNum(count);
            sysUserInfoRDao.save(userInfo);

        }
    }

    @Override
    @ApiOperation(value = "删除用户",notes = "根据UserInfoId 删除用户信息")
    public void deleteSysUserInfoById(Long id) {
        LOGGER.info("用户信息 SysUserInfo id:{}",id);
        sysUserInfoRDao.deleteById(id);
    }

    @Override
    @ApiOperation(value = "删除用户-批量",notes = "根据UserInfoId 批量删除用户信息")
    public void deleteSysUserInfoByIds(Long[] ids) {
        LOGGER.info("用户信息 SysUserInfo ids:{}",ids);
        sysUserInfoRDao.deleteByIds(ids);
    }

    @Override
    @ApiOperation(value = "查询用户信息",notes = "根据 UserInfoId查询用户信息")
    public SysUserInfo getSysUserInfoById(Long id) {
        return sysUserInfoRDao.getById(id);
    }

    @Override
    @ApiOperation(value = "查询用户信息",notes = "查询所有用户信息")
    public List listSysUserInfo() {
        return sysUserInfoRDao.findAll();
    }

    @Override
    @ApiOperation(value = "查询用户信息",notes = "根据复杂查询条件查询用户信息(分页信息)")
    public ListPager<SysUserInfo> querySysUserInfo(SysUserInfo userInfo, Pager pager) {
        LOGGER.info("查询用户信息 TASK_TIME TaskTime:{}，Pager:{}",userInfo,pager);
        if(userInfo == null) {
            pager = PagerHelper.getPager(pager, sysUserInfoRDao.listCount());
            return new ListPager(sysUserInfoRDao.listPager(pager),pager);
        }else {
            List<Long> departmentIdList = new ArrayList<>();
            if(userInfo.getOrganizeId() != null){

                // 查出所有组织 ID 集合
                SysOrganize parent = coreTreeService.getSysOrganizeTreeById(userInfo.getOrganizeId());
                List<Long> childIds = coreTreeService.findSysOrganizeChildIds(parent);

                // 查询所有部门 ID 集合
                if(childIds != null && childIds.size() > 0){
                    for (Long organizeId : childIds) {
                        departmentIdList.addAll(coreTreeService.findSysDepartmentIdByOrganizeId(organizeId));
                    }
                }
            }

            // 封装部门 ID 信息
            if(userInfo.getDepartmentId() != null){
                SysDepartment department = departmentRDao.getById(userInfo.getDepartmentId());
                departmentIdList.addAll(coreTreeService.findSysDepartmentChildIds(department));
            }

            userInfo.setDepartmentIdList(StringTool.getListString(departmentIdList));

            String hqlPack = CoreHqlPack.packHqlSysUserInfo(userInfo);
            pager = PagerHelper.getPager(pager, sysUserInfoRDao.findByHqlWhereCount(hqlPack));
            return new ListPager(sysUserInfoRDao.findByHqlWherePage(hqlPack + userInfo.orderBy(),pager),pager);
        }
    }

    @Override
    @ApiOperation(value = "关系查询-用户部门",notes = "查询用户部门关系")
    public List<SysRefUserDepartment> findRefUserDepartmentByUserId(Long userId) {
        return refUserDepartmentRDao.findByProperty("userId",userId);
    }

    @Override
    @ApiOperation(value = "关系查询-用户部门",notes = "根据部门或者组织集合查询用户部门关系")
    public List<SysRefUserDepartment> querySysRefUserDepartment(UserDetailModel model) {
        if(model != null){
            StringBuffer userIdWhere = new StringBuffer();

            if(model.getUserDepartmentIdList() != null){
                HqlPack.getInPack(StringUtils.join(model.getInfoDepartmentIdList(),","),"departmentId", userIdWhere);
            }
            if(model.getUserOrganizeIdList() != null){
                HqlPack.getInPack( StringUtils.join(model.getUserOrganizeIdList(),","),"organizeId",userIdWhere);
            }

            return refUserDepartmentRDao.findByHqlWhere(userIdWhere.toString());
        }else {
            return null;
        }
    }

    @Override
    @ApiOperation(value = "关系查询-用户岗位",notes = "查询用户岗位关系")
    public List<SysRefUserPosition> findSysRefUserPositionByUserId(Long userId) {
        return refUserPositionRDao.findByProperty("userId",userId);
    }

    @Override
    @ApiOperation(value = "用户唯一校验",notes = "校验用户信息唯一性")
    public void checkSysUserInfoOnly(SysUserInfo userInfo) {
        if(userInfo != null){
            // 登录名唯一教研
            if(!checkUserInfoByUserEmpNo(userInfo.getUserEmpNo(), userInfo.getId() == null ? 0 : userInfo.getId())){
                throw ImppExceptionBuilder.newInstance()
                        .setSystemID(CommonEnumUtil.SOFT_TYPE.CORE.getCode())
                        .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_EXIT.getCode())
                        .setErrorDetail("工号已存在")
                        .setErrorSolution("请重新输入工号")
                        .build();
            }
        }
    }

    @Override
    @ApiOperation(value = "查询用户信息-",notes = "根据组织、部门、名称+工号组合查询条件查询用户信息")
    public List<SysUserInfo> querySysUserInfoList(SysUserInfo info, List<Long> idList) {
        LOGGER.info("查询用户信息 TASK_TIME SysUserInfo:{}，List<Long> idList :{}",info,idList);

        String hqlPack = CoreHqlPack.packHqlSysUserInfo(info,idList);
        return sysUserInfoRDao.findByHqlWhere(hqlPack);
    }

    @Override
    public List<SysUserInfo> querySysUserInfoList(UserDetailModel model, List<Long> idList) {
        return null;
    }

    @Override
    @ApiOperation(value = "用户唯一校验  用户工号",notes = "用户唯一校验  用户工号")
    public boolean checkUserInfoByUserEmpNo(String no, long id) {
        int count;
        if(id > 0){
            StringBuffer sw = new StringBuffer();
            HqlPack.getStringEqualPack(no,"userEmpNo",sw);
            HqlPack.getNumNOEqualPack(id,"id",sw);
            count = sysUserInfoRDao.findByHqlWhereCount(sw.toString());
        }else{
            count = sysUserInfoRDao.findByPropertyCount("userEmpNo",no);
        }
        return count <= 0 ;
    }
}
