package com.mosty.common.core.business.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mosty.common.base.constant.UserConstants;
import com.mosty.common.base.constant.enums.DeletedEnum;
import com.mosty.common.base.exception.Asserts;
import com.mosty.common.base.exception.BusinessException;
import com.mosty.common.base.util.PasswordUtil;
import com.mosty.common.base.util.RandomUtil;
import com.mosty.common.config.config.SystemConfig;
import com.mosty.common.core.business.entity.*;
import com.mosty.common.core.business.entity.request.SysUserEditPasswordRequest;
import com.mosty.common.core.business.entity.vo.*;
import com.mosty.common.core.business.mapper.SysDeptMapper;
import com.mosty.common.core.business.mapper.SysUserDeptMapper;
import com.mosty.common.core.business.mapper.SysUserMapper;
import com.mosty.common.core.business.service.*;
import com.mosty.common.core.config.DefaultRoleConfig;
import com.mosty.common.core.util.BeanUtils;
import com.mosty.common.core.util.http.HttpUtils;
import com.mosty.common.token.UserInfo;
import com.mosty.common.token.UserInfoManager;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements SysUserService {

    @Resource
    private SysUserMapper sysUserMapper;
    @Resource
    private SysUserDeptService sysUserDeptService;
    @Resource
    private DefaultRoleConfig defaultRoleConfig;
    @Resource
    private SysUserRoleService sysUserRoleService;
    @Resource
    private SystemConfig systemConfig;
    @Resource
    private SysDeptService sysDeptService;
    @Resource
    private SysPositionService sysPositionService;
    @Resource
    private SysDeptMapper sysDeptMapper;
    @Resource
    private SysUserDeptMapper sysUserDeptMapper;
    @Resource
    private SysRoleService sysRoleService;
    @Resource
    private LoginService loginService;
    public static String USER_URL = "http://80.149.27.78:8001/no-auth-api/coreUsersList";

    @Override
    public void saveInfo(AddSysUserVO sysUserVo) {
        if (StringUtils.isBlank(sysUserVo.getSsbmdm())) return;
        // 保存用户信息
        Long userId = saveUserInfo(sysUserVo);
        // 保存用户部门关联关系
        // 验证部门并设置部门名称
//        List<Long> deptIds = sysUserVo.getDeptIds();
        List<SysUserDept> sysUserDeptList = new ArrayList<>();
//        deptIds.forEach(deptId -> {
//            SysDept sysDept = sysDeptService.getById(deptId);
//            Asserts.check(sysDept == null || sysDept.getXtZxbz() != 0, "部门 %s 不存在！", deptId);
//            SysUserDept sysUserDept = new SysUserDept().setUserId(userId).setDeptId(deptId);
//            sysUserDeptList.add(sysUserDept);
//        });
        SysDept sysDept = sysDeptService.getDeptByOrgCode(sysUserVo.getSsbmdm());
        Asserts.check(sysDept == null || sysDept.getXtZxbz() != 0, "部门 %s 不存在！", sysUserVo.getSsbmdm());
        SysUserDept sysUserDept = new SysUserDept().setUserId(userId).setDeptId(sysDept.getId());
        sysUserDeptList.add(sysUserDept);

        sysUserDeptService.saveBatch(sysUserDeptList);
        // 保存默认用户角色
        List<Long> defaultRoleList = defaultRoleConfig.getDefaultRoleList();
        if (CollectionUtils.isNotEmpty(defaultRoleList)) {
            List<SysUserRole> collect = defaultRoleList.stream()
                    .map(roleId -> new SysUserRole(userId, roleId)).collect(Collectors.toList());
            sysUserRoleService.saveBatch(collect);
        }
    }

    // 保存用户信息
    private Long saveUserInfo(AddSysUserVO sysUserVo) {
        SysUser sysUser = BeanUtil.copyProperties(sysUserVo, SysUser.class);

        // 初始化用户密码
        String salt = RandomUtil.generateString(8);
        if (StringUtils.isNotBlank(sysUserVo.getPassword())) {
            String encodePassword = PasswordUtil.encode(sysUserVo.getPassword(), salt);
            sysUser.setPassword(encodePassword);
        } else {
            String passwordPzz = getDefaultPassword(salt);
            sysUser.setPassword(passwordPzz);
        }
        sysUser.setSalt(salt);
        UserInfo userInfo = UserInfoManager.get();
        sysUser.setXtZxbz(DeletedEnum.NATURE.code);

        sysUser.setXtCjsj(new Date());
        sysUser.setXtZhxgsj(new Date());
        sysUser.setXtZhxgid(userInfo.getUserId());
        sysUser.setXtZhxgrxm(userInfo.getUserName());
        sysUser.setXtZhxgrbmid(userInfo.getDeptId());
        sysUser.setXtZhxgrbm(userInfo.getDeptName());

        sysUser.setXtLrsj(new Date());
        sysUser.setXtLrrid(userInfo.getUserId());
        sysUser.setXtLrrxm(userInfo.getUserName());
        sysUser.setXtLrrbmid(userInfo.getDeptId().toString());
        sysUser.setXtLrrbm(userInfo.getDeptName());

        this.save(sysUser);

        return sysUser.getId();
    }

    // 获取默认的初始化密码
    private String getDefaultPassword(String salt) {
        String passwordPzz = systemConfig.getDefaultPassword();
        return PasswordUtil.encode(passwordPzz, salt);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void editInfo(SysUserEditVO sysUserEditVo, SysUser userInfo) {

        if (StringUtils.isBlank(sysUserEditVo.getSsbmdm())) return;

        // 先删除用户id，再添加
        QueryWrapper<SysUserDept> wrapper = new QueryWrapper<>();
        wrapper.eq("user_id", userInfo.getId());

        sysUserDeptService.remove(wrapper);

//        List<SysUserDept> saveRelation = sysUserEditVo.getDeptIds().stream().map(deptId ->
//                new SysUserDept(userInfo.getId(), deptId)).collect(Collectors.toList());
        List<SysUserDept> sysUserDeptList = new ArrayList<>();
        SysDept sysDept = sysDeptService.getDeptByOrgCode(sysUserEditVo.getSsbmdm());
        Asserts.check(sysDept == null || sysDept.getXtZxbz() != 0, "部门 %s 不存在！", sysUserEditVo.getSsbmdm());
        SysUserDept sysUserDept = new SysUserDept().setUserId(sysUserEditVo.getId()).setDeptId(sysDept.getId());
        sysUserDeptList.add(sysUserDept);
        sysUserDeptService.saveBatch(sysUserDeptList);

        SysPosition position = sysPositionService.getById(sysUserEditVo.getPositionId());
//        Asserts.check(position == null, "岗位信息不存在，请登陆");
        // 更改需要保存的字段
        userInfo.setPositionId(sysUserEditVo.getPositionId());
        userInfo.setPositionName(position != null ? position.getPostName() : "");
        userInfo.setUserName(sysUserEditVo.getUserName());
        userInfo.setEmail(sysUserEditVo.getEmail());
        userInfo.setMobile(sysUserEditVo.getMobile());
        userInfo.setTelePhone(sysUserEditVo.getTelePhone());
        userInfo.setPolitic(sysUserEditVo.getPolitic());
        userInfo.setMarital(sysUserEditVo.getMarital());
        userInfo.setType(sysUserEditVo.getType());
        userInfo.setBz(sysUserEditVo.getBz());
        userInfo.setIsVirtualUser(sysUserEditVo.getIsVirtualUser());
        userInfo.setSex(sysUserEditVo.getSex());
        userInfo.setUserType(sysUserEditVo.getUserType());
        userInfo.setInDustRialId(sysUserEditVo.getInDustRialId());
        userInfo.setBeginTime(sysUserEditVo.getBeginTime());
        userInfo.setEndTime(sysUserEditVo.getEndTime());
        userInfo.setBirthday(sysUserEditVo.getBirthday());
        userInfo.setIdEntityCard(sysUserEditVo.getIdEntityCard());
        userInfo.setWhcd(sysUserEditVo.getWhcd());
        userInfo.setNation(sysUserEditVo.getNation());
        userInfo.setLoginName(sysUserEditVo.getLoginName());
        userInfo.setSfrh(sysUserEditVo.getSfrh());
        userInfo.setMk(sysUserEditVo.getMk());
        super.updateById(userInfo);
    }

    @Override
    public void editPassword(SysUserEditPasswordRequest sysUserEditPasswordRequest) {
        UserInfo userInfo = UserInfoManager.get();
        SysUser sysUser = this.getById(userInfo.getUserId());
        boolean match = PasswordUtil.match(sysUserEditPasswordRequest.getOldPassword(), sysUser.getPassword());
        Asserts.check(!match, "账号 %s 的密码错误", sysUser.getLoginName());
        String salt = RandomUtil.generateString(8);
        String password = PasswordUtil.encode(sysUserEditPasswordRequest.getPassword(), salt);
        sysUser.setPassword(password);
        sysUser.setSalt(salt);
        this.updateById(sysUser);
    }

    @Override
    public SysUser getUserInfo(Long id) {
        return this.getById(id);
    }

    @Override
    public SysUser checkUserInfo(SysUser user) {
        SysUser sysUser = this.getOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getLoginName, user.getLoginName()).eq(SysUser::getXtZxbz, UserConstants.NORMAL));
        Asserts.check(sysUser == null, "账号 %s 的用户不存在", user.getLoginName());
        boolean match = PasswordUtil.match(sysUser.getPassword(), sysUser.getPassword());
        Asserts.check(match, "账号 %s 的密码错误", sysUser.getLoginName());
        return sysUser;
    }

    @Override
    public IPage<SysUserVO> selectByPage(UserPage userPage) {
        if (StringUtils.isBlank(userPage.getDeptId())) {
            userPage.setOrgcode(this.getSsbm("", userPage.getIsChild()));
            List<SysUserVO> list = sysUserMapper.selectByPage(userPage);
            Page<SysUserVO> page = BeanUtil.copyProperties(userPage, Page.class);
            page.setRecords(list);
            return page;
        } else {
            SysDept dept = this.sysDeptMapper.selectById(userPage.getDeptId());
            if (dept != null) {
                userPage.setOrgcode(this.getSsbm(dept.getOrgCode(), userPage.getIsChild()));
                List<SysUserVO> list = sysUserMapper.selectByPage(userPage);
                Page<SysUserVO> page = BeanUtil.copyProperties(userPage, Page.class);
                page.setRecords(list);
                return page;
            }
            return null;
        }
    }

    @Override
    public void resetPassword(SysUser user) {
        String defaultPassword = getDefaultPassword(user.getSalt());
        user.setPassword(defaultPassword);
        sysUserMapper.updateById(user);
    }

    @Override
    public IPage<SysUserVO> selectUnAccreditPage(UserPage userPage) {
        QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>();
        if (StringUtils.isNotBlank(userPage.getLoginName())) {
            queryWrapper.and(wrapper -> wrapper.like("login_name", userPage.getLoginName()));
        }
        if (StringUtils.isNotBlank(userPage.getPhone())) {
            queryWrapper.and(wrapper -> wrapper.like("mobile", userPage.getPhone()));
        }
        queryWrapper.and(wrapper -> wrapper.eq("xt_zxbz", DeletedEnum.NATURE.code));
        QueryWrapper<SysUserRole> sysUserRoleQueryWrapper = new QueryWrapper<>();
        sysUserRoleQueryWrapper.and(wrapper -> wrapper.eq("role_id", userPage.getRoleId()));
        List<SysUserRole> list = sysUserRoleService.list(sysUserRoleQueryWrapper);
        if (CollectionUtil.isNotEmpty(list)) {
            List<Long> userList = list.stream().map(SysUserRole::getUserId).collect(Collectors.toList());
            queryWrapper.and(wrapper -> wrapper.notIn("id", userList));
        }
        UserPage page = this.baseMapper.selectPage(userPage, queryWrapper);
        IPage<SysUserVO> resPage = new Page<>(userPage.getCurrent(), userPage.getSize());
        List<SysUserVO> voList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(page.getRecords())) {
            page.getRecords().forEach(item -> {
                SysUserVO userVO = new SysUserVO();
                BeanUtils.copyProperties(item, userVO);
                voList.add(userVO);
            });
        }
        resPage.setRecords(voList);
        resPage.setTotal(page.getTotal());
        return resPage;
    }

    @Override
    public IPage<SysUserDeptVO> selectUserDeptPage(UserDeptPage userDeptPage) {
        UserInfo user = UserInfoManager.get();
        if (StringUtils.isEmpty(userDeptPage.getSsbmdm())) {
            userDeptPage.setSsbmdm(String.valueOf(user.getDeptCode()));
        }
//        else {
//            userDeptPage.setOrgcode(userDeptPage.getDeptId());
//        }
        userDeptPage.setOrgcode(userDeptPage.getSsbmdm().replaceAll("(00)+$", ""));
        return sysUserMapper.selectUserDeptPage(userDeptPage);
    }

    @Override
    public Boolean userSys() {
        Map<String, Object> params = new HashMap<>();
        String rs = HttpUtils.executeGet(USER_URL, params);
        JSONObject json = JSONObject.parseObject(rs);
        if (json.getBoolean("success")) {
            JSONArray array = json.getJSONArray("data");
            if (CollectionUtils.isNotEmpty(array)) {
                for (int i = 0; i < array.size(); i++) {
                    JSONObject userJson = array.getJSONObject(i);
                    String orgCode = userJson.getString("jurisdictionCode");
                    SysDept sysDept = sysDeptService.getDeptByOrgCode(orgCode);
                    Asserts.check(sysDept == null, "用户code对应的部门信息不存在");
                    String idNum = userJson.getString("idNum");
                    QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>();
                    queryWrapper.eq("id_entity_card", idNum);
                    SysUser sysUser = sysUserMapper.selectOne(queryWrapper);
                    if (sysUser == null) {
                        sysUser = new SysUser();
                    }
                    sysUser.setInDustRialId(userJson.getString("username"));
                    sysUser.setLoginName(userJson.getString("nickName"));
                    sysUser.setUserName(userJson.getString("nickName"));
                    sysUser.setMobile(userJson.getString("mobilePhone"));
                    sysUser.setIdEntityCard(userJson.getString("idNum"));
                    sysUser.setManagerOrgId(sysDept.getId());
                    sysUser.setManagerOrgName(sysDept.getOrgJc());
                    sysUser.setXtZxbz(DeletedEnum.NATURE.code);
                    sysUser.setXtCjsj(new Date());
                    sysUser.setXtZhxgsj(new Date());
                    if (sysUser.getId() == null) {
                        sysUser.setXtLrsj(new Date());
                        this.save(sysUser);
                        SysUserDept userDept = new SysUserDept();
                        userDept.setUserId(sysUser.getId());
                        userDept.setDeptId(sysDept.getId());
                        sysUserDeptService.save(userDept);
                    } else {
                        this.updateById(sysUser);
                        SysUserDept oldUserDept = sysUserDeptService.getByDeptIdAndUserId(sysDept.getId(),
                                sysUser.getId());
                        if (oldUserDept == null) {
                            sysUserDeptService.remove(new LambdaQueryWrapper<SysUserDept>().eq(SysUserDept::getUserId,
                                    sysUser.getId()));
                            SysUserDept userDept = new SysUserDept();
                            userDept.setUserId(sysUser.getId());
                            userDept.setDeptId(sysDept.getId());
                            sysUserDeptService.save(userDept);
                        }
                    }
                }
            }
        }
        return true;
    }


    @Override
    public void delById(Long id) {
        this.baseMapper.delById(id);
    }


    @Override
    public List<SysUserVO> getUserList(GetUserPage dto) {
        UserInfo user = UserInfoManager.get();
        if ("1".equals(dto.getType())) {
            return this.getUserListByDept(dto.getKeyword(), String.valueOf(user.getDeptId()));
        } else {
            return this.getUserListByAll(dto.getKeyword());
        }
    }

    private List<SysUserVO> getUserListByAll(String keyword) {
        List<SysUserVO> userVOList = new ArrayList<>();
        if (StringUtils.isNotBlank(keyword)) {
            List<SysDept> list = this.sysDeptMapper.selectList(
                    new LambdaQueryWrapper<SysDept>()
                            .like(SysDept::getOrgName, keyword)
                            .eq(SysDept::getXtZxbz, "0")
            );

            if (list != null && list.size() > 0) {
                List<String> deptIds = list.stream().map(d -> String.valueOf(d.getId())).collect(Collectors.toList());
                List<SysUser> userList = this.baseMapper.getUserListByDeptId(deptIds, null);
                userList.forEach(user -> {
                    SysUserVO userVO = new SysUserVO();
                    BeanUtils.copyProperties(user, userVO);
                    SysDept dept = this.sysDeptMapper.getDeptByUserId(user.getId());
                    userVO.setDeptId(dept.getId());
                    userVO.setDeptCode(dept.getOrgCode());
                    userVO.setDeptJc(dept.getOrgJc());
                    userVO.setDeptName(dept.getOrgName());
                    userVOList.add(userVO);
                });
            }
        }
        List<SysUser> userList = this.baseMapper.selectList(
                new LambdaQueryWrapper<SysUser>()
                        .eq(SysUser::getIsVirtualUser, "02")
                        .eq(SysUser::getXtZxbz, "0")
                        .and(StringUtils.isNotBlank(keyword), it -> it.like(SysUser::getLoginName, keyword)
                                .or()
                                .like(SysUser::getUserName, keyword))
        );
        userList.forEach(item -> {
            SysUserVO userVO = new SysUserVO();
            BeanUtils.copyProperties(item, userVO);
            SysUserDept sysUserDept = this.sysUserDeptMapper.selectOne(
                    new QueryWrapper<SysUserDept>()
                            .eq("user_id", String.valueOf(item.getId()))
                            .last(" limit 1")
            );
            if (sysUserDept != null) {
                SysDept sysDept = this.sysDeptMapper.selectById(sysUserDept.getDeptId());
                userVO.setDeptId(sysDept.getId());
                userVO.setDeptCode(sysDept.getOrgCode());
                userVO.setDeptJc(sysDept.getOrgJc());
                userVO.setDeptName(sysDept.getOrgName());
            }
            userVOList.add(userVO);
        });
        return userVOList;
    }

    // 获取本部门下的所有的人员信息
    private List<SysUserVO> getUserListByDept(String keyword, String deptid) {
        SysDept dept = this.sysDeptMapper.selectById(deptid);
        List<String> deptIds = new ArrayList<>();
        this.getChildList(dept, deptIds);
        List<SysUser> userList = this.baseMapper.getUserListByDeptId(deptIds, keyword);
        List<SysUserVO> userVOList = new ArrayList<>();
        userList.forEach(item -> {
            SysUserVO userVO = new SysUserVO();
            BeanUtils.copyProperties(item, userVO);
            userVO.setDeptId(dept.getId());
            userVO.setDeptCode(dept.getOrgCode());
            userVO.setDeptJc(dept.getOrgJc());
            userVO.setDeptName(dept.getOrgName());
            userVOList.add(userVO);
        });
        return userVOList;
    }

    private void getChildList(SysDept dept, List<String> deptIds) {
        deptIds.add(String.valueOf(dept.getId()));
        List<SysDept> tempList1 = this.sysDeptMapper.selectList(
                new LambdaQueryWrapper<SysDept>()
                        .eq(SysDept::getParentId, dept.getId())
        );
        if (tempList1.size() > 0) {
            deptIds.addAll(tempList1.stream().map(item -> String.valueOf(item.getId())).collect(Collectors.toList()));
            tempList1.forEach(item -> this.getChildList(item, deptIds));
        }
    }

    public String getSsbm(String ssbmdm, String isChild) {
        isChild = StringUtils.isNotBlank(isChild) ? isChild : "1";
        UserInfo user = UserInfoManager.getUser();
        // 如果用户信息存在，先查询用户权限
        SysRoleVO role = null;
        if (StringUtils.isBlank(ssbmdm)) {
            if (user != null) {
                ssbmdm = user.getDeptCode();
                // 查询用户权限
                List<SysRoleVO> userRoles = sysRoleService.getUserRoleList(user.getUserId());
                if (!org.springframework.util.CollectionUtils.isEmpty(userRoles)) {
                    int level = Integer.parseInt(userRoles.get(0).getDataPermissionLevel());
                    role = userRoles.get(0);
                    for (SysRoleVO item : userRoles) {
                        if (level > Integer.parseInt(item.getDataPermissionLevel())) {
                            level = Integer.parseInt(item.getDataPermissionLevel());
                            role = item;
                        }
                    }
                }
            }
            if (role != null && !"5".equals(role.getDataPermissionLevel())) {
                String level = role.getDataPermissionLevel();
                if ("1".equals(level) || "2".equals(level)) {
                    return "1".equals(isChild) ? ssbmdm.substring(0, 2) : ssbmdm;
                } else if ("3".equals(level)) {
                    return "1".equals(isChild) ? ssbmdm.substring(0, 4) : ssbmdm;
                } else if ("4".equals(level)) {
                    return "1".equals(isChild) ? ssbmdm.substring(0, 6) : ssbmdm;
                } else if ("6".equals(level)) {
                    return ssbmdm;
                }
            } else {
                if ("1".equals(isChild)) {
                    SysDept dept = this.sysDeptMapper.selectOne(
                            new LambdaQueryWrapper<SysDept>()
                                    .eq(SysDept::getXtZxbz, "0")
                                    .eq(SysDept::getOrgCode, ssbmdm)
                    );
                    if (dept == null) {
                        throw new BusinessException("部门信息不存在！");
                    }
                    if (StringUtils.isBlank(dept.getOrgLevel())) {
                        return ssbmdm;
                    }
                    switch (dept.getOrgLevel()) {
                        case "10":
                        case "11":
                            return ssbmdm.substring(0, 2);
                        case "21":
                        case "31":
                            return ssbmdm.substring(0, 8);
                        case "12":
                        case "32":
                        case "22":
                            return ssbmdm.substring(0, 10);
                        case "20":
                            return ssbmdm.substring(0, 4);
                        case "30":
                            return ssbmdm.substring(0, 6);
                        default:
                            return ssbmdm;
                    }
                }
            }
        } else {
            if ("1".equals(isChild)) {
                SysDept dept = this.sysDeptMapper.selectOne(
                        new LambdaQueryWrapper<SysDept>()
                                .eq(SysDept::getXtZxbz, "0")
                                .eq(SysDept::getOrgCode, ssbmdm)
                );
                if (dept == null) {
                    throw new BusinessException("部门信息不存在！");
                }
                if (StringUtils.isBlank(dept.getOrgLevel())) {
                    return ssbmdm;
                }
                switch (dept.getOrgLevel()) {
                    case "10":
                    case "11":
                        return ssbmdm.substring(0, 2);
                    case "21":
                    case "31":
                        return ssbmdm.substring(0, 8);
                    case "12":
                    case "32":
                    case "22":
                        return ssbmdm.substring(0, 10);
                    case "20":
                        return ssbmdm.substring(0, 4);
                    case "30":
                        return ssbmdm.substring(0, 6);
                    default:
                        return ssbmdm;
                }
            }
        }
        return ssbmdm;
    }

}




