package com.xunhong.erp.turbo.rbac.infrastructure.gateway;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.xunhong.erp.turbo.api.rbac.dto.cmd.UserRoleCreateCmd;
import com.xunhong.erp.turbo.api.rbac.dto.cmd.UserRoleUpdateCmd;
import com.xunhong.erp.turbo.api.rbac.dto.qry.UserRoleListQry;
import com.xunhong.erp.turbo.rbac.domain.entity.UserRole;
import com.xunhong.erp.turbo.rbac.domain.gateway.UserRoleGateway;
import com.xunhong.erp.turbo.rbac.infrastructure.convert.UserRoleConvert;
import com.xunhong.erp.turbo.rbac.infrastructure.entity.UserRoleDO;
import com.xunhong.erp.turbo.rbac.infrastructure.mapper.UserRoleMapper;
import lombok.RequiredArgsConstructor;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Repository
@RequiredArgsConstructor
public class UserRoleGatewayImpl implements UserRoleGateway {
	private final UserRoleMapper userRoleMapper;
	private final UserRoleConvert userRoleConvert;
	private final SqlSessionFactory sqlSessionFactory;

	@Override
	@Transactional
	public void assignRole(Long userId, List<Long> roleIdList) {
		// 查询当前用户所有的权限，如果roleIdList不在里面则添加角色
		List<UserRoleDO> userRoleDOList = userRoleMapper.listByUserId(userId);
		List<Long> oldRoleIdList = userRoleDOList.stream().map(UserRoleDO::getRoleId).toList();
		roleIdList = roleIdList.stream().filter(roleId -> !oldRoleIdList.contains(roleId)).toList();

		SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH, false);
		UserRoleMapper userRoleMapper1 = sqlSession.getMapper(UserRoleMapper.class);

		for (Long roleId : roleIdList) {
			UserRoleDO userRoleDO = new UserRoleDO();
			userRoleDO.setUserId(userId);
			userRoleDO.setRoleId(roleId);
			userRoleMapper1.insert(userRoleDO);
		}

		sqlSession.commit();
		sqlSession.close();
	}

	@Override
	public List<UserRole> list(UserRoleListQry userRoleListQry) {
		QueryWrapper<UserRoleDO> queryWrapper = Wrappers.query(UserRoleDO.class);
		queryWrapper.eq(Objects.nonNull(userRoleListQry.getUserId()), "user_id", userRoleListQry.getUserId());
		queryWrapper.in(Objects.nonNull(userRoleListQry.getUserIdList()), "user_id", userRoleListQry.getUserIdList());
		queryWrapper.eq(Objects.nonNull(userRoleListQry.getPlatformId()), "platform_id", userRoleListQry.getPlatformId());

		queryWrapper.select("user_id", "role_id");
		List<UserRoleDO> userRoleDOList = userRoleMapper.selectList(queryWrapper);
		return userRoleDOList.stream().map(userRoleConvert::toUserRole).toList();
	}

	@Override
	public List<UserRole> create(UserRoleCreateCmd userRoleCreateCmd) {
		List<UserRoleDO> userRoleDOList = new ArrayList<>();

		SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH, false);
		UserRoleMapper userRoleMapper1 = sqlSession.getMapper(UserRoleMapper.class);

		for (Long roleId : userRoleCreateCmd.getRoleId()) {
			UserRoleDO userRoleDO = new UserRoleDO();
			userRoleDO.setUserId(userRoleCreateCmd.getUserId());
			userRoleDO.setRoleId(roleId);
			userRoleMapper1.insert(userRoleDO);
			userRoleDOList.add(userRoleDO);
		}

		sqlSession.commit();
		sqlSession.close();

		return userRoleDOList.stream().map(userRoleConvert::toUserRole).collect(Collectors.toList());
	}

	@Override
	@Transactional
	public List<UserRole> update(UserRoleUpdateCmd userRoleUpdateCmd) {
		List<UserRoleDO> userRoleDOList = new ArrayList<>();
		List<Long> roleIdList = userRoleUpdateCmd.getRoleIdList();

		if (userRoleUpdateCmd.getCover()) {
			// 删除角色关联
			LambdaQueryWrapper<UserRoleDO> queryWrapper = Wrappers.lambdaQuery(UserRoleDO.class);
			queryWrapper.eq(UserRoleDO::getUserId, userRoleUpdateCmd.getUserId());
			userRoleMapper.delete(queryWrapper);
		} else {
			// 获取角色列表，不存在则添加角色关联
			LambdaQueryWrapper<UserRoleDO> queryWrapper = Wrappers.lambdaQuery(UserRoleDO.class);
			queryWrapper.eq(UserRoleDO::getUserId, userRoleUpdateCmd.getUserId());
			List<UserRoleDO> userRoleDOList1 = userRoleMapper.selectList(queryWrapper);

			List<Long> oldRoleIdList = userRoleDOList1.stream().map(UserRoleDO::getRoleId).toList();
			roleIdList = roleIdList.stream().filter(roleId -> !oldRoleIdList.contains(roleId)).toList();
		}

		// 角色为空，则不处理
		if (roleIdList.isEmpty()) {
			return new ArrayList<>();
		}

		SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH, false);
		UserRoleMapper userRoleMapper1 = sqlSession.getMapper(UserRoleMapper.class);

		// 创建新角色关联
		for (Long roleId : roleIdList) {
			UserRoleDO userRoleDO = new UserRoleDO();
			userRoleDO.setUserId(userRoleUpdateCmd.getUserId());
			userRoleDO.setRoleId(roleId);
			userRoleMapper1.insert(userRoleDO);
			userRoleDOList.add(userRoleDO);
		}

		sqlSession.commit();
		sqlSession.close();

		return userRoleDOList.stream().map(userRoleConvert::toUserRole).collect(Collectors.toList());
	}
}
