/**
 * 네트워크 요청 재시도 유틸리티
 */
import { RetryOptions } from './types';

// 네트워크 재시도 설정
const MAX_RETRY_COUNT = 3;
const INITIAL_RETRY_DELAY = 1000; // 1초

/**
 * 네트워크 요청 래퍼 함수 (재시도 로직 포함)
 */
export const withRetry = async <T>(
  fn: () => Promise<T>,
  options: RetryOptions<T> = {}
): Promise<T> => {
  const {
    maxRetries = MAX_RETRY_COUNT,
    retryDelay = INITIAL_RETRY_DELAY,
    onRetry = () => {},
    shouldRetry = () => true,
    entityType
  } = options;
  
  let lastError: Error | unknown;
  
  for (let attempt = 0; attempt <= maxRetries; attempt++) {
    try {
      // 함수 실행
      return await fn();
    } catch (error) {
      lastError = error;
      
      // 마지막 시도였으면 에러 발생
      if (attempt === maxRetries) {
        break;
      }
      
      // 재시도 여부 확인
      if (!shouldRetry(error)) {
        break;
      }
      
      // 재시도 콜백 호출
      onRetry(attempt + 1, error);
      
      // 지수 백오프 (exponential backoff) 적용
      const delay = retryDelay * Math.pow(2, attempt);
      console.log(`[네트워크] ${attempt + 1}번째 재시도 ${delay}ms 후 실행`);
      await new Promise(resolve => setTimeout(resolve, delay));
    }
  }
  
  throw lastError;
};

/**
 * 네트워크 요청 타임아웃 래퍼 함수
 */
export const withTimeout = async <T>(
  promise: Promise<T>,
  timeoutMs: number = 10000
): Promise<T> => {
  return Promise.race([
    promise,
    new Promise<T>((_, reject) => {
      setTimeout(() => {
        reject(new Error(`요청 시간 초과 (${timeoutMs}ms)`));
      }, timeoutMs);
    })
  ]);
};
