package com.icomsys.main_vm.common.filter;

import com.fasterxml.jackson.databind.ObjectMapper;
//import com.icomsys.main_vm.db.jpa.repo.bot.TbBotAuthMenuRepo;
//import com.icomsys.main_vm.db.jpa.repo.bot.TbBotMenuRepo;
import com.google.gson.Gson;
import com.icomsys.main_vm.biz.common.login.TokenProvider;
import com.icomsys.main_vm.common.code.enumresource.SessionResource;
import com.icomsys.main_vm.db.mybatis.alias.LoginVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;
import org.springframework.web.util.ContentCachingRequestWrapper;
import org.springframework.web.util.ContentCachingResponseWrapper;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.time.LocalDateTime;

@Configuration
@Slf4j
@RequiredArgsConstructor
public class LoginFilter extends OncePerRequestFilter {

    private final ObjectMapper objectMapper;

    private final TokenProvider tokenProvider;
//    private final TbBotAuthMenuRepo tbBotAuthMenuRepo;
//    private final TbBotMenuRepo tbBotMenuRepo;
//    @Value("${Server.servlet.context-path}")
//    private String context;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        int chk = 0;
//        ContentCachingRequestWrapper wrapRequest = new ContentCachingRequestWrapper(request); // 커스텀으로 생성한 Wrapper
//        ContentCachingResponseWrapper wrapResponse = new ContentCachingResponseWrapper(response);
//        String reqUrl = request.getRequestURI().toString().replaceAll(context, "");
        String reqUrl = request.getRequestURI();
//        log.info("meyhod-"+ reqUrl+ request.getMethod());
//        log.info("필터 요청유알엘 - {}, {}", reqUrl);



        if (reqUrl.startsWith("/lib")
                || reqUrl.startsWith("/css")
                || reqUrl.startsWith("/images")
                || reqUrl.startsWith("/js")
                || reqUrl.startsWith("/adm/")
                || reqUrl.startsWith("/ws")
                || reqUrl.startsWith("/rest")
                || reqUrl.startsWith("/create")
                || reqUrl.startsWith("/data")
                || reqUrl.startsWith("/createEnv")
                || reqUrl.startsWith("/error")
                || reqUrl.startsWith("/files")
                || reqUrl.equals("/")
//                || reqUrl.equals("/tokenLogin")
        ) {
            filterChain.doFilter(request, response);
        } else {

            // 1. Request Header 에서 JWT 토큰 추출
            String token = resolveToken((HttpServletRequest) request);

            // 2. validateToken 으로 토큰 유효성 검사
            if (token != null && tokenProvider.validateToken(token)) {

                // Todo: 토큰 유효성 검사 후 에러 처리
                // 토큰이 유효할 경우 토큰에서 Authentication 객체를 가지고 와서 SecurityContext 에 저장
                Authentication authentication = tokenProvider.getAuthentication(token);
                SecurityContextHolder.getContext().setAuthentication(authentication);

                response.sendError(403);
            }
            filterChain.doFilter(request, response);
        }

/*
            if (request.getSession().getAttribute(SessionResource.UserVO.getName()) == null || request.getSession().getAttribute(SessionResource.UserVO.getName()).equals("")) {
                log.info("session Check");
                response.sendError(490);
                return;
            } else {
                log.info("Permission Check");
                //세션이 있으면 URL별 권한 확인.
                //ajax로 호출되는 url은 auth메뉴에 리스트업이 안되있어서 검사를 어떻게할지 계획이 필요함.
//                LoginVO loginVO = (LoginVO) request.getSession().getAttribute("LoginVO");
//                List<String> auths =
//                        if(!tbBotMenuRepo.findByMenuNoInOrderByMenuNoAsc(tbBotAuthMenuRepo.findByAuthCode(loginVO.getAuthCode())
//                                .stream().map(e -> e.getMenuNo())
//                                .collect(Collectors.toList()))
//                        .stream()
//                        .map(f -> f.getUrlPath())
//                        .collect(Collectors.toList())
//                        .contains(reqUrl)){
//                            wrapResponse.sendRedirect("adm/main/egovLoginUsr.do");
//                        }
//                log.info("auths - {}", new Gson().toJson(auths));
//
//                for (String e : auths) {
//                    if (e != null && !e.equals("") && !e.equals("null") && e.equals(reqUrl)) {
//                            chk+=1;
//                        break;
//                    }
//                }
//                if(chk == 0){
//                    wrapResponse.setStatus(404);
//                    wrapResponse.sendRedirect("adm/main/egovLoginUsr.do");
//                }
                filterChain.doFilter(request, response);
            }
        }
//        response.copyBodyToResponse();

 */
    }

    // Request Header 에서 토큰 정보 추출
    private String resolveToken(HttpServletRequest request) {
        String bearerToken = request.getHeader("Authorization");
        if (StringUtils.hasText(bearerToken) && bearerToken.startsWith("Bearer")) {
            return bearerToken.substring(7);
        }
        return null;
    }

}
