package com.saas.shared.exception;

import lombok.extern.slf4j.Slf4j;

/**
 * Exception Factory
 * 
 * Centralizes exception creation with consistent logging and error code mapping.
 * Replaces scattered RuntimeException throws with typed BusinessException.
 * 
 * Usage:
 * - ExceptionFactory.throwBusinessException(ErrorCode.VOIP_CALL_FAILED, "Details...")
 * - ExceptionFactory.throwBusinessException(ErrorCode.DATABASE_ERROR, exception, "Context")
 */
@Slf4j
public final class ExceptionFactory {
    
    private ExceptionFactory() {
        // Utility class, prevent instantiation
    }
    
    /**
     * Throw BusinessException with error code and message
     * Logs error before throwing
     * 
     * @param errorCode Error code enum
     * @param message Custom error message
     * @throws BusinessException Always throws
     */
    public static void throwBusinessException(ErrorCode errorCode, String message) {
        log.error("BusinessException: {} - {}", errorCode.getCode(), message);
        throw new BusinessException(errorCode, message);
    }
    
    /**
     * Throw BusinessException with error code, cause, and message
     * Logs error with stack trace before throwing
     * 
     * @param errorCode Error code enum
     * @param cause Root cause exception
     * @param message Custom error message
     * @throws BusinessException Always throws
     */
    public static void throwBusinessException(ErrorCode errorCode, Throwable cause, String message) {
        log.error("BusinessException: {} - {} (Cause: {})", 
                errorCode.getCode(), message, cause.getMessage(), cause);
        throw new BusinessException(errorCode, message + " - Cause: " + cause.getMessage());
    }
    
    /**
     * Throw BusinessException with error code only (uses default message)
     * Logs error before throwing
     * 
     * @param errorCode Error code enum
     * @throws BusinessException Always throws
     */
    public static void throwBusinessException(ErrorCode errorCode) {
        log.error("BusinessException: {} - {}", errorCode.getCode(), errorCode.getMessage());
        throw new BusinessException(errorCode);
    }
    
    /**
     * Throw BusinessException with formatted message (args)
     * Logs error before throwing
     * 
     * @param errorCode Error code enum
     * @param args Format arguments for message
     * @throws BusinessException Always throws
     */
    public static void throwBusinessException(ErrorCode errorCode, Object... args) {
        String formattedMessage = String.format(errorCode.getMessage(), args);
        log.error("BusinessException: {} - {}", errorCode.getCode(), formattedMessage);
        throw new BusinessException(errorCode, args);
    }
}
