package com.yiboshi.science.config.security;


import com.yiboshi.science.enumeration.CommonEnum;
import com.yiboshi.science.param.dto.SystemUserDTO;
import com.yiboshi.science.service.SystemRoleService;
import com.yiboshi.science.service.SystemUserService;
import lombok.AllArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.InternalAuthenticationServiceException;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.Objects;

@Service
@AllArgsConstructor
public class UserDetailsServiceImpl implements UserDetailsService {

    @Autowired
    private SystemUserService systemUserService;

    @Autowired
    private SystemRoleService systemRoleService;

    private PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    public SecurityUser loadUserByUsername(String username) throws UsernameNotFoundException {
        SystemUserDTO dto = systemUserService.findByName(username);
        if (null == dto)
            throw new UsernameNotFoundException(String.format("No user found with username '%s'.", username));

        if (!dto.getNoteState().equals(CommonEnum.userState.normal.getCode()))
            throw new InternalAuthenticationServiceException("User has been disabled!");

        if (Objects.isNull(dto.getRoles()) || dto.getRoles().equals(""))
            throw new InternalAuthenticationServiceException("Role does not exist!");

        if (!dto.getRoles().contains(CommonEnum.systemRole.sys.getCode().toString())) {
            if (!dto.getUnitState().equals(CommonEnum.unitState.normal.getCode()))
                throw new InternalAuthenticationServiceException("User has been disabled!");
        }
        String authority = systemRoleService.getAuthorityByRoleId(dto.getRoles());
        return new SecurityUser(dto.getId(), dto.getPersonId(), dto.getUsername(), passwordEncoder().encode(dto.getPassword()),
                dto.getPersonName(), dto.getRoles(), dto.getUnitId(), dto.getUnitCode(), dto.getUnitName(), dto.getExpertId(),
                dto.getNoteState(), AuthorityUtils.commaSeparatedStringToAuthorityList(authority)
        );
    }
}
