/**
 * API 호출을 위한 편의 함수
 *
 * @template T - 응답 데이터의 타입
 * @param path - API 엔드포인트 경로 (예: '/users', '/users/1')
 * @param options - 요청 및 에러 처리 옵션
 * @returns Promise<T> - API 응답 데이터
 *
 * @example
 * // GET 요청 (기본 - 전역 로딩 자동 적용)
 * const users = await useApi<User[]>('/users')
 *
 * // POST 요청 (커스텀 로딩 메시지)
 * const newUser = await useApi<User>('/users', {
 *   method: 'POST',
 *   body: { name: 'John', email: 'john@example.com' },
 *   loadingMessage: '사용자를 생성하는 중...'
 * })
 *
 * // 전역 로딩 없이 API 호출
 * const data = await useApi<User[]>('/users', {
 *   useGlobalLoading: false
 * })
 *
 * // 에러를 직접 처리
 * try {
 *   const data = await useApi<User[]>('/users', { handleError: false })
 * } catch (error) {
 *   // 직접 에러 처리
 * }
 *
 * // FormData 업로드
 * const formData = new FormData()
 * formData.append('file', file)
 * await useApi('/upload', {
 *   method: 'POST',
 *   body: formData,
 *   loadingMessage: '파일을 업로드하는 중...'
 * })
 */
export const useApi = async <T>(
  path: string,
  options?: {
    // API 요청 옵션
    method?: string;
    body?: any;
    headers?: Record<string, string>;
    // 에러 처리 옵션
    handleError?: boolean; // true: 에러를 null로 반환, false: 에러를 다시 던짐
    showAlert?: boolean; // true: 에러 시 alert 표시
    // 로딩 옵션
    loadingMessage?: string; // 로딩 메시지
    useGlobalLoading?: boolean; // 전역 로딩 사용 여부 (기본값: true)
  }
): Promise<T> => {
  const { withLoading } = useLoading();

  // API 호출 로직을 별도 함수로 분리
  const apiCall = async (): Promise<T> => {
    const { $api } = useNuxtApp();

    // 기본값 설정
    const {
      method = "GET",
      body,
      headers,
      handleError = true,
      showAlert = true,
    } = options || {};

    // API 요청 옵션 구성
    const apiOpts = {
      method,
      ...(body && { body }),
      ...(headers && { headers }),
    };

    return ($api as any)(path, apiOpts).catch(async (error: any) => {
      const status = error.response?.status;
      const message = error.response._data.message;

      if (
        status === 401 &&
        ["JWT_TOKEN_EXPIRED", "INVALID_CLIENT_IP", "JWT_TOKEN_NULL"].includes(
          message
        )
      ) {
        const userStore = useUserStore();
        userStore.user = null;
        userStore.isLoggedIn = false;
        await navigateTo(`/auth-error?type=${message}`);
        throw error;
      }

      // 사용자에게 알림 표시
      if (showAlert) {
        let description =
          status === 404
            ? "요청한 리소스를 찾을 수 없습니다."
            : status === 500
              ? "서버 오류가 발생했습니다."
              : "요청 처리 중 오류가 발생했습니다.";

        // 서버에서 온 에러 메시지가 있으면 우선 사용
        if (error.response?._data?.description) {
          description = error.response._data.description;
        }

        alert(description);
      }

      // 에러 처리 방식에 따라 반환
      if (handleError) {
        return null as T; // 에러를 null로 반환
      } else {
        throw error; // 에러를 다시 던짐
      }
    });
  };

  // 전역 로딩 사용 여부 확인 (기본값: true)
  const shouldUseLoading = options?.useGlobalLoading !== false;

  if (shouldUseLoading) {
    // 전역 로딩과 함께 API 호출
    return await withLoading(
      apiCall,
      options?.loadingMessage || "데이터를 불러오는 중..."
    );
  } else {
    // 전역 로딩 없이 API 호출
    return await apiCall();
  }
};
