'use client';

/**
 * API 에러 컨텍스트
 *
 * Server Action 결과에서 인증 에러를 감지하고
 * 자동으로 로그인 페이지로 리다이렉트
 */

import { createContext, useContext, useCallback, useRef, type ReactNode } from 'react';
import { useRouter } from 'next/navigation';
import { isAuthError, isApiError, type ApiErrorResponse } from '@/lib/api/errors';
import { callLogoutAPI } from '@/lib/auth/logout';

interface ApiErrorContextType {
  /**
   * API 응답을 체크하고 인증 에러면 로그인 페이지로 이동
   * @returns true면 에러가 있음 (호출자는 early return 해야 함)
   */
  checkAuthError: <T>(response: T) => response is ApiErrorResponse;

  /**
   * 수동으로 인증 에러 처리 (로그아웃 후 로그인 페이지 이동)
   */
  handleAuthError: () => Promise<void>;
}

const ApiErrorContext = createContext<ApiErrorContextType | null>(null);

/**
 * API 에러 Provider
 *
 * Protected Layout에 추가하여 모든 하위 페이지에서 사용
 */
export function ApiErrorProvider({ children }: { children: ReactNode }) {
  const router = useRouter();
  const isRedirecting = useRef(false);

  /**
   * 인증 에러 처리 - 로그아웃 후 로그인 페이지 이동
   */
  const handleAuthError = useCallback(async () => {
    // 중복 리다이렉트 방지
    if (isRedirecting.current) return;
    isRedirecting.current = true;

    console.warn('[ApiErrorContext] 인증 에러 감지 - 로그인 페이지로 이동');

    try {
      // 서버 로그아웃 API 호출 (HttpOnly 쿠키 삭제)
      await callLogoutAPI();
    } catch (error) {
      console.error('[ApiErrorContext] 로그아웃 API 호출 실패:', error);
    }

    // 로그인 페이지로 이동
    window.location.href = '/login';
  }, []);

  /**
   * API 응답에서 인증 에러 체크
   * 인증 에러면 자동으로 로그인 페이지 이동
   */
  const checkAuthError = useCallback(<T,>(response: T): response is ApiErrorResponse => {
    if (isAuthError(response)) {
      handleAuthError();
      return true;
    }

    if (isApiError(response)) {
      console.warn('[ApiErrorContext] API 에러:', response.message);
      return true;
    }

    return false;
  }, [handleAuthError]);

  return (
    <ApiErrorContext.Provider value={{ checkAuthError, handleAuthError }}>
      {children}
    </ApiErrorContext.Provider>
  );
}

/**
 * API 에러 컨텍스트 훅
 *
 * @example
 * ```typescript
 * const { checkAuthError } = useApiError();
 *
 * const result = await getEmployees();
 * if (checkAuthError(result)) return; // 인증 에러면 자동 리다이렉트
 *
 * // 정상 데이터 처리...
 * ```
 */
export function useApiError() {
  const context = useContext(ApiErrorContext);

  if (!context) {
    throw new Error('useApiError must be used within ApiErrorProvider');
  }

  return context;
}

/**
 * Server Action 결과 래퍼
 *
 * Server Action 호출 결과를 자동으로 체크하고
 * 인증 에러면 null 반환 + 리다이렉트
 *
 * @example
 * ```typescript
 * const { withAuthCheck } = useApiError();
 *
 * const employees = await withAuthCheck(getEmployees());
 * if (!employees) return; // 에러 발생 시 null
 *
 * // 정상 데이터 사용...
 * ```
 */
export function useWithAuthCheck() {
  const { checkAuthError } = useApiError();

  const withAuthCheck = useCallback(async <T,>(
    promise: Promise<T>
  ): Promise<T | null> => {
    const result = await promise;

    if (checkAuthError(result)) {
      return null;
    }

    return result;
  }, [checkAuthError]);

  return { withAuthCheck };
}