package com.takensoft.common.oauth.web;

import com.takensoft.cms.mber.service.MberService;
import com.takensoft.cms.mber.vo.MberVO;
import com.takensoft.common.message.MessageCode;
import com.takensoft.common.service.VerificationService;
import com.takensoft.common.util.ResponseUtil;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpSession;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;

/**
 * @author takensoft
 * @since 2025.05.22
 * @modification
 *     since    |    author    | description
 *  2025.05.22  |  takensoft   | 최초 등록
 *
 * OAuth2 관련 컨트롤러
 */
@RestController
@RequiredArgsConstructor
@Slf4j
@RequestMapping(value = "/oauth2")
public class OAuth2Controller {

    private final MberService mberService;
    private final VerificationService verificationService;
    private final ResponseUtil resUtil;

    /**
     * OAuth2 로그인 후 사용자 정보 조회
     */
    @GetMapping(value = "/user-info")
    public ResponseEntity<?> getUserInfo(HttpServletRequest request) {
        try {
            // 현재 로그인된 사용자 ID 추출
            String currentUserId = verificationService.getCurrentUserId();

            if (currentUserId == null || currentUserId.isEmpty()) {
                // 세션에서 OAuth2 정보 확인 (세션 모드인 경우)
                HttpSession session = request.getSession(false);
                if (session != null && session.getAttribute("oauth2User") != null) {
                    return handleSessionOAuth2User(session);
                }

                return resUtil.errorRes(MessageCode.LOGIN_USER_NOT_FOUND);
            }

            // DB에서 사용자 정보 조회
            HashMap<String, Object> params = new HashMap<>();
            params.put("mbrId", currentUserId);
            MberVO userInfo = mberService.findByMbr(params);

            if (userInfo == null) {
                return resUtil.errorRes(MessageCode.LOGIN_USER_NOT_FOUND);
            }

            // 응답 데이터 구성
            Map<String, Object> response = createUserResponse(userInfo);
            return resUtil.successRes(response, MessageCode.COMMON_SUCCESS);

        } catch (Exception e) {
            log.error("사용자 정보 조회 실패", e);
            return resUtil.errorRes(MessageCode.COMMON_UNKNOWN_ERROR);
        }
    }

    /**
     * 세션의 OAuth2 사용자 정보 처리
     */
    private ResponseEntity<?> handleSessionOAuth2User(HttpSession session) {
        try {
            // 세션에서 OAuth2 사용자 정보 추출
            // 이는 DB 저장이 완료되기 전의 임시 상태
            Map<String, Object> tempResponse = new HashMap<>();
            tempResponse.put("mbrId", "TEMP_OAUTH2");
            tempResponse.put("mbrNm", "OAuth2 User");
            tempResponse.put("roles", new String[]{"ROLE_USER"});
            tempResponse.put("isTemporary", true);

            return resUtil.successRes(tempResponse, MessageCode.COMMON_SUCCESS);
        } catch (Exception e) {
            log.error("세션 OAuth2 사용자 정보 처리 실패", e);
            return resUtil.errorRes(MessageCode.COMMON_UNKNOWN_ERROR);
        }
    }

    /**
     * 사용자 응답 데이터 생성
     */
    private Map<String, Object> createUserResponse(MberVO userInfo) {
        Map<String, Object> response = new HashMap<>();
        response.put("mbrId", userInfo.getMbrId());
        response.put("mbrNm", userInfo.getMbrNm());
        response.put("eml", userInfo.getEml());
        response.put("ncnm", userInfo.getNcnm());
        response.put("mbrType", userInfo.getMbrType());

        // 권한 정보 변환
        String[] roles = userInfo.getAuthorList().stream()
                .map(auth -> auth.getAuthrtCd())
                .toArray(String[]::new);
        response.put("roles", roles);
        response.put("isTemporary", false);

        return response;
    }
}