package com.takensoft.common.oauth.vo;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;

import java.util.Map;

/**
 * @author takensoft
 * @since 2025.05.22
 * @modification
 *     since    |    author    | description
 *  2025.05.22  |  takensoft   | 최초 등록
 *
 * OAuth2 사용자 정보 통합 VO
 */
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class OAuth2UserInfoVO {

    private Map<String, Object> attributes;    // OAuth2 응답 전체 데이터
    private String provider;                   // 제공업체 (kakao, naver, google 등)
    private String id;                         // 사용자 ID
    private String name;                       // 사용자 이름
    private String email;                      // 이메일
    private String imageUrl;                   // 프로필 이미지 URL

    // 제공업체별 데이터를 통일된 형태로 변환하는 생성자
    public OAuth2UserInfoVO(String provider, Map<String, Object> attributes) {
        this.provider = provider;
        this.attributes = attributes;

        switch (provider.toLowerCase()) {
            case "kakao":
                setKakaoUserInfo(attributes);
                break;
            case "naver":
                setNaverUserInfo(attributes);
                break;
            case "google":
                setGoogleUserInfo(attributes);
                break;
        }
    }

    private void setKakaoUserInfo(Map<String, Object> attributes) {
        try {
            Map<String, Object> kakaoAccount = (Map<String, Object>) attributes.get("kakao_account");
            if (kakaoAccount == null) {
                throw new IllegalArgumentException("kakao_account 정보가 없습니다.");
            }

            Map<String, Object> profile = (Map<String, Object>) kakaoAccount.get("profile");
            if (profile == null) {
                throw new IllegalArgumentException("profile 정보가 없습니다.");
            }

            this.id = String.valueOf(attributes.get("id"));
            this.name = (String) profile.get("nickname");
            this.email = (String) kakaoAccount.get("email");
            this.imageUrl = (String) profile.get("profile_image_url");

            // 필수 정보 검증
            validateRequiredFields("kakao");
        } catch (Exception e) {
            throw new RuntimeException("카카오 로그인 정보 처리 실패", e);
        }
    }

    private void setNaverUserInfo(Map<String, Object> attributes) {
        try {
            Map<String, Object> response = (Map<String, Object>) attributes.get("response");
            if (response == null) {
                throw new IllegalArgumentException("response 정보가 없습니다.");
            }

            this.id = (String) response.get("id");
            this.name = (String) response.get("name");
            this.email = (String) response.get("email");
            this.imageUrl = (String) response.get("profile_image");

            // 필수 정보 검증
            validateRequiredFields("naver");
        } catch (Exception e) {
            throw new RuntimeException("네이버 로그인 정보 처리 실패", e);
        }
    }

    private void setGoogleUserInfo(Map<String, Object> attributes) {
        try {
            // 구글은 직접 attributes에서 정보 추출
            this.id = (String) attributes.get("sub");
            this.name = (String) attributes.get("name");
            this.email = (String) attributes.get("email");
            this.imageUrl = (String) attributes.get("picture");

            // 구글 특정 필드 검증 및 대안 처리
            if (this.id == null) {
                this.id = (String) attributes.get("id"); // 대안 필드
            }

            if (this.name == null) {
                // given_name과 family_name 조합
                String givenName = (String) attributes.get("given_name");
                String familyName = (String) attributes.get("family_name");
                if (givenName != null || familyName != null) {
                    this.name = (givenName != null ? givenName : "") +
                            (familyName != null ? " " + familyName : "").trim();
                }
            }
            // 이메일 검증 상태 확인
            Boolean emailVerified = (Boolean) attributes.get("email_verified");
            // 필수 정보 검증
            validateRequiredFields("google");
        } catch (Exception e) {
            throw new RuntimeException("구글 로그인 정보 처리 실패", e);
        }
    }

    /**
     * 필수 필드 검증
     */
    private void validateRequiredFields(String provider) {
        if (this.id == null || this.id.trim().isEmpty()) {
            throw new IllegalArgumentException(provider + " 사용자 ID가 없습니다.");
        }
        if (this.email == null || this.email.trim().isEmpty()) {
            throw new IllegalArgumentException(provider + " 이메일 정보가 없습니다.");
        }
        if (this.name == null || this.name.trim().isEmpty()) {
            this.name = this.email.split("@")[0];
        }
    }

    /**
     * 파싱 실패 시 기본값 설정
     */
    private void setDefaultValues() {
        if (this.id == null) this.id = "unknown_" + System.currentTimeMillis();
        if (this.name == null) this.name = "Unknown User";
        if (this.email == null) this.email = this.id + "@unknown.com";
        if (this.imageUrl == null) this.imageUrl = "";
    }
}