package com.tsi.sig.server.controller;

import com.tsi.sig.server.objects.UserVO;
import com.tsi.sig.server.security.TSIEncoder;
import com.tsi.sig.server.service.LoginServiceImpl;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.javassist.NotFoundException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Slf4j
@Controller
@AllArgsConstructor
public class LoginController {
    private final LoginServiceImpl loginServiceImpl;
    private final String REDIR2DENY = "redirect:/denied.do";
    private final TSIEncoder encoder;

    @RequestMapping({"/showlogin.do"})
    public String showlogin() throws Exception, NotFoundException {
        return "login";
//        String reqId = "admin";
//        String reqPw = "cjaeks#11";
//        UserVO userDetails = this.loginServiceImpl.loadUserByUsername(reqId);
//        SecurityContext context = SecurityContextHolder.createEmptyContext();
//        UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, reqPw, userDetails.getAuthorities());
//        context.setAuthentication(authentication);
//        SecurityContextHolder.setContext(context);
//        return "login";
//        return "redirect:/login.do";
    }

    @PostMapping({"/login.do"})
    public String login(UserVO userVO, RedirectAttributes redir) throws IOException {

        if (userVO == null) {
            return "redirect:/denied.do";
        } else {
            String reqId = userVO.getUserId();
            String reqPw = userVO.getUserPswd();
            UserVO userDetails = this.loginServiceImpl.loadUserByUsername(reqId);
           if (userDetails == null){
                return "redirect:/denied.do";
           }
           else {
                redir.addFlashAttribute("userVO", userDetails);
                if (userDetails.getUseyn().equals("N")) {
                    return "redirect:/denied.do";
                }
                else if (!encoder.matches(reqPw, userDetails.getUserPswd())) {
                    return "redirect:/denied.do";
                }
                else {
                    this.loginServiceImpl.initFailCnt(reqId);
                    SecurityContext context = SecurityContextHolder.createEmptyContext();
                    UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, reqPw, userDetails.getAuthorities());
                    context.setAuthentication(authentication);
                    SecurityContextHolder.setContext(context);
                    return "redirect:/main.do";
                }
            }
        }
    }

    @GetMapping({"/login.do"})
    public String showDashBoard(Model model) {
//        return "main_org";
        return "main_new";
    }

    @GetMapping({"/denied.do"})
    public String denied(HttpServletRequest req, @ModelAttribute("userVO") UserVO userVO) {
        if (userVO.getUserId() != null) {
            String useYN = userVO.getUseyn();
            req.setAttribute("userId", userVO.getUserId());
            req.setAttribute("useYN", useYN);
            req.setAttribute("failCnt", userVO.getFailCnt());
            if (useYN.equals("Y")) {
                this.loginServiceImpl.loginFail(userVO.getUserId());
            }
        }

        return "denied";
    }

    @GetMapping({"/logout.do"})
    public String logout(HttpServletResponse res, HttpServletRequest req) {
        Authentication auth = SecurityContextHolder.getContext().getAuthentication();
        if (auth != null) {
            (new SecurityContextLogoutHandler()).logout(req, res, auth);
        }

        return "login";
    }

}
