/*
 * Copyright (c) 2020 yifu4cloud Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.yifu.cloud.plus.v1.yifu.admin.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yifu.cloud.plus.v1.yifu.admin.api.entity.SysDept;
import com.yifu.cloud.plus.v1.yifu.admin.api.entity.SysUser;
import com.yifu.cloud.plus.v1.yifu.admin.api.entity.SysUserDeptPermission;
import com.yifu.cloud.plus.v1.yifu.admin.api.vo.SysCspDeptVo;
import com.yifu.cloud.plus.v1.yifu.admin.api.vo.UserCspVO;
import com.yifu.cloud.plus.v1.yifu.admin.constants.UserDeptPermConstants;
import com.yifu.cloud.plus.v1.yifu.admin.mapper.SysDeptMapper;
import com.yifu.cloud.plus.v1.yifu.admin.mapper.SysUserDeptPermissionMapper;
import com.yifu.cloud.plus.v1.yifu.admin.mapper.SysUserMapper;
import com.yifu.cloud.plus.v1.yifu.admin.service.SysUserDeptPermissionService;
import com.yifu.cloud.plus.v1.yifu.common.core.constant.CacheConstants;
import com.yifu.cloud.plus.v1.yifu.common.core.constant.ClientNameConstants;
import com.yifu.cloud.plus.v1.yifu.common.core.constant.CommonConstants;
import com.yifu.cloud.plus.v1.yifu.common.core.util.Common;
import com.yifu.cloud.plus.v1.yifu.common.core.util.R;
import com.yifu.cloud.plus.v1.yifu.common.core.util.RedisUtil;
import com.yifu.cloud.plus.v1.yifu.common.core.vo.UserPermissionVo;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 项目下用户部门及权限
 *
 * @author chenyuxi
 * @since 1.9.7
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class SysUserDeptPermissionServiceImpl extends ServiceImpl<SysUserDeptPermissionMapper, SysUserDeptPermission> implements SysUserDeptPermissionService {

	private final RedisUtil redisUtil;

	private final SysDeptMapper sysDeptMapper;

	private final SysUserMapper sysUserMapper;

	private static final PasswordEncoder ENCODER = new BCryptPasswordEncoder();

	/**
	 * 项目下用户的部门，数据权限配置信息
	 * @param projectNo 项目编号
	 * @param userId    用户ID
	 *
	 * @return UserPermissionVo 用户在指定项目下的权限
	 */
	@Override
	public SysUserDeptPermission getInfo(String projectNo, String userId) {
		LambdaQueryWrapper<SysUserDeptPermission> permissionQuery = Wrappers.<SysUserDeptPermission>lambdaQuery()
				.eq(SysUserDeptPermission::getUserId, userId)
				.eq(SysUserDeptPermission::getProjectNo, projectNo)
				.last(" limit 1 ");
		return baseMapper.selectOne(permissionQuery);
	}



	/**
	 * 客户服务平台——用户权限控制
	 *
	 * @param sysUserDeptPermission 实体
	 * @return success/false
	 */
	@Override
	public R<String> saveUserPermission(SysUserDeptPermission sysUserDeptPermission) {

		LambdaQueryWrapper<SysUser> userQuery = Wrappers.<SysUser>lambdaQuery()
				.eq(SysUser::getUserId, sysUserDeptPermission.getUserId())
				.eq(SysUser::getDelFlag, CommonConstants.ZERO_STRING)
				.last(" limit 1 ");
		SysUser userInfo = sysUserMapper.selectOne(userQuery);
		if (Common.isEmpty(userInfo)) {
			return R.failed("未找到对应用户信息");
		}
		LambdaQueryWrapper<SysUserDeptPermission> permissionQuery = Wrappers.<SysUserDeptPermission>lambdaQuery()
				.eq(SysUserDeptPermission::getUserId, sysUserDeptPermission.getUserId())
				.eq(SysUserDeptPermission::getProjectNo, sysUserDeptPermission.getProjectNo())
				.last(" limit 1 ");
		SysUserDeptPermission permissionInfo = baseMapper.selectOne(permissionQuery);
		if (Common.isEmpty(permissionInfo)) {
			return R.failed("未找到对应用户部门信息");
		}
		LambdaQueryWrapper<SysDept> deptQuery = Wrappers.<SysDept>lambdaQuery()
				.eq(SysDept::getDeptId, permissionInfo.getDeptId())
				.eq(SysDept::getDelFlag, CommonConstants.ZERO_STRING)
				.last(" limit 1 ");
		SysDept deptInfo = sysDeptMapper.selectOne(deptQuery);
		if (Common.isEmpty(deptInfo)) {
			return R.failed("异常数据，对应用户部门不存在");
		}
		String ancestors = deptInfo.getAncestors();
		if (Common.isEmpty(ancestors)) {
			return R.failed("异常数据，该用户所属部门关系为空");
		}
		String[] ancestorsSplit = ancestors.split(CommonConstants.COMMA_STRING);
		if (ancestorsSplit.length < 2 && CommonConstants.ONE_STRING.equals(sysUserDeptPermission.getPermissionsType())) {
			return R.failed("当前用户所在部门为顶级部门，不能使用该权限");
		}

		// 更新用户数据权限
		permissionInfo.setPermissionsType(sysUserDeptPermission.getPermissionsType());
		if(!CommonConstants.THREE_STRING.equals(sysUserDeptPermission.getPermissionsType())){
			sysUserDeptPermission.setAppointDeptScope("");
		}
		permissionInfo.setAppointDeptScope(sysUserDeptPermission.getAppointDeptScope());
		baseMapper.updateById(permissionInfo);
		redisUtil.remove(CacheConstants.USER_DETAILS +"::"+ userInfo.getUsername());

		return R.ok("更新成功");
	}

	/**
	 * 客户服务平台——绑定项目
	 *
	 * @param sysUserDeptPermission 实体
	 * @return success/false
	 */
	@Override
	public R<String> relationUser(SysUserDeptPermission sysUserDeptPermission) {

		LambdaQueryWrapper<SysUser> userQuery = Wrappers.<SysUser>lambdaQuery()
				.eq(SysUser::getUserId, sysUserDeptPermission.getUserId())
				.eq(SysUser::getDelFlag, CommonConstants.ZERO_STRING)
				.last(" limit 1 ");
		SysUser userInfo = sysUserMapper.selectOne(userQuery);
		if (Common.isEmpty(userInfo)) {
			return R.failed("未找到对应用户信息");
		}
		LambdaQueryWrapper<SysUserDeptPermission> permissionQuery = Wrappers.<SysUserDeptPermission>lambdaQuery()
				.eq(SysUserDeptPermission::getUserId, sysUserDeptPermission.getUserId())
				.eq(SysUserDeptPermission::getProjectNo, sysUserDeptPermission.getProjectNo())
				.last(" limit 1 ");
		SysUserDeptPermission permissionInfo = baseMapper.selectOne(permissionQuery);
		if (Common.isNotNull(permissionInfo)) {
			return R.failed("该用户已绑定到项目下了，请勿重复绑定");
		}

		// 更新用户数据权限
		sysUserDeptPermission.setClient(ClientNameConstants.CLIENT_CSP);
		sysUserDeptPermission.setPermissionsType(CommonConstants.TWO_STRING);
		baseMapper.insert(sysUserDeptPermission);
		redisUtil.remove(CacheConstants.USER_DETAILS +"::"+ userInfo.getUsername());

		return R.ok("用户绑定项目成功");
	}
	/**
	 * @Author fxj
	 * @Description 既有接口‘通过用户ID获取用户的权限相关信息返回数组’
	 * @Date 11:26 2025/2/26
	**/
	@Override
	public List<UserPermissionVo> getUserPermission(String userId) {
		UserPermissionVo authority;
		List permissionMapByProject = new ArrayList<>();
		if (Common.isEmpty(userId)) {
			return permissionMapByProject;
		}

		String deptIdSplit = "";
		Long deptId = 0L;
		Set<String> permissionDbSet = null;

		List<SysUserDeptPermission> tPermissionInfoList = baseMapper.getUserDeptPermissionList(userId);
		if (Common.isEmpty(tPermissionInfoList)) {
			return permissionMapByProject;
		}
		Set<String> projectNoSet = tPermissionInfoList.stream().map(SysUserDeptPermission::getProjectNo).collect(Collectors.toSet());
		Map<String, SysUserDeptPermission> tPermissionMap = tPermissionInfoList.stream().collect(Collectors.toMap(SysUserDeptPermission::getProjectNo, v -> v, (v1, v2) -> v1));
		SysUserDeptPermission tPermissionInfo;
		SysDept sysDept;
		List<SysDept> sysDeptList;
		String[] ancestorsSplit;
		for (String projectNoStr : projectNoSet) {
			tPermissionInfo = tPermissionMap.get(projectNoStr);
			// 没有配置部门
			if(Common.isEmpty(tPermissionInfo)){
				authority = new UserPermissionVo();
				authority.setHaveAll(false);
				continue;
			}else {
				authority = new UserPermissionVo();
				authority.setProjectNo(projectNoStr);
				authority.setProjectName(tPermissionInfo.getProjectName());
				authority.setUserType(tPermissionInfo.getUserType());
				authority.setProjectId(tPermissionInfo.getProjectId());
				if (CommonConstants.ZERO_STRING.equals(tPermissionInfo.getPermissionsType())) {
					// 全部数据
					authority.setHaveAll(true);
				} else if (CommonConstants.THREE_STRING.equals(tPermissionInfo.getPermissionsType())) {
					// 指定部门权限
					if (Common.isNotKong(tPermissionInfo.getAppointDeptScope())) {
						authority.setHaveAll(false);
						String[] appointDeptIdArr = tPermissionInfo.getAppointDeptScope().split(CommonConstants.COMMA_STRING);
						Set<String> appointDeptIdSet = Arrays.stream(appointDeptIdArr).collect(Collectors.toSet());
						// 过滤被删除的数据
						sysDeptList = sysDeptMapper.getDeptListByDeptIdSet(appointDeptIdSet);
						Set<String> normalDeptIdSet = new HashSet<>();
						if(Common.isNotNull(sysDeptList)){
							for(SysDept dept : sysDeptList){
								normalDeptIdSet.add(dept.getDeptId().toString());
							}
						}
						authority.setDepartIdSet(normalDeptIdSet);
						authority.setUserId(userId);
					} else {
						authority.setHaveAll(false);
						continue;
					}
				} else {
					sysDept = sysDeptMapper.selectById(tPermissionInfo.getDeptId());
					if (Common.isNotKong(sysDept)) {
						String ancestors = sysDept.getAncestors();
						if (Common.isEmpty(ancestors)) {
							authority.setHaveAll(false);
							continue;
						}
						ancestorsSplit = ancestors.split(CommonConstants.COMMA_STRING);
						if (CommonConstants.ONE_STRING.equals(tPermissionInfo.getPermissionsType())) {
							// 二级部门及以下
							if (ancestorsSplit.length == 2) {
								deptIdSplit = ancestorsSplit[0] + CommonConstants.COMMA_STRING + ancestorsSplit[1] + CommonConstants.COMMA_STRING + sysDept.getDeptId();
								deptId = sysDept.getDeptId();
							} else if (ancestorsSplit.length > 2) {
								deptIdSplit = ancestorsSplit[0] + CommonConstants.COMMA_STRING + ancestorsSplit[1] + CommonConstants.COMMA_STRING + ancestorsSplit[2];
								deptId = Long.valueOf(ancestorsSplit[2]);
							} else {
								authority.setHaveAll(false);
								continue;
							}
						} else if (CommonConstants.TWO_STRING.equals(tPermissionInfo.getPermissionsType())) {
							// 本级部门及以下
							deptIdSplit = ancestors + CommonConstants.COMMA_STRING + sysDept.getDeptId();
							deptId = sysDept.getDeptId();
						}
						// 获取指定部门及下级部门的数据
						sysDeptList = sysDeptMapper.getDeptListByDeptId(deptIdSplit, deptId);
						if (Common.isNotKong(sysDeptList)) {
							permissionDbSet = new HashSet<>();
							for(SysDept deptOne : sysDeptList){
								permissionDbSet.add(String.valueOf(deptOne.getDeptId()));
							}
							authority.setHaveAll(false);
							authority.setDepartIdSet(permissionDbSet);
							authority.setUserId(userId);
						} else {
							authority.setHaveAll(false);
							continue;
						}
					} else {
						authority.setHaveAll(false);
						continue;
					}
				}
			}
			// 赋值用户在不同项目下的权限
			permissionMapByProject.add(authority);
		}

		return permissionMapByProject;
	}
	/**
	 * @Author fxj
	 * @Description 新增客户服务平台用户 及  用户权限关系表
	 * @Date 11:24 2025/2/26
	**/
	@Override
	public R<Boolean> saveAsso(UserCspVO entity) {
		long count = sysUserMapper.selectCount(Wrappers.<SysUser>query().lambda()
				.eq(SysUser::getUsername,entity.getUsername())
				.eq(SysUser::getDelFlag, CommonConstants.ZERO_STRING));
		if ( count > CommonConstants.ZERO_INT) {
			return R.failed(UserDeptPermConstants.USER_EXITS_ERROR);
		}
		SysUser user = new SysUser();
		user.setUserGroup("0");
		user.setDeptId(entity.getDeptId());
		user.setDeptName(entity.getDeptName());
		user.setType(CommonConstants.FOUR_STRING);
		user.setDelFlag(CommonConstants.STATUS_NORMAL);
		user.setSystemFlag(CommonConstants.ONE_STRING);
		user.setUsername(entity.getUsername());
		user.setNickname(entity.getNickname());
		user.setPhone(entity.getPhone());
		user.setLockFlag(CommonConstants.STATUS_NORMAL);
		user.setPassword(ENCODER.encode(UserDeptPermConstants.DEFAULT_PASSWORD));
		user.setPost(UserDeptPermConstants.CUSTOMER_SERVICE_PLATFORM);
		user.setLockFlag(CommonConstants.STATUS_NORMAL);
		user.setDelFlag(CommonConstants.STATUS_NORMAL);
		user.setCreateTime(LocalDateTime.now());
		sysUserMapper.insert(user);
		if (Common.isNotNull(user) &&  Common.isNotNull(user.getUserId())){
			SysUserDeptPermission permission = new SysUserDeptPermission();
			permission.setDeptId(entity.getDeptId());
			permission.setUserId(user.getUserId());
			permission.setClient(ClientNameConstants.CLIENT_CSP);
			permission.setProjectName(entity.getProjectName());
			permission.setProjectNo(entity.getProjectNo());
			permission.setUserType(entity.getUserType());
			permission.setProjectId(entity.getProjectId());
			baseMapper.insert(permission);
			if (Common.isNotNull(permission) &&  Common.isNotNull(permission.getUserId())){
				return R.ok(Boolean.TRUE,CommonConstants.SAVE_SUCCESS);
			}
		}
		return R.failed(Boolean.FALSE,CommonConstants.SAVE_FAILED);
	}
	/**
	 * @Author fxj
	 * @Description 更新客服服务平台用户信息
	 * @Date 11:26 2025/2/26
	**/
	@Override
	public R<Boolean> updateByIdAsso(UserCspVO entity) {
		try {
			if (Common.isEmpty(entity) || Common.isEmpty(entity.getUserId())){
				return R.failed(CommonConstants.PARAM_IS_NOT_ERROR);
			}
			SysUser user  = sysUserMapper.selectById(entity.getUserId());
			if (Common.isEmpty(user)){
				return R.failed(CommonConstants.NO_DATA_TO_HANDLE);
			}
			SysUserDeptPermission permission = baseMapper.selectOne(Wrappers.<SysUserDeptPermission>query().lambda()
					.eq(SysUserDeptPermission::getUserId,user.getUserId())
					.eq(SysUserDeptPermission::getProjectNo,entity.getProjectNo()).last(CommonConstants.LAST_ONE_SQL));
			if (Common.isEmpty(permission)){
				return R.failed(CommonConstants.NO_DATA_TO_HANDLE);
			}
			user.setNickname(entity.getNickname());
			user.setPhone(entity.getPhone());
			user.setDeptName(entity.getDeptName());
			user.setDeptId(entity.getDeptId());
			LambdaUpdateWrapper<SysUser> updateWrappers = new LambdaUpdateWrapper<>();
			updateWrappers.eq(SysUser::getUserId,user.getUserId());
			updateWrappers.set(SysUser::getNickname,entity.getNickname());
			updateWrappers.set(SysUser::getPhone,entity.getPhone());
			if (CommonConstants.FOUR_STRING.equals(user.getType())){
				updateWrappers.set(SysUser::getDeptName,entity.getDeptName());
				updateWrappers.set(SysUser::getDeptId,entity.getDeptId());
			}
			sysUserMapper.update(null,updateWrappers);
			permission.setDeptId(entity.getDeptId());
			permission.setUserType(entity.getUserType());
			baseMapper.updateById(permission);
			redisUtil.remove(CacheConstants.USER_DETAILS +"::"+ user.getUsername());
		}catch (Exception e){
			log.error(UserDeptPermConstants.PERMISSION_SAVE_ERROR,e);
			return R.failed(UserDeptPermConstants.PERMISSION_SAVE_ERROR);
		}
		return R.ok(null,CommonConstants.SAVE_SUCCESS);
	}
	/**
	 * @Author fxj
	 * @Description 收回账号
	 * @Date 11:24 2025/2/26
	 * @Param
	 * @return
	**/
	@Override
	public R<Boolean> removeUserDeptPermissionById(String userId, String projectNo) {
		SysUserDeptPermission permission = baseMapper.selectOne(Wrappers.<SysUserDeptPermission>query().lambda()
				.eq(SysUserDeptPermission::getUserId,userId)
				.eq(SysUserDeptPermission::getProjectNo,projectNo)
				.last(CommonConstants.LAST_ONE_SQL));
		if (Common.isNotNull(permission) && CommonConstants.ZERO_STRING.equals(permission.getUserType())){
			return R.failed(UserDeptPermConstants.ADMIN_DISABLE_ERROR);
		}
		if (Common.isEmpty(permission)){
			return R.failed(CommonConstants.PARAM_IS_NOT_ERROR);
		}
		SysUser user = sysUserMapper.selectById(userId);
		if (Common.isEmpty(user)){
			return  R.failed(CommonConstants.PARAM_IS_NOT_ERROR);
		}
		if (baseMapper.deleteById(permission.getId()) > CommonConstants.ZERO_INT){
			redisUtil.remove(CacheConstants.USER_DETAILS +"::"+ user.getUsername());
			return R.ok(Boolean.TRUE,CommonConstants.RESULT_DATA_SUCESS);
		}
		return R.failed(Boolean.FALSE,CommonConstants.RESULT_DATA_FAIL);
	}

	@Override
	public SysCspDeptVo selectCasDeptVo(String userId, String projectId) {
		return baseMapper.selectCasDeptVo(userId,projectId);
	}
}
