package com.zjty.tynotes.pas.config.handler;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.zjty.tynotes.pas.entity.Authority;
import com.zjty.tynotes.pas.entity.Role;
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.entity.User;
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 lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.session.SessionInformation;
import org.springframework.security.core.session.SessionRegistry;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.session.SessionAuthenticationException;
import org.springframework.security.web.session.ConcurrentSessionFilter;
import org.springframework.stereotype.Component;

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

/**
 * @author mcj
 */
@Component
@Slf4j
public class MySuccessHandler implements AuthenticationSuccessHandler {
    @Autowired
    private SessionRegistry sessionRegistry;

    @Autowired
    private IAuthorityService iAuthorityService;

    @Autowired
    IRoleService iRoleService;

    private BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();

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



    @Autowired
    RedisTemplate redisTemplate;

    @Override
    public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
        Cookie[] cookies = httpServletRequest.getCookies();
        if(cookies==null){
            return;
        }
        String value = cookies[0].getValue();
        List<Object> o = sessionRegistry.getAllPrincipals();
        User user = (User) authentication.getPrincipal();
//        String encode = bCryptPasswordEncoder.encode(user.getPassword());
//        user.setPassword(encode);
        for (Object principal : o) {
            User cacheUser = (User) principal;
            if (cacheUser.getUsername().equals(user.getUsername())) {
                log.info("当前用户已经在线上.现顶替:{}",user.getUsername());
                List<SessionInformation> sessions = sessionRegistry.getAllSessions(cacheUser, false);
                for (SessionInformation sessionInformation : sessions) {
                    String sessionId = sessionInformation.getSessionId();

                    sessionInformation.expireNow();
                }
            }
        }


//        redisTemplate.opsForValue().set(user.getUsername(),0);
        if(("root").equals(user.getUsername())){
            user = init.root;
        }else{
            List<UserRole> userRoles = userRoleDao.findAllByUserId(user.getId());
            List<Role> roles = new ArrayList<>();
            for (UserRole userRole : userRoles) {
                String roleId = userRole.getRoleId();
                Optional<Role> op = roleDao.findById(userRole.getRoleId());
                if(op.isPresent()){
                    Role role = op.get();
                    List<RoleAuthority> roleAuthorities = roleAuthorityDao.findAllByRoleId(roleId);
                    List<String> authorityIds = new ArrayList<>();
                    for (RoleAuthority roleAuthority : roleAuthorities) {
                        authorityIds.add(roleAuthority.getAuthorityId());
                    }
                    List<Authority> authorities = authorityDao.findAllByIdIn(authorityIds);
                    role.setAuthorities(authorities);
                    roles.add(role);
                }
            }
            user.setRoles(roles);
        }

        sessionRegistry.registerNewSession(value, authentication.getPrincipal());
        httpServletResponse.setStatus(200);
        httpServletResponse.setContentType("application/json; charset=utf-8");
        httpServletResponse.getWriter().println(new ObjectMapper().writeValueAsString(user));
    }

}
