package com.qunzhixinxi.hnqz.admin.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qunzhixinxi.hnqz.admin.api.entity.SysDictItem;
import com.qunzhixinxi.hnqz.admin.api.entity.SysUser;
import com.qunzhixinxi.hnqz.admin.api.entity.SysUserRole;
import com.qunzhixinxi.hnqz.admin.entity.WmTeam;
import com.qunzhixinxi.hnqz.admin.entity.model.excel.WmTeamExcelModel;
import com.qunzhixinxi.hnqz.admin.enums.DelEnum;
import com.qunzhixinxi.hnqz.admin.mapper.SysUserMapper;
import com.qunzhixinxi.hnqz.admin.mapper.SysUserRoleMapper;
import com.qunzhixinxi.hnqz.admin.mapper.WmTeamMapper;
import com.qunzhixinxi.hnqz.admin.service.SysDictItemService;
import com.qunzhixinxi.hnqz.admin.service.WmTeamService;
import com.qunzhixinxi.hnqz.common.security.util.SecurityUtils;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 团队管理服务
 *
 * @author lixuesong
 * @date 2021年12月08日 13:51
 */
@Slf4j
@Service
@AllArgsConstructor
public class WmTeamServiceImpl extends ServiceImpl<WmTeamMapper, WmTeam> implements WmTeamService {

	private final SysUserMapper sysUserMapper;

	private final SysUserRoleMapper sysUserRoleMapper;

	private final SysDictItemService sysDictItemService;

	/**
	 * 查询可选择的人员
	 *
	 * @param deptId
	 * @param teamId
	 * @param realNameOrPhone
	 * @return
	 */
	@Override
	public Map<String, Object> listSelectableUser(Integer deptId, Integer teamId, String realNameOrPhone) {
		Map<String, Object> resultMap = MapUtil.newHashMap(3);
		if (deptId == null) {
			deptId = SecurityUtils.getUser().getDeptId();
		}
		// 查询负责人user（药企管理员或CSO管理员）
		List<SysUser> leaderUserList = sysUserMapper.selectByDeptIdAndRoleId(deptId, realNameOrPhone, CollectionUtil.toList(3, 4));
		// 查询组成人员user（兼职学术信息沟通专员）
		List<SysUser> memberList = sysUserMapper.selectByDeptIdAndRoleId(deptId, realNameOrPhone, CollectionUtil.toList(6));
		// 该企业下所有团队的已配置人员
		List<WmTeam> deptTeamList = this.list(Wrappers.<WmTeam>lambdaQuery()
				.eq(WmTeam::getDeptId, deptId)
				.eq(WmTeam::getDelFlag, DelEnum.NOT_DEL.val()));
		Set<Integer> assignedUserSet = new HashSet<>();
		deptTeamList.forEach(wmTeam -> {
			if (StrUtil.isAllNotBlank(wmTeam.getMember())) {
				Set<Integer> memberSet = Stream.of(wmTeam.getMember())
						.map(Integer::parseInt)
						.collect(Collectors.toSet());
				assignedUserSet.addAll(memberSet);
			}
		});
		// 负责人列表
		List<Map<String, Object>> leaderList = leaderUserList.stream()
				.map(sysUser -> {
					Map<String, Object> userMap = MapUtil.newHashMap(3);
					userMap.put("realName", sysUser.getRealname());
					userMap.put("phone", sysUser.getUsername());
					userMap.put("userId", sysUser.getUserId());
					userMap.put("isLeader", true);
					return userMap;
				}).collect(Collectors.toList());
		// 未分配人员列表
		List<Map<String, Object>> notAssignedUserList = memberList.stream()
				.filter(sysUser -> !assignedUserSet.contains(sysUser.getUserId()))
				.map(sysUser -> {
					Map<String, Object> userMap = MapUtil.newHashMap(3);
					userMap.put("realName", sysUser.getRealname());
					userMap.put("phone", sysUser.getUsername());
					userMap.put("userId", sysUser.getUserId());
					userMap.put("isLeader", false);
					return userMap;
				}).collect(Collectors.toList());
		// 已分配人员列表
		List<Map<String, Object>> assignedUserList = memberList.stream()
				.filter(sysUser -> assignedUserSet.contains(sysUser.getUserId()))
				.map(sysUser -> {
					Map<String, Object> userMap = MapUtil.newHashMap(3);
					userMap.put("realName", sysUser.getRealname());
					userMap.put("phone", sysUser.getUsername());
					userMap.put("userId", sysUser.getUserId());
					userMap.put("isLeader", false);
					return userMap;
				}).collect(Collectors.toList());
		// 已选择的人员（leader+member）
		if (teamId != null) {
			WmTeam team = this.getById(teamId);
			List<String> selectedLeaderIds = CollectionUtil.toList(team.getLeader());
			List<String> selectedMemberIds = CollectionUtil.toList(team.getMember());
			if (CollectionUtil.isNotEmpty(selectedLeaderIds)) {
				List<SysUser> selectedLeaderUsers = sysUserMapper.selectBatchIds(selectedLeaderIds);
				List<Map<String, Object>> selectedLeaders = selectedLeaderUsers.stream()
						.map(sysUser -> {
							Map<String, Object> userMap = MapUtil.newHashMap(3);
							userMap.put("realName", sysUser.getRealname());
							userMap.put("phone", sysUser.getUsername());
							userMap.put("userId", sysUser.getUserId());
							userMap.put("isLeader", true);
							return userMap;
						}).collect(Collectors.toList());
				resultMap.put("selectedLeaders", selectedLeaders);
			} else {
				resultMap.put("selectedLeaders", new ArrayList<>());
			}
			if (CollectionUtil.isNotEmpty(selectedMemberIds)) {
				List<SysUser> selectedMemberUsers = sysUserMapper.selectBatchIds(selectedMemberIds);
				List<Map<String, Object>> selectedMembers = selectedMemberUsers.stream()
						.map(sysUser -> {
							Map<String, Object> userMap = MapUtil.newHashMap(3);
							userMap.put("realName", sysUser.getRealname());
							userMap.put("phone", sysUser.getUsername());
							userMap.put("userId", sysUser.getUserId());
							userMap.put("isLeader", false);
							return userMap;
						}).collect(Collectors.toList());
				resultMap.put("selectedMembers", selectedMembers);
			} else {
				resultMap.put("selectedMembers", new ArrayList<>());
			}
			resultMap.put("teamName", team.getName());
		} else {
			resultMap.put("selectedLeaders", new ArrayList<>());
			resultMap.put("selectedMembers", new ArrayList<>());
			resultMap.put("teamName", "");
		}
		resultMap.put("leaders", leaderList);
		resultMap.put("notAssignedMembers", notAssignedUserList);
		resultMap.put("assignedMembers", assignedUserList);

		return resultMap;
	}

