package com.unicorn.hgzero.common.util;

import org.springframework.util.StringUtils;

/**
 * 문자열 유틸리티 클래스
 * 문자열 관련 공통 기능을 제공
 */
public class StringUtil {

    private StringUtil() {
        // Utility class - prevent instantiation
    }

    /**
     * 문자열이 비어있는지 확인
     *
     * @param str 확인할 문자열
     * @return 비어있으면 true, 아니면 false
     */
    public static boolean isEmpty(String str) {
        return !StringUtils.hasText(str);
    }

    /**
     * 문자열이 비어있지 않은지 확인
     *
     * @param str 확인할 문자열
     * @return 비어있지 않으면 true, 아니면 false
     */
    public static boolean isNotEmpty(String str) {
        return StringUtils.hasText(str);
    }

    /**
     * 문자열 앞뒤 공백 제거
     * null-safe 처리
     *
     * @param str 입력 문자열
     * @return 공백이 제거된 문자열 (null인 경우 null 반환)
     */
    public static String trim(String str) {
        return str != null ? str.trim() : null;
    }

    /**
     * 문자열 앞뒤 공백 제거
     * null인 경우 빈 문자열 반환
     *
     * @param str 입력 문자열
     * @return 공백이 제거된 문자열 (null인 경우 빈 문자열 반환)
     */
    public static String trimToEmpty(String str) {
        return str != null ? str.trim() : "";
    }

    /**
     * 문자열이 null 또는 빈 문자열인 경우 기본값 반환
     *
     * @param str 입력 문자열
     * @param defaultValue 기본값
     * @return 문자열이 비어있으면 기본값, 아니면 입력 문자열
     */
    public static String defaultIfEmpty(String str, String defaultValue) {
        return isEmpty(str) ? defaultValue : str;
    }

    /**
     * 문자열 마스킹
     * 이메일, 전화번호 등 민감한 정보를 부분적으로 마스킹
     *
     * @param str 마스킹할 문자열
     * @param visibleStart 앞에서 보일 문자 수
     * @param visibleEnd 뒤에서 보일 문자 수
     * @param maskChar 마스킹 문자
     * @return 마스킹된 문자열
     */
    public static String mask(String str, int visibleStart, int visibleEnd, char maskChar) {
        if (isEmpty(str) || str.length() <= (visibleStart + visibleEnd)) {
            return str;
        }

        int maskLength = str.length() - visibleStart - visibleEnd;
        String maskedPart = String.valueOf(maskChar).repeat(maskLength);

        return str.substring(0, visibleStart) +
               maskedPart +
               str.substring(str.length() - visibleEnd);
    }

    /**
     * 이메일 마스킹
     * 예: test@example.com -> te**@example.com
     *
     * @param email 마스킹할 이메일
     * @return 마스킹된 이메일
     */
    public static String maskEmail(String email) {
        if (isEmpty(email) || !email.contains("@")) {
            return email;
        }

        String[] parts = email.split("@");
        String localPart = parts[0];
        String domain = parts[1];

        if (localPart.length() <= 2) {
            return localPart + "@" + domain;
        }

        String maskedLocal = localPart.substring(0, 2) +
                            "*".repeat(localPart.length() - 2);

        return maskedLocal + "@" + domain;
    }

    /**
     * 전화번호 마스킹
     * 예: 010-1234-5678 -> 010-****-5678
     *
     * @param phone 마스킹할 전화번호
     * @return 마스킹된 전화번호
     */
    public static String maskPhone(String phone) {
        if (isEmpty(phone)) {
            return phone;
        }

        // 하이픈 제거
        String cleanPhone = phone.replaceAll("-", "");

        if (cleanPhone.length() < 8) {
            return phone;
        }

        // 뒤 4자리만 보이도록 마스킹
        String masked = "*".repeat(cleanPhone.length() - 4) +
                       cleanPhone.substring(cleanPhone.length() - 4);

        // 원본 형식에 따라 하이픈 추가
        if (phone.contains("-")) {
            if (cleanPhone.length() == 10) {
                return masked.substring(0, 3) + "-" +
                      masked.substring(3, 6) + "-" +
                      masked.substring(6);
            } else if (cleanPhone.length() == 11) {
                return masked.substring(0, 3) + "-" +
                      masked.substring(3, 7) + "-" +
                      masked.substring(7);
            }
        }

        return masked;
    }

    /**
     * Camel Case를 Snake Case로 변환
     * 예: userName -> user_name
     *
     * @param camelCase Camel Case 문자열
     * @return Snake Case 문자열
     */
    public static String toSnakeCase(String camelCase) {
        if (isEmpty(camelCase)) {
            return camelCase;
        }

        return camelCase.replaceAll("([a-z])([A-Z])", "$1_$2").toLowerCase();
    }

    /**
     * Snake Case를 Camel Case로 변환
     * 예: user_name -> userName
     *
     * @param snakeCase Snake Case 문자열
     * @return Camel Case 문자열
     */
    public static String toCamelCase(String snakeCase) {
        if (isEmpty(snakeCase)) {
            return snakeCase;
        }

        StringBuilder result = new StringBuilder();
        boolean nextUpper = false;

        for (char c : snakeCase.toCharArray()) {
            if (c == '_') {
                nextUpper = true;
            } else {
                result.append(nextUpper ? Character.toUpperCase(c) : c);
                nextUpper = false;
            }
        }

        return result.toString();
    }
}
