// API 에러 핸들링 헬퍼 유틸리티
// API 요청 실패 시 에러 처리 및 사용자 친화적 메시지 생성

/**
 * API 에러 클래스
 * - 표준 Error를 확장하여 HTTP 상태 코드와 validation errors 포함
 */
export class ApiError extends Error {
  constructor(
    public status: number,
    public message: string,
    public errors?: Record<string, string[]>
  ) {
    super(message);
    this.name = 'ApiError';
  }
}

/**
 * 품목코드 중복 에러 클래스
 * - 백엔드에서 400 에러와 함께 duplicate_id, duplicate_code 반환 시 사용
 * - 2025-12-11: 백엔드 DuplicateCodeException 대응
 */
export class DuplicateCodeError extends ApiError {
  constructor(
    public message: string,
    public duplicateId: number,
    public duplicateCode: string
  ) {
    super(400, message);
    this.name = 'DuplicateCodeError';
  }
}

/**
 * API 응답 에러를 처리하고 ApiError를 throw
 * @param response - fetch Response 객체
 * @throws {ApiError} HTTP 상태 코드, 메시지, validation errors 포함
 */
export const handleApiError = async (response: Response): Promise<never> => {
  const data = await response.json().catch(() => ({}));

  // 401 Unauthorized - 토큰 만료 또는 인증 실패
  // ✅ 자동으로 로그인 페이지로 리다이렉트
  if (response.status === 401) {
    console.warn('⚠️ 401 Unauthorized - 로그인 페이지로 이동합니다.');

    // 클라이언트 사이드에서만 리다이렉트
    if (typeof window !== 'undefined') {
      window.location.href = '/login';
    }

    throw new ApiError(
      401,
      data.message || '인증이 필요합니다. 로그인 상태를 확인해주세요.',
      data.errors
    );
  }

  // 403 Forbidden - 권한 없음
  if (response.status === 403) {
    throw new ApiError(
      403,
      data.message || '접근 권한이 없습니다.',
      data.errors
    );
  }

  // 400 Bad Request - 품목코드 중복 에러 체크
  // 백엔드 DuplicateCodeException이 duplicate_id, duplicate_code 반환
  if (response.status === 400 && data.duplicate_id) {
    console.warn('⚠️ 품목코드 중복 감지:', {
      duplicateId: data.duplicate_id,
      duplicateCode: data.duplicate_code,
      message: data.message
    });
    throw new DuplicateCodeError(
      data.message || '해당 품목코드가 이미 존재합니다.',
      data.duplicate_id,
      data.duplicate_code
    );
  }

  // 422 Unprocessable Entity - Validation 에러
  if (response.status === 422) {
    // errors는 top-level 또는 error.details에 있을 수 있음
    const validationErrors = data.errors || data.error?.details;
    // 상세 validation 에러 로그 출력
    console.error('🔴 [API 422 Validation Error]', {
      message: data.message,
      errors: validationErrors,
      fullResponse: data
    });
    throw new ApiError(
      422,
      data.message || '입력값을 확인해주세요.',
      validationErrors
    );
  }

  // 기타 에러
  throw new ApiError(
    response.status,
    data.message || '서버 오류가 발생했습니다',
    data.errors
  );
};

/**
 * 디버그 모드 설정
 * - true: 에러 코드 표시 (개발/테스트)
 * - false: 메시지만 표시 (프로덕션)
 *
 * TODO: 프로덕션 배포 시 false로 변경하거나 환경변수 사용
 */
const SHOW_ERROR_CODE = true;

/**
 * 에러 객체에서 사용자 친화적인 메시지 추출
 * @param error - 발생한 에러 객체 (ApiError, Error, unknown)
 * @param includeCode - 에러 코드 포함 여부 (기본값: SHOW_ERROR_CODE 설정 따름)
 * @returns 사용자에게 표시할 에러 메시지
 */
export const getErrorMessage = (error: unknown, includeCode?: boolean): string => {
  const showCode = includeCode ?? SHOW_ERROR_CODE;

  if (error instanceof DuplicateCodeError) {
    return showCode
      ? `[${error.status}] ${error.message} (코드: ${error.duplicateCode})`
      : error.message;
  }
  if (error instanceof ApiError) {
    return showCode ? `[${error.status}] ${error.message}` : error.message;
  }
  if (error instanceof Error) {
    return error.message;
  }
  return '알 수 없는 오류가 발생했습니다';
};