package com.takensoft.common.service;

import com.takensoft.cms.mber.vo.MberVO;
import com.takensoft.common.exception.CustomAccessDeniedException;
import lombok.RequiredArgsConstructor;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;

/**
 * @author takensoft
 * @since 2025.01.22
 * @modification
 *     since    |    author    | description
 *  2025.01.22  |  takensoft   | 최초 등록
 *
 * 사용자 검증 서비스
 */
@Service("authorizationService")
@RequiredArgsConstructor
public class VerificationService {

    /**
     * @return 현재 인증된 사용자 정보
     * @throws CustomAccessDeniedException 인증되지 않은 경우 예외 발생
     *
     * 현재 로그인된 사용자를 가져오는 공통 메서드
     */
    private MberVO getAuthenticatedUser() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if(authentication == null || !authentication.isAuthenticated()) {
            throw new CustomAccessDeniedException("접근 권한이 없습니다.");
        }

        Object principal = authentication.getPrincipal();
        if(!(principal instanceof MberVO)) {
            throw new CustomAccessDeniedException("접근 권한이 없습니다.");
        }
        return (MberVO) principal;
    }

    /**
     * @param targetUserId 접근하려는 사용자 ID
     * @throws CustomAccessDeniedException - 접근 권한이 없을 경우 예외 발생
     *
     * 특정 사용자 ID에 대한 접근 권한 검증
     */
    public void verifyAccess(String targetUserId) {
        MberVO user = getAuthenticatedUser();
        // 관리자 권한 여부
        boolean isAdmin = user.getAuthorList().stream()
                .anyMatch(auth -> "ROLE_ADMIN".equals(auth.getAuthrtCd()));
        // 본인 여부
        boolean isOwner = user.getMbrId().equals(targetUserId);

        if(!isAdmin && !isOwner) {
            throw new CustomAccessDeniedException("접근 권한이 없습니다.");
        }
    }

    /**
     * @return 관리자 여부(true, false)
     *
     * 관리자 여부 검증
     */
    public boolean verifyAdmin() {
        MberVO user = getAuthenticatedUser();
        // 관리자 권한 여부 반환
        return user.getAuthorList().stream()
                .anyMatch(auth -> "ROLE_ADMIN".equals(auth.getAuthrtCd()));
    }

    /**
     * @return 현재 로그인된 사용자 ID
     *
     * 로그인된 사용자 아이디 반환
     *  - 등록자, 수정자 입력 시 사용
     */
    public String getCurrentUserId() {
        String userId = null;
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();


        // 디버깅용 로그 추가
        System.out.println("Authentication: " + authentication);
        if(authentication != null) {
            System.out.println("Is Authenticated: " + authentication.isAuthenticated());
            System.out.println("Principal Type: " + authentication.getPrincipal().getClass().getName());
            System.out.println("Principal: " + authentication.getPrincipal());
        }

        if(authentication != null && authentication.isAuthenticated()) {
            Object principal = authentication.getPrincipal();
            if(principal instanceof MberVO) {
                userId = ((MberVO) authentication.getPrincipal()).getMbrId();
            }
        }
        return userId;
    }
}
