/**
* 文件：UserServiceImpl.java
* 版本：1.0.0
* 日期：
* Copyright &reg; 
* All right reserved.
*/

package com.mortals.xhx.base.system.user.service.impl;

import com.mortals.framework.ap.SysConstains;
import com.mortals.framework.common.code.UserType;
import com.mortals.framework.exception.AppException;
import com.mortals.framework.model.Context;
import com.mortals.framework.model.PageInfo;
import com.mortals.framework.model.Result;
import com.mortals.framework.service.IUser;
import com.mortals.framework.service.impl.AbstractCRUDServiceImpl;
import com.mortals.framework.util.SecurityUtil;
import com.mortals.framework.util.StringUtils;
import com.mortals.xhx.base.system.menu.model.MenuEntity;
import com.mortals.xhx.base.system.menu.service.MenuService;
import com.mortals.xhx.base.system.resource.model.ResourceEntity;
import com.mortals.xhx.base.system.resource.service.ResourceService;
import com.mortals.xhx.base.system.user.dao.UserDao;
import com.mortals.xhx.base.system.user.model.UserEntity;
import com.mortals.xhx.base.system.user.model.UserQuery;
import com.mortals.xhx.base.system.user.service.UserService;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * <p>Title: 用户信息</p>
 * <p>Description: UserServiceImpl service接口 </p>
 * <p>Copyright: Copyright &reg;  </p>
 * <p>Company: </p>
 * @author 
 * @version 1.0.0
 */
@Service("userService")
public class UserServiceImpl extends AbstractCRUDServiceImpl<UserDao,UserEntity,Long> implements UserService {


    @Autowired
    private MenuService menuService;
    @Autowired
    private ResourceService resourceService;

    private void doHandlerUser(UserEntity entity) throws AppException {
        if (StringUtils.isNotEmpty(entity.getLoginPwd())) {
            try {
                entity.setLoginPwd(SecurityUtil.md5DoubleEncoding(entity.getLoginPwd()));
            } catch (Exception e) {
                throw new AppException("密码转换异常");
            }
        }else {
            entity.setLoginPwd(null);
        }
//        if (entity.isSystemUser()) {
//            entity.setUserType(UserType.SYSTEM.getValue());
//        } else {
//            entity.setUserType(UserType.CUSTOMER.getValue());
//        }
    }

    @Override
    protected void saveBefore(UserEntity entity, Context context) throws AppException {
        this.doHandlerUser(entity);
    }

    @Override
    protected void updateBefore(UserEntity entity, Context context) throws AppException {
        if (entity.getId().longValue() == SysConstains.ADMIN_ID && !context.getUser().isAdmin()) {
            throw new AppException("你没有权限执行该操作");
        }
        this.doHandlerUser(entity);
    }

    @Override
    protected UserEntity findBefore(UserEntity params, Context context) throws AppException {
//        if (StringUtils.isNotEmpty(params.getDeptIds())) {
//            params.setDeptIds(StringUtils.fillWithMark(params.getDeptIds(), ","));
//        }
        return super.findBefore(params, context);
    }

    @Override
    protected UserEntity findBefore(UserEntity params, PageInfo pageInfo, Context context) throws AppException {
//        if (StringUtils.isNotEmpty(params.getDeptIds())) {
//            params.setDeptIds(StringUtils.fillWithMark(params.getDeptIds(), ","));
//        }
        return super.findBefore(params, pageInfo, context);
    }

    public UserEntity findByLoginName(String loginName) {
        UserQuery params = new UserQuery();
        params.setLoginName(loginName);
        List<UserEntity> userList = super.dao.getList(params);
        if (userList != null && userList.size() > 0) {
            return userList.get(0);
        }
        return null;
    }

    @Override
    public UserEntity doLogin(String loginName, String password, String loginIp) throws AppException {
        UserEntity sysUser = this.findByLoginName(loginName);
        if (sysUser == null || !sysUser.getLoginName().equals(loginName)) {
            throw new AppException("用户名不存在！");
        }
        try {
            if (!sysUser.getLoginPwd().equals(SecurityUtil.md5DoubleEncoding(password))) {
                throw new AppException("登录密码错误！");
            }
        } catch (Exception e) {
            throw new AppException("密码验认出错！", e);
        }
        return sysUser;
    }

    @Override
    public UserEntity doCheckUser(String loginName, String password) throws AppException {
        UserEntity sysUser = this.findByLoginName(loginName);
        if (sysUser == null || !sysUser.getLoginName().equals(loginName)) {
            return null;
        }
        try {
            if (!sysUser.getLoginPwd().equals(SecurityUtil.md5DoubleEncoding(password))) {
                return null;
            }
        } catch (Exception e) {
            return null;
        }
        return sysUser;
    }

    @Override
    public Set<Long> findAllAuthIds(UserEntity userEntity) throws AppException {
        Set<Long> authIds = new HashSet<Long>();
        if (userEntity.isAdmin()) {
            return authIds;
        }
        authIds.addAll(dao.getAuthListById(userEntity.getId()));
        return authIds;
    }

