package com.samsung.user.controller;

import com.onelogin.saml2.SamlSSOAuth;
import com.onelogin.saml2.exception.Error;
import com.onelogin.saml2.exception.SettingsException;
import com.samsung.common.entity.JwtResponse;
import com.samsung.common.util.JwtUtil;
import com.samsung.common.util.WebUtil;
import com.samsung.core.exception.AuthenticationException;
import com.samsung.core.exception.RegistrationException;
import com.samsung.user.AuthenticationService;
import com.samsung.user.entity.User;
import com.samsung.user.interceptor.LoginInterceptorExecutor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;

import javax.security.auth.login.AccountException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Map;

@Controller
public class AdLoginController {

    @Value("${web-content-root-path}")
    private String webContentRootPath;

    private final AuthenticationService authenticationService;

    private final LoginInterceptorExecutor loginInterceptorExecutor;

    private final JwtUtil jwtUtil;

    private final WebUtil webUtil;

    public AdLoginController(AuthenticationService authenticationService, LoginInterceptorExecutor loginInterceptorExecutor, JwtUtil jwtUtil, WebUtil webUtil) {
        this.authenticationService = authenticationService;
        this.loginInterceptorExecutor = loginInterceptorExecutor;
        this.jwtUtil = jwtUtil;
        this.webUtil = webUtil;
    }

    @PostMapping("/noauth/login/ad")
    public String loginByAd(HttpServletRequest request, HttpServletResponse response) throws Exception {
        SamlSSOAuth auth = new SamlSSOAuth(request, response);
        // SAML 인증 결과 처리
        auth.processResponse();
        Map<String, String> userInfoMap = auth.getUserInfo();

        //ADFS 로그인 실패 ID/PW 창으로 이동
        if(  userInfoMap.get("UserId") == null ) throw new AccountException("AD 로그인에 실패 하였습니다.");
        else{
            User user;
            try{
                user = authenticationService.loginByAd(userInfoMap);
            }catch(RegistrationException e) {
                return "redirect:" + webContentRootPath + "/login?code=" + e.getCode() + "&message=" + e.getMessage();
            }catch (AuthenticationException ex){
                return "redirect:"+webContentRootPath+"/error?code="+ ex.getCode();
            }
            user.setRecentLoginIp(webUtil.getClientIp(request));
            JwtResponse jwtResponse = new JwtResponse(jwtUtil.generateToken(user), user.getUserId());
            user.setJwt(jwtResponse.getJwtToken().split("\\.")[2]);
            loginInterceptorExecutor.applyPostLogin(request, response, user);

            String relayState = auth.getRequest().getParameter("RelayState");
            String redirectUrl = "redirect:" + webContentRootPath + "/login?token=" + jwtResponse.getJwtToken();
            if(StringUtils.contains(relayState, "/noauth/saml-request")){
                return redirectUrl;
            }else{
                return redirectUrl + "&redirect=" + relayState ;
            }
        }
    }

    @GetMapping("/noauth/saml-request")
    public void samlRequest(HttpServletRequest request, HttpServletResponse response) throws SettingsException, Error, IOException {
        SamlSSOAuth auth = new SamlSSOAuth(request, response);
        auth.login(request.getParameter("redirect"));
    }
}
