package me.qwq.doghouse.service;

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

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 com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.github.yulichang.wrapper.MPJLambdaWrapper;

import me.qwq.doghouse.component.Rk;
import me.qwq.doghouse.dao.UserMapper;
import me.qwq.doghouse.entity.User;
import me.qwq.doghouse.enums.FuncsEnum;

/**
 * 用户服务
 * @author Doghole
 *
 */
@Service
public class UserService extends BaseServiceImpl<UserMapper, User> implements UserDetailsService {
    
    /**
     * 针对已有用户，重新生成其邮箱对应的 Doghash
     * @return 重新生成的邮箱数
     */
    public Long reprepareDogHash() {
        List<User> users = list(
                new MPJLambdaWrapper<User>(User.class)
                .selectFunc(FuncsEnum.DISTINCT, User::getEmail)
        );
        List<String> distinctEmails = users.stream()
                .map(user -> user.getEmail().toLowerCase(Locale.ENGLISH))
                .distinct()
                .collect(Collectors.toList());
        distinctEmails.forEach(email -> Rk.Gravatar.prepareDogHash(email));
        return (long) distinctEmails.size();
    }

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        
        if (StringUtils.isBlank(username)) {
            throw new UsernameNotFoundException("用户不存在");
        }
        
        User user = getOne(new LambdaQueryWrapper<User>().eq(User::getUsername, username));
        if (user == null) {
            throw new UsernameNotFoundException("用户不存在");
        }
        return org.springframework.security.core.userdetails.User
                .withUsername(username)
                .password(user.getPassword())
                .roles("admin")
                .build();
    }
    
}