    @Override
    public List<MenuEntity> findOutlookBarList(IUser user) {
        Set<String> urls = new HashSet<String>();
        if (!user.isAdmin()) {
            List<ResourceEntity> resList = resourceService.findListByUserId(user.getId());
            for (ResourceEntity res : resList) {
                String url = res.getUrl();
                if (StringUtils.isEmpty(url)) {
                    continue;
                }
                url = url.replaceAll("，", ",");
                urls.addAll(StringUtils.converStr2Set(url));
            }
        }
        Set<Long> authIds = new HashSet<Long>();
        Map<Long, MenuEntity> menuMap = new HashMap<Long, MenuEntity>();
        List<MenuEntity> userModuleList = this.menuService.findAllEnable();
        for (MenuEntity sysModule : userModuleList) {
            if (sysModule == null) {
                continue;
            }
            menuMap.put(sysModule.getId(), sysModule);
            if (!user.isAdmin() && urls.contains(StringUtils.trim(sysModule.getUrl()))) {
                authIds.add(sysModule.getId());
            }
        }
        if (!user.isAdmin()) {
            Long[] ids = authIds.toArray(new Long[authIds.size()]);
            for (Long id : ids) {
                MenuEntity menu = menuMap.get(id);
                while (menu != null) {
                    authIds.add(menu.getId());
                    menu = menuMap.get(menu.getParentId());
                }
            }
        }
        List<MenuEntity> outlookBar = new ArrayList<MenuEntity>();
        List<MenuEntity> norightList = new ArrayList<MenuEntity>();
        for (MenuEntity sysModule : userModuleList) {
            if (!user.isAdmin() && !authIds.contains(sysModule.getId())) {
                norightList.add(sysModule);
                continue;
            }
            if (sysModule.getParentId() == null || sysModule.getParentId().longValue() == 0) {
                outlookBar.add(sysModule);
                continue;
            }
            MenuEntity sysModuleParent = menuMap.get(sysModule.getParentId());
            if (sysModuleParent != null) {
                sysModuleParent.getChildList().add(sysModule);
            }
        }
        return outlookBar;
    }

    @Override
    public Result<UserEntity> find(Long platformId, UserEntity params, int currPage, int prePageResult) throws AppException {
        PageInfo pageInfo = new PageInfo(prePageResult);
        pageInfo.setCurrPage(currPage);
        return super.find(params, pageInfo, null);
    }

    @Override
    public UserEntity createUser(IUser currUser, Long customerId, String customerName, String loginName, String password,
                                 String userName, String mobile) throws AppException {
        try {
            UserEntity entity = new UserEntity();
            entity.initAttrValue();
            entity.setLoginName(loginName);
            entity.setRealName(userName);
            entity.setCustomerId(customerId);
            entity.setLoginPwd(password);
            entity.setMobile(mobile);
            entity.setUserType(UserType.CUSTOMER.getValue());
            entity.setCreateTime(new Date());
            if (currUser != null) {
                entity.setCreateUser(currUser.getLoginName());
                entity.setCreateUserName(currUser.getRealName());
            }
            this.doHandlerUser(entity);
            dao.insert(entity);
            return entity;
        } catch (Exception e) {
            log.error("给客户创建用户异常-->customerId:" + customerId + ",customerName:" + customerName + ",loginName:" + loginName +
                    "-->原因：" + e.getMessage());
            return null;
        }
    }

    @Override
    public boolean existUser(String loginName, Long userId) throws AppException {
        UserEntity sysUser = this.findByLoginName(loginName);
        boolean bRet = false;
        if (sysUser != null) {
            if (userId == null || userId == 0 || userId.longValue() != sysUser.getId().longValue()) {
                bRet = true;
            }
        }
        return bRet;
    }

    @Override
    public boolean updateUserPwd(String loginName, String oldPwd, String newPwd) throws AppException {
        UserEntity sysUser = this.findByLoginName(loginName);
        if (sysUser == null || !sysUser.getLoginName().equals(loginName)) {
            throw new AppException("帐号错误！");
        }
        try {
            if (!sysUser.getLoginPwd().equals(SecurityUtil.md5DoubleEncoding(oldPwd))) {
                throw new AppException("原始密码错误！");
            }
        } catch (Exception e) {
            throw new AppException("密码验认出错！", e);
        }
        try {
            sysUser.setLoginPwd(SecurityUtil.md5DoubleEncoding(newPwd));
            sysUser.setLoginPwd3(sysUser.getLoginPwd2());
            sysUser.setLoginPwd2(sysUser.getLoginPwd1());
            sysUser.setLoginPwd1(sysUser.getLoginPwd());
            sysUser.setLastModPwdTime(new Date());
        } catch (Exception e) {
            throw new AppException("密码转换异常！", e);
        }
        dao.update(sysUser);
        return true;
    }

}