package org.lingniu.idp.security.provider;

import org.lingniu.idp.security.token.SmsCodeAuthenticationToken;
import org.lingniu.idp.service.core.SmsCodeService;
import org.lingniu.idp.service.core.UserDetailsServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;

@Component
public class SmsCodeAuthenticationProvider implements AuthenticationProvider {
    
    @Autowired
    private SmsCodeService smsCodeService;
    
    @Autowired
    private UserDetailsServiceImpl userDetailsService;
    
    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        SmsCodeAuthenticationToken authenticationToken = (SmsCodeAuthenticationToken) authentication;
        String phone = (String) authenticationToken.getPrincipal();
        String code = (String) authenticationToken.getCredentials();
        
        // 1. 验证短信验证码
        if (!smsCodeService.verifyCode(phone, code)) {
            throw new BadCredentialsException("验证码错误或已过期");
        }
        
        // 2. 根据手机号查找用户
        UserDetails userDetails;
        try {
            // 这里可以根据手机号从数据库查询用户
            userDetails = loadUserByPhone(phone);
        } catch (UsernameNotFoundException e) {
            // 用户不存在，可以自动创建用户
            userDetails = createNewUser(phone);
        }
        
        // 3. 返回认证成功的Token
        return new SmsCodeAuthenticationToken(
            userDetails,
            null
        );
    }
    
    @Override
    public boolean supports(Class<?> authentication) {
        return SmsCodeAuthenticationToken.class.isAssignableFrom(authentication);
    }
    
    private UserDetails loadUserByPhone(String phone) {
        // 这里实现根据手机号查询用户的逻辑
        // 可以查询数据库，或者调用用户服务
        
        // 示例：假设手机号作为用户名
        return userDetailsService.loadUserByUsername(phone);
    }
    
    private UserDetails createNewUser(String phone) {
        // 用户不存在时自动创建
        return User.builder()
            .username(phone)
            .password("{noop}") // 无密码
            .authorities("ROLE_USER")
            .build();
    }
}