package com.takensoft.common.util;

import org.springframework.dao.DataAccessException;
import org.springframework.stereotype.Component;

import jakarta.servlet.http.HttpServletRequest;
import java.net.InetAddress;
import java.net.UnknownHostException;
/**
 * @author  : takensoft
 * @since   : 2025.01.22
 * @modification
 *     since    |    author    | description
 *  2025.01.22  |  takensoft   | 최초 등록
 *
 * HTTP 요청 관련 유틸리티
 */
@Component
public class HttpRequestUtil {

    /**
     * 기본 생성자
     */
    private HttpRequestUtil() {

    }

    /**
     * @param req - HTTP 요청 객체
     * @return 클라이언트 IP 주소 (String)
     * @throws UnknownHostException - 로컬 IP 주소를 확인할 수 없는 경우
     *
     * HTTP 요청에서 클라이언트의 IP 주소를 반환
     */
    public String getIp(HttpServletRequest req){
        try {
            String ip = req.getHeader("X-Forwarded-For");

            if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = req.getHeader("Proxy-Client-IP");
            }
            if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = req.getHeader("WL-Proxy-Client-IP");
            }
            if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = req.getHeader("HTTP_CLIENT_IP");
            }
            if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = req.getHeader("HTTP_X_FORWARDED_FOR");
            }
            if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = req.getHeader("X-Real-IP");
            }
            if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = req.getHeader("X-RealIP");
            }
            if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = req.getHeader("REMOTE_ADDR");
            }
            if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = req.getRemoteAddr();
            }

            if(ip.equals("0:0:0:0:0:0:0:1") || ip.equals("127.0.0.1") || ip.equals("::1")) {
                InetAddress adr = InetAddress.getLocalHost();
                ip = adr.getHostAddress();
    //            ip = adr.getHostName() + "/" + adr.getHostAddress();
            } else if (ip.startsWith("::ffff:")) {
                ip = ip.substring(7); // ::ffff:를 제거하고 IPv4 주소만 추출
            }
            return ip;

        } catch (UnknownHostException Uhe) {
            throw new RuntimeException("호스트 IP의 정보를 알 수가 없습니다.", Uhe);
        } catch (Exception e) {
            throw e;
        }
    }

    /**
     * @param req - HTTP 요청 객체
     * @return User-Agent (String)
     *
     * HTTP 요청에서 User-Agent 헤더 값을 추출
     */
    public static String getUserAgent(HttpServletRequest req) {
        return req.getHeader("User-Agent");
    }

    /**
     * @param userAgent - User-Agent
     * @return 운영체제 이름 (String)
     *
     * User-Agent에서 운영체제 정보를 추출
     */
    public static String getOS(String userAgent) {
        String os = "Unknown";

        // userAgent 문자열에서 운영체제 정보 추출
        if(userAgent != null && !userAgent.isEmpty()) {
            if(userAgent.toLowerCase().contains("windows")) {
                os = "Windows";
            } else if(userAgent.toLowerCase().contains("mac")) {
                os = "Mac";
            } else if(userAgent.toLowerCase().contains("linux")) {
                os = "Linux";
            }
        }
        return os;
    }

    /**
     * @param userAgent - User-Agent
     * @return 디바이스 이름 (String)
     *
     * User-Agent에서 디바이스 정보를 추출
     */
    public static String getDevice(String userAgent) {
        String device = "Unknown";
        // userAgent 문자열에서 디바이스 정보 추출
        if(userAgent != null && !userAgent.isEmpty()) {
            if(userAgent.toLowerCase().contains("mobile")) {
                device = "Mobile";
            } else {
                device = "Desktop";
            }
        }
        return device;
    }

    /**
     * @param userAgent - User-Agent
     * @return 브라우저 이름 (String)
     *
     * User-Agent에서 브라우저 정보를 추출
     */
    public static String getBrowser(String userAgent) {
        String browser = "Unknown";
        // userAgent 문자열에서 브라우저저 정보추출
        if(userAgent != null && !userAgent.isEmpty()) {
            if(userAgent.toLowerCase().contains("msie")) {
                browser = "Internet Explorer";
            } else if(userAgent.toLowerCase().contains("firefox")) {
                browser = "Firefox";
            } else if(userAgent.toLowerCase().contains("chrome")) {
                browser = "Chrome";
            } else if(userAgent.toLowerCase().contains("safari")) {
                browser = "Safari";
            } else if(userAgent.toLowerCase().contains("edge")) {
                browser = "Edge";
            }
        }
        return browser;
    }
}
