package com.zjty.tynotes.pas.config;

import com.zjty.tynotes.pas.config.handler.MyFailHandler;
import com.zjty.tynotes.pas.dao.AuthorityDao;
import com.zjty.tynotes.pas.dao.RoleAuthorityDao;
import com.zjty.tynotes.pas.dao.RoleDao;
import com.zjty.tynotes.pas.dao.UserRoleDao;
import com.zjty.tynotes.pas.entity.*;
import com.zjty.tynotes.pas.service.IAuthorityService;
import com.zjty.tynotes.pas.service.IRoleService;
import com.zjty.tynotes.pas.service.IUserService;
import com.zjty.tynotes.pas.task.Init;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.session.SessionRegistry;
import org.springframework.security.core.session.SessionRegistryImpl;
import org.springframework.security.core.userdetails.UserDetails;
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.web.authentication.session.SessionAuthenticationException;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

/**
 * @author mcj
 */
@Service
public class MyUserDetailsServiceImpl implements UserDetailsService {
    @Autowired
    private BCryptPasswordEncoder bCryptPasswordEncoder;

    @Autowired
    IUserService iUserService;
    @Autowired
    RoleDao roleDao;
    @Autowired
    private UserRoleDao userRoleDao;
    @Autowired
    private RoleAuthorityDao roleAuthorityDao;
    @Autowired
    private AuthorityDao authorityDao;

    @Autowired
    private Init init;
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException{
        System.out.println("userService验证:" + username);

        if(username.equals("root")){
            User root = init.root;
//            root.setPassword("root");
//            root.setPassword(bCryptPasswordEncoder.encode("root"));
            List<SimpleGrantedAuthority> authorityList = new ArrayList<>();
            List<Role> roles = root.getRoles();
            Role role = roles.get(0);
            List<Authority> authorities = role.getAuthorities();

            SimpleGrantedAuthority s = new SimpleGrantedAuthority("管理员");
            for (Authority authority : authorities) {
                authorityList.add(new SimpleGrantedAuthority(authority.getName()));
            }
            root.setArrayList(authorityList);
            return root;
        }else{
            User user = iUserService.findUserByUsername(username);
            if(user!=null){
                List<UserRole> userRoles = userRoleDao.findAllByUserId(user.getId());
                List<String> roleIds = new ArrayList<>();
                if(userRoles!=null){
                    for (UserRole userRole : userRoles) {
                        roleIds.add(userRole.getRoleId());
                    }
                }
                user.setUsername(username);
//                user.setPassword(bCryptPasswordEncoder.encode(user.getPassword()));
                ArrayList<SimpleGrantedAuthority> list = new ArrayList<>();
                List<Role> roles = roleDao.findAllByIdIn(roleIds);
                List<RoleAuthority> roleAuthorities = roleAuthorityDao.findAllByRoleIdIn(roleIds);
                List<String> authorityIds = new ArrayList<>();
                if(roleAuthorities!=null){
                    for (RoleAuthority roleAuthority : roleAuthorities) {
                        if(!authorityIds.contains(roleAuthority.getAuthorityId())){
                            authorityIds.add(roleAuthority.getAuthorityId());
                        }
                    }
                }

                List<Authority> authorities = authorityDao.findAllByIdIn(authorityIds);
                authorities.forEach(authority -> {
                    list.add(new SimpleGrantedAuthority(authority.getName()));
                });
                user.setArrayList(list);
        }

            if(user==null){
                throw new UsernameNotFoundException("用户名或密码不正确");
            }
            return user;
        }
    }
}
