package com.yonge.cooleshow.auth.core.provider.service;

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

import com.yonge.cooleshow.api.feign.AdminFeignService;
import com.yonge.cooleshow.api.feign.dto.EmployeeApi;
import com.yonge.cooleshow.api.feign.dto.StudentApi;
import com.yonge.cooleshow.api.feign.dto.TeacherApi;
import com.yonge.cooleshow.common.enums.SysUserType;
import com.yonge.cooleshow.common.enums.UserLockFlag;
import com.yonge.cooleshow.common.util.WebUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.LockedException;
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.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import com.yonge.cooleshow.auth.api.dto.SysUserInfo;
import com.yonge.cooleshow.auth.api.entity.SysUser;
import com.yonge.cooleshow.auth.service.SysUserService;
import com.yonge.cooleshow.common.security.AuthUser;
import com.yonge.cooleshow.common.security.SecurityConstants;

import javax.annotation.Resource;

@Service
public class DefaultUserDetailsService implements UserDetailsService {

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Autowired
    private SysUserService sysUserService;

    @Resource
    private AdminFeignService adminFeignService;

    private final String BCRYPT = "{bcrypt}";

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        if (StringUtils.isBlank(username)) {
            return null;
        }
        String clientId = WebUtil.getParameter("clientId").toUpperCase();
        String clientSecret = WebUtil.getParameter("clientSecret");

        SysUserInfo userInfo;

        if (StringUtils.startsWith(username, SecurityConstants.PHONE_PRINCIPAL_PREFIX)) {
            userInfo = sysUserService.queryUserInfoByPhone(StringUtils.substringAfter(username, SecurityConstants.PHONE_PRINCIPAL_PREFIX));
        } else if (StringUtils.startsWith(username, SecurityConstants.USERNAME_PRINCIPAL_PREFIX)) {
            userInfo = sysUserService.queryUserInfoByUsername(StringUtils.substringAfter(username, SecurityConstants.USERNAME_PRINCIPAL_PREFIX));
        } else {
            userInfo = sysUserService.queryUserInfoByUsername(username);
        }
        SysUser sysUser = userInfo.getSysUser();

        if (userInfo == null || sysUser == null) {
            throw new UsernameNotFoundException("账户不存在");
        } else if (sysUser.getLockFlag() == 9) {
            throw new LockedException("账户被锁定");
        }
        //判断用户是否被锁定
        if (SysUserType.STUDENT.getCode().equals(clientId)) {
            StudentApi data = adminFeignService.getStudent(sysUser.getId()).getData();
            if (data == null) {
                throw new UsernameNotFoundException("账户不存在");
            }
            if (UserLockFlag.LOCKED.equals(data.getLockFlag())) {
                throw new LockedException("账户被锁定");
            }
        }else if(SysUserType.TEACHER.getCode().equals(clientId)) {
            TeacherApi data = adminFeignService.getTeacher(sysUser.getId()).getData();
            if (data == null) {
                throw new UsernameNotFoundException("账户不存在");
            }
            if (UserLockFlag.LOCKED.equals(data.getLockFlag())) {
                throw new LockedException("账户被锁定");
            }
        }else if(SysUserType.SYSTEM.getCode().equals(clientId)) {
            EmployeeApi data = adminFeignService.getEmployee(sysUser.getId()).getData();
            if (data == null) {
                throw new UsernameNotFoundException("账户不存在");
            }
            if (UserLockFlag.LOCKED.equals(data.getLockFlag())) {
                throw new LockedException("账户被锁定");
            }
        }

        List<GrantedAuthority> authorities = null;

        String userType = sysUser.getUserType();
        String[] roles = userType.split(",");

        if (userType.contains("SYSTEM")) {
            authorities = AuthorityUtils.createAuthorityList(userInfo.getPermissions());
        }

        if (authorities == null) {
            authorities = new ArrayList<>();
        }

        authorities.add(new SimpleGrantedAuthority(StringUtils.lowerCase(userType)));

        for (String role : roles) {
            authorities.add(new SimpleGrantedAuthority(StringUtils.lowerCase(role)));
        }

        return new AuthUser(sysUser.getId(), username, BCRYPT + sysUser.getPassword(), sysUser.getLockFlag() == 0, true, true, true, authorities, clientId, clientSecret);
    }

}
