package com.skr.mdm.authentication.admin;

import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.skr.mdm.dao.AuAdminDao;
import com.skr.mdm.dao.AuAdminRoleDao;
import com.skr.mdm.dao.AuPermissionDao;
import com.skr.mdm.dto.LoginAdminDTO;
import com.skr.mdm.entity.AuAdminRoleDO;
import com.skr.mdm.entity.AuAdministratorDO;
import com.skr.mdm.entity.AuPermissionDO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationCredentialsNotFoundException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author nfq
 */
@Service
@Slf4j
public class AdminDetailsServiceImpl implements UserDetailsService {

    @Autowired
    private AuAdminDao auAdminDao;
    @Autowired
    private AuPermissionDao auPermissionDao;
    @Autowired
    private AuAdminRoleDao adminRoleDao;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

        LambdaQueryChainWrapper<AuAdministratorDO> queryWrapper = new LambdaQueryChainWrapper<>(auAdminDao);
        AuAdministratorDO auAdministratorDO = queryWrapper
                .eq(AuAdministratorDO::getAdminName, username)
                .eq(AuAdministratorDO::getDeleted, 0)
                .one();

        if (auAdministratorDO == null) {
            throw new AuthenticationCredentialsNotFoundException("用户名不存在");
        }

        if (auAdministratorDO.getUsable() == 0) {
            throw new BlockedAccountException("该账户被冻结, 请联系管理员");
        }

        LoginAdminDTO loginAdminDTO = new LoginAdminDTO();
        BeanUtils.copyProperties(auAdministratorDO, loginAdminDTO);

        List<AuPermissionDO> listPermissionByAdminId = auPermissionDao.listPermissionByAdminId(loginAdminDTO.getId());
        if (CollectionUtils.isNotEmpty(listPermissionByAdminId)) {
            Set<String> permissionList = listPermissionByAdminId.stream().map(AuPermissionDO::getPercode).collect(Collectors.toSet());
            loginAdminDTO.setPermissionList(permissionList);
        }

        LambdaQueryChainWrapper<AuAdminRoleDO> queryChainWrapper = new LambdaQueryChainWrapper<>(adminRoleDao);
        AuAdminRoleDO adminRoleDO = queryChainWrapper.eq(AuAdminRoleDO::getAdminId, loginAdminDTO.getId()).one();
        if (adminRoleDO != null) {
            loginAdminDTO.setRoleId(adminRoleDO.getRoleId());
        }
        return loginAdminDTO;
    }

}
