package com.keyware.shandan.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.keyware.shandan.bianmu.service.DirectoryMembersService;
import com.keyware.shandan.bianmu.service.DirectoryService;
import com.keyware.shandan.common.entity.Result;
import com.keyware.shandan.common.enums.DataOperateType;
import com.keyware.shandan.common.service.BaseServiceImpl;
import com.keyware.shandan.common.util.MD5Util;
import com.keyware.shandan.common.util.StreamUtil;
import com.keyware.shandan.common.util.StringUtils;
import com.keyware.shandan.frame.annotation.DataPermissions;
import com.keyware.shandan.frame.annotation.UserSync;
import com.keyware.shandan.frame.config.security.SecurityUtil;
import com.keyware.shandan.system.entity.SysOrg;
import com.keyware.shandan.system.entity.SysUser;
import com.keyware.shandan.system.entity.SysUserRole;
import com.keyware.shandan.system.mapper.SysUserMapper;
import com.keyware.shandan.system.service.SysOrgService;
import com.keyware.shandan.system.service.SysUserClientService;
import com.keyware.shandan.system.service.SysUserRoleService;
import com.keyware.shandan.system.service.SysUserService;
import com.keyware.shandan.system.utils.SysSettingUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 系统用户表 服务实现类
 * </p>
 *
 * @author
 * @since 2021-05-07
 */
@Service
public class SysUserServiceImpl extends BaseServiceImpl<SysUserMapper, SysUser, String> implements SysUserService {

    @Autowired
    private SysOrgService sysOrgService;

    @Autowired
    private SysUserRoleService sysUserRoleService;

    @Autowired
    private DirectoryMembersService directoryMembersService;

    @Autowired
    private SysUserClientService userClientService;

    @Autowired
    private DirectoryService directoryService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    @UserSync(operateType = DataOperateType.DELETE)
    public Result<Boolean> deleteById(String id) {
        // 删除用户角色关系
        SysUserRole userRole = new SysUserRole();
        userRole.setUserId(id);
        sysUserRoleService.remove(new QueryWrapper<>(userRole));

        // 如果是主管，先取消主管设置
        SysUser user = getById(id);
        if (user.isLeader()) {
            sysOrgService.removeOrgLeader(user.getOrgId());
        }

        // 删除目录成员
        directoryMembersService.removeByMemberId(id);

        // 删除客户端权限
        userClientService.deleteByUserId(id);

        updateDeleteLoginName(user);

        // 迁移用户下的目录数据
        directoryService.moveDataToOrg(user);

        return Result.of(removeById(id));
    }

    @Override
    @DataPermissions
    public Page<SysUser> page(Page<SysUser> page, QueryWrapper<SysUser> wrapper) {
        return pageAll(page, wrapper);
    }

    @Override
    public SysUser findByLoginName(String username) {
        QueryWrapper<SysUser> wrapper = new QueryWrapper<>();
        wrapper.eq("LOGIN_NAME", username);
        return super.getOne(wrapper);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @UserSync(operateType = DataOperateType.INSERT_OR_UPDATE)
    public Result<SysUser> updateOrSave(SysUser entity) throws Exception {
        SysUser oldUser = getById(entity.getUserId());

        if (oldUser == null) {
            SysUser existsUser = findByLoginName(entity.getLoginName());
            Assert.isNull(existsUser, "用户名已存在");
            //需要设置初始密码
            entity.setPassword(MD5Util.getMD5(SysSettingUtil.getCurrentSysSetting().getUserInitPassword()));
        }

        super.saveOrUpdate(entity);

        if (oldUser == null) {
            // 设置普通用户角色
            sysUserRoleService.addUserRole(entity.getUserId(), "ROLE_USER");
        }

        if (entity.isLeader()) {
            // 如果原始数据已经是主管了，则不需要再设置主管
            if (oldUser == null || !oldUser.isLeader()) {
                //设置组织领导
                sysOrgService.setOrgLeader(entity.getOrgId(), entity);
                // 自动配置部门管理员角色
                sysUserRoleService.addUserRole(entity.getUserId(), "ROLE_ADMIN");
            }
        } else if (oldUser != null && oldUser.isLeader()) {
            sysOrgService.removeOrgLeader(entity.getOrgId());
        }
        return Result.of(entity);
    }

    @Override
    public Result<SysUser> resetPassword(SysUser user) {
        user.setPassword(MD5Util.getMD5(user.getPassword()));
        boolean flag = updateById(user);
        user.setPassword(null);
        return flag ? Result.of(user) : null;
    }

    @Override
    public Result<Boolean> updatePassword(String oldPassword, String newPassword) {
        SysUser user = findByLoginName(SecurityUtil.getLoginUserByContext().getUsername());
        Assert.notNull(user, "用户信息未找到");
        boolean ok = false;
        if (user.getPassword().equals(MD5Util.getMD5(oldPassword))) {
            user.setPassword(MD5Util.getMD5(newPassword));

            user.setLastChangePwdTime(new Date());

            ok = saveOrUpdate(user);

        }

        return Result.of(ok, ok, ok ? "修改成功" : "修改失败，你输入的原密码错误！");
    }

    @Override
    public Page<SysUser> pageAll(Page<SysUser> page, QueryWrapper<SysUser> queryWrapper) {
        SysUser user = queryWrapper.getEntity();
        if (StringUtils.hasText(user.getOrgId()) && !"ROOT".equals(user.getOrgId())) {
            List<String> orgIds = StreamUtil.as(sysOrgService.getOrgAllChildren(user.getOrgId())).map(SysOrg::getId).toList();
            orgIds.add(user.getOrgId());
            queryWrapper.in("ORG_ID", orgIds);
        }
        if (StringUtils.hasText(user.getLoginName())) {
            queryWrapper.and(wrapper -> {
                wrapper.like("LOGIN_NAME", user.getLoginName()).or().like("USER_NAME", user.getLoginName());
            });
        }
        queryWrapper.setEntity(null);

        Page<SysUser> userPage = super.page(page, queryWrapper);
        userPage.setRecords(userPage.getRecords().stream().map(sysUser -> {
            sysUser.setPassword(null);
            return sysUser;
        }).collect(Collectors.toList()));

        return userPage;
    }

    void updateDeleteLoginName(SysUser user) {
        UpdateWrapper<SysUser> uw = new UpdateWrapper<>();
        uw.set("LOGIN_NAME", user.getLoginName() + "(DEL:" + System.currentTimeMillis() + ")");
        uw.eq("USER_ID", user.getUserId());
        update(uw);
    }
}
