package com.jkcredit.invoice.hub.service.security;

import com.jkcredit.invoice.hub.config.SelfUserDetails;
import com.jkcredit.invoice.hub.model.po.user.UserPo;
import com.jkcredit.invoice.hub.model.po.permission.PermissionPo;
import com.jkcredit.invoice.hub.service.permission.PermissionService;
import com.jkcredit.invoice.hub.service.user.UserService;
import com.jkcredit.invoice.hub.spi.lang.exception.ServiceException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
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.Component;

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

@Component("userDetailsService")
public class CustomUserDetailsService implements UserDetailsService {

    private final Logger log = LoggerFactory.getLogger(CustomUserDetailsService.class);

    @Autowired
    UserService userService;
    @Autowired
    PermissionService permissionService;

    @Override
    public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
        log.info("Authenticating {}", s);

        String lowercaseLogin = s.toLowerCase(Locale.ENGLISH);
        Optional<UserPo> userPo = userService.getUserByUserName(lowercaseLogin);

        return userPo.map(user -> createSpringSecurityUser(lowercaseLogin, user))
                .orElseThrow(() -> new UsernameNotFoundException("user " + lowercaseLogin + " was not found in the database"));
    }

    private UserDetails createSpringSecurityUser(String lowercaseLogin, UserPo user) {
        SelfUserDetails selfUserDetails = new SelfUserDetails();
        if (!user.getActivated().equals(1)) {
            throw new ServiceException("user " + lowercaseLogin + " was not activated");
        }

        List<PermissionPo> permissionPoList = permissionService.getPermissionByUserId(user.getId());
        List<GrantedAuthority> grantedAuthorities = new ArrayList<>();
        for (PermissionPo permissionPo : permissionPoList) {
            if (permissionPo.getActivated().equals(1)) {
                SimpleGrantedAuthority simpleGrantedAuthority = new SimpleGrantedAuthority(permissionPo.getPermission());
                grantedAuthorities.add(simpleGrantedAuthority);
            }
        }
        selfUserDetails.setUsername(user.getUsername());
        selfUserDetails.setPassword(user.getPassword());
        selfUserDetails.setAuthorities(grantedAuthorities);
//        return new org.springframework.security.core.userdetails.User(user.getUsername(), user.getPassword(), grantedAuthorities);
        return selfUserDetails;
    }
}
