
package com.tmerclub.cloud.platform.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.tmerclub.cloud.api.auth.constant.SysTypeEnum;
import com.tmerclub.cloud.api.auth.feign.AccountFeignClient;
import com.tmerclub.cloud.api.auth.vo.AuthAccountVO;
import com.tmerclub.cloud.api.platform.vo.SysUserVO;
import com.tmerclub.cloud.api.rbac.dto.UserRoleDTO;
import com.tmerclub.cloud.api.rbac.feign.UserRoleFeignClient;
import com.tmerclub.cloud.common.cache.constant.CacheNames;
import com.tmerclub.cloud.common.database.dto.PageDTO;
import com.tmerclub.cloud.common.database.util.PageUtil;
import com.tmerclub.cloud.common.database.vo.PageVO;
import com.tmerclub.cloud.common.exception.LuckException;
import com.tmerclub.cloud.common.leaf.manager.SegmentManager;
import com.tmerclub.cloud.common.response.ServerResponseEntity;
import com.tmerclub.cloud.constant.DistributedIdKey;
import com.tmerclub.cloud.platform.dto.SysUserDTO;
import com.tmerclub.cloud.platform.mapper.SysUserMapper;
import com.tmerclub.cloud.platform.model.SysUser;
import com.tmerclub.cloud.platform.service.SysUserService;
import com.tmerclub.cloud.platform.vo.SysUserSimpleVO;
import io.seata.spring.annotation.GlobalTransactional;
import jakarta.annotation.Resource;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

/**
 * @author lhd
 * @date 2020/12/22
 */
@Service
public class SysUserServiceImpl implements SysUserService {

    @Resource
    private SysUserMapper sysUserMapper;
    @DubboReference
    private AccountFeignClient accountFeignClient;
    @DubboReference
    private UserRoleFeignClient userRoleFeignClient;
    @Autowired
    private SegmentManager segmentManager;


    @Override
    @Cacheable(cacheNames = CacheNames.PLATFORM_SIMPLE_INFO_KEY, key = "#userId")
    public SysUserSimpleVO getSimpleByUserId(Long userId) {
        return sysUserMapper.getSimpleByUserId(userId);
    }

    @Override
    public PageVO<SysUserVO> pageByShopId(PageDTO pageDTO, SysUserDTO sysUserDTO) {
        PageVO<SysUserVO> page = PageUtil.doPage(pageDTO, () -> sysUserMapper.listByShopId(sysUserDTO));
        if (CollUtil.isEmpty(page.getList())) {
            return page;
        }
        List<Long> userIds = page.getList().stream().map(SysUserVO::getSysUserId).collect(Collectors.toList());
        ServerResponseEntity<List<AuthAccountVO>> responseEntity = accountFeignClient.listUserByUserIdsAndType(userIds, SysTypeEnum.PLATFORM.value());
        Map<Long, AuthAccountVO> authAccountMap = responseEntity.getData().stream().collect(Collectors.toMap(AuthAccountVO::getUserId, a -> a));
        for (SysUserVO sysUserVO : page.getList()) {
            AuthAccountVO authAccountVO = authAccountMap.get(sysUserVO.getSysUserId());
            if (Objects.nonNull(authAccountVO)) {
                sysUserVO.setIsAdmin(authAccountVO.getIsAdmin());
                sysUserVO.setStatus(authAccountVO.getStatus());
            }
        }
        return page;
    }

    @Override
    public SysUserVO getByUserId(Long userId) {
        SysUserVO sysUser = sysUserMapper.getByUserId(userId);
        ServerResponseEntity<List<Long>> roleIds = userRoleFeignClient.getRoleIds(sysUser.getSysUserId());
        sysUser.setRoleIds(roleIds.getData());
        return sysUser;
    }

    @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    @Transactional(rollbackFor = Exception.class)
    public void save(SysUser sysUser, List<Long> roleIds) {
        checkSysUser(sysUser);
        UserRoleDTO userRoleDTO = new UserRoleDTO();
        userRoleDTO.setRoleIds(roleIds);
        sysUser.setSysUserId(segmentManager.getSegmentId(DistributedIdKey.tmerclub_PLATFORM_USER));
        sysUserMapper.save(sysUser);
        if (CollUtil.isEmpty(roleIds)) {
            return;
        }
        userRoleDTO.setUserId(sysUser.getSysUserId());
        userRoleFeignClient.saveByUserIdAndSysType(userRoleDTO);
    }

    private void checkSysUser(SysUser sysUser) {
        // 修改，检查昵称是否重复，sys_user_id是不等于sysUserId
        if (sysUserMapper.countNickName(sysUser.getNickName(), sysUser.getSysUserId()) > 0) {
            throw new LuckException("该昵称已存在");
        }
    }

    @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    @Transactional(rollbackFor = Exception.class)
    @CacheEvict(cacheNames = CacheNames.PLATFORM_SIMPLE_INFO_KEY, key = "#sysUser.sysUserId")
    public void update(SysUser sysUser, List<Long> roleIds) {
        checkSysUser(sysUser);
        UserRoleDTO userRoleDTO = new UserRoleDTO();
        userRoleDTO.setRoleIds(roleIds);
        userRoleDTO.setUserId(sysUser.getSysUserId());
        userRoleDTO.setSysType(SysTypeEnum.PLATFORM.value());
        sysUserMapper.update(sysUser);
        userRoleFeignClient.updateByUserIdAndSysType(userRoleDTO);
    }

    @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    @Transactional(rollbackFor = Exception.class)
    @CacheEvict(cacheNames = CacheNames.PLATFORM_SIMPLE_INFO_KEY, key = "#sysUserId")
    public void deleteById(Long sysUserId) {
        ServerResponseEntity<Void> responseEntity = accountFeignClient.deleteByUserIdAndSysType(sysUserId);
        if (!responseEntity.isSuccess()) {
            throw new LuckException(responseEntity.getMsg());
        }
        userRoleFeignClient.deleteByUserIdAndSysType(sysUserId);
        sysUserMapper.deleteById(sysUserId);
    }

    @Override
    public List<SysUserVO> getUserNameMap(List<Long> userIds) {
        if (CollUtil.isEmpty(userIds)) {
            return new ArrayList<>(0);
        }
        return sysUserMapper.getUserName(userIds);
    }

}