	/**
	 * 查询接单对象范围名称
	 *
	 * @param packageUserScope
	 * @return
	 */
	@Override
	public String getPackageUserScopeName(String packageUserScope) {
		String packageUserScopeName = "";
		int packageUserScopeInt = Integer.parseInt(packageUserScope);
		if (packageUserScopeInt >= 1000) {
			// 1.查询当前企业下的团队
			WmTeam team = this.getById(packageUserScopeInt);
			packageUserScopeName = team.getName();
		} else {
			// 2.原有的字典数据项
			SysDictItem dictItem = sysDictItemService.getOne(Wrappers.<SysDictItem>lambdaQuery()
					.eq(SysDictItem::getType, "package_user_scope")
					.eq(SysDictItem::getValue, packageUserScope)
					.eq(SysDictItem::getDelFlag, DelEnum.NOT_DEL.val()));
			packageUserScopeName = dictItem.getLabel();
		}
		return packageUserScopeName;
	}

	/**
	 * 团队批量导入成员
	 *
	 * @param teamId
	 * @param excelMap
	 * @return
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public Map<String, String> batchImport(Integer teamId, Map<String, List<WmTeamExcelModel>> excelMap) {
		// 变量
		Map<String, String> errorMap = new HashMap<>();
		List<SysUser> currentList = new ArrayList<>();

		// 获取操作员
		WmTeam queryTeam = this.getById(teamId);

		// 业务值校验
		List<WmTeamExcelModel> repeatUserList = new ArrayList<>();
		for (Map.Entry<String, List<WmTeamExcelModel>> entry : excelMap.entrySet()) {
			checkoutUserInfo(entry.getValue(), queryTeam, errorMap, currentList, repeatUserList);
		}
		// 校验是否存在重复成员
		if (CollectionUtil.isNotEmpty(repeatUserList)) {
			List<String> nameList = repeatUserList.stream().map(WmTeamExcelModel::getRealname).collect(Collectors.toList());
			List<String> excelIdList = repeatUserList.stream().map(WmTeamExcelModel::getId).collect(Collectors.toList());
			log.error("用户在该团队已存在:{}", String.join(",", nameList));
			errorMap(errorMap, String.format("用户在该团队已存在'%s'", String.join(",", nameList)), String.join(",", excelIdList));
		}

		// 上传结果
		if (CollectionUtil.isEmpty(errorMap)) {
			String[] userIdArr = currentList.stream()
					.map(sysUser -> String.valueOf(sysUser.getUserId()))
					.toArray(String[]::new);
			// 增量添加成员
			String[] members = ArrayUtil.addAll(userIdArr, ArrayUtil.defaultIfEmpty(queryTeam.getMember(), new String[0]));
			WmTeam team = new WmTeam();
			team.setId(teamId);
			team.setMember(members);
			team.setUpdateTime(LocalDateTime.now());
			team.setUpdateUser(SecurityUtils.getUser().getId());
			this.updateById(team);
		}

		return errorMap;
	}

	/**
	 * 校验用户信息
	 *
	 * @param excelList      excel用户数据
	 * @param team           team对象
	 * @param errorMap       错误信息map
	 * @param currentList    正确数据list
	 * @param repeatUserList 重复成员用户list
	 */
	private void checkoutUserInfo(List<WmTeamExcelModel> excelList, WmTeam team, Map<String, String> errorMap,
								  List<SysUser> currentList, List<WmTeamExcelModel> repeatUserList) {
		log.info("开始校验数据：{}", excelList);

		if (excelList.size() != 1) {
			log.error("表中手机号重复");
			Set<String> idSet = excelList.stream().map(WmTeamExcelModel::getId).collect(Collectors.toSet());
			errorMap(errorMap, "表中手机号重复", JSONUtil.toJsonStr(idSet));
		}

		WmTeamExcelModel excel = excelList.get(0);

		SysUser insertUser = new SysUser();
		// 校验用户是否存在
		List<SysUser> sysUsers = sysUserMapper.selectList(Wrappers.<SysUser>lambdaQuery()
				.eq(SysUser::getDeptId, team.getDeptId())
				.eq(SysUser::getRealname, excel.getRealname())
				.eq(SysUser::getUsername, excel.getUsername())
				.eq(SysUser::getDelFlag, DelEnum.NOT_DEL.val()));
		SysUser sysUser = null;
		if (CollectionUtil.isEmpty(sysUsers)) {
			log.error("用户在当前企业不存在");
			errorMap(errorMap, "用户在当前企业不存在", excel.getId());
		} else {
			sysUser = sysUsers.get(0);
			insertUser.setUserId(sysUser.getUserId());
			insertUser.setRealname(sysUser.getRealname());
			insertUser.setUsername(sysUser.getUsername());
		}

		// 校验用户角色是否正确
		if (sysUser != null) {
			List<SysUserRole> sysUserRoles = sysUserRoleMapper.selectList(Wrappers.<SysUserRole>lambdaQuery()
					.eq(SysUserRole::getUserId, sysUser.getUserId()));
			if (CollectionUtil.isNotEmpty(sysUserRoles)) {
				List<Integer> roleList = sysUserRoles.stream().map(SysUserRole::getRoleId).collect(Collectors.toList());
				if (!roleList.contains(6)) {
					log.error("用户角色不正确");
					errorMap(errorMap, "用户角色不正确", excel.getId());
				}
			} else {
				log.error("用户角色异常");
				errorMap(errorMap, "用户角色异常", excel.getId());
			}
		}

		// 记录正确的结果
		currentList.add(insertUser);

		// 校验成员是否在当前团队中已存在
		if (ArrayUtil.isNotEmpty(team.getMember())) {
			if (ArrayUtil.contains(team.getMember(), String.valueOf(insertUser.getUserId()))) {
				repeatUserList.add(excel);
			}
		}
	}

	/**
	 * 封装错误信息
	 *
	 * @param errorMap 记录错误信息map
	 * @param key      原因
	 * @param idStr    错误id
	 */
	private void errorMap(Map<String, String> errorMap, String key, String idStr) {
		if (errorMap.containsKey(key)) {
			String val = errorMap.get(key);
			idStr = String.join(";", val, idStr);
		}
		errorMap.put(key, idStr);
	}
}
