/**
 * API 클라이언트
 * 모든 API 호출에서 사용되는 기본 fetch 래퍼
 */
import { useAuthStore } from '@/stores';

const API_BASE = '/api';

/**
 * API 에러 클래스
 */
export class ApiError extends Error {
  constructor(message, status, data = null) {
    super(message);
    this.name = 'ApiError';
    this.status = status;
    this.data = data;
  }
}

/**
 * 응답 처리 헬퍼
 */
async function handleResponse(response) {
  if (!response.ok) {
    const error = await response.json().catch(() => ({ error: '요청 실패' }));
    throw new ApiError(
      error.error || error.message || `HTTP ${response.status}`,
      response.status,
      error
    );
  }

  // 204 No Content 처리
  if (response.status === 204) {
    return null;
  }

  return response.json();
}

/**
 * 공개 API fetch
 * @param {string} endpoint - API 엔드포인트 (/api 제외)
 * @param {RequestInit} options - fetch 옵션
 */
export async function fetchApi(endpoint, options = {}) {
  const url = endpoint.startsWith('/api') ? endpoint : `${API_BASE}${endpoint}`;
  const headers = { ...options.headers };

  // body가 있고 FormData가 아닐 때만 Content-Type 설정
  if (options.body && !(options.body instanceof FormData)) {
    headers['Content-Type'] = 'application/json';
  }

  const response = await fetch(url, {
    ...options,
    headers,
  });

  return handleResponse(response);
}

/**
 * 인증된 API fetch (토큰 자동 추가)
 * @param {string} endpoint - API 엔드포인트
 * @param {RequestInit} options - fetch 옵션
 */
export async function fetchAuthApi(endpoint, options = {}) {
  const token = useAuthStore.getState().token;

  if (!token) {
    throw new ApiError('인증이 필요합니다.', 401);
  }

  return fetchApi(endpoint, {
    ...options,
    headers: {
      ...options.headers,
      Authorization: `Bearer ${token}`,
    },
  });
}

/**
 * FormData 전송용 (이미지 업로드 등)
 * @param {string} endpoint - API 엔드포인트
 * @param {FormData} formData - 전송할 FormData
 * @param {string} method - HTTP 메서드 (기본: POST)
 */
export async function fetchFormData(endpoint, formData, method = 'POST') {
  const token = useAuthStore.getState().token;
  const url = endpoint.startsWith('/api') ? endpoint : `${API_BASE}${endpoint}`;

  const headers = {};
  if (token) {
    headers.Authorization = `Bearer ${token}`;
  }

  const response = await fetch(url, {
    method,
    headers,
    body: formData,
  });

  return handleResponse(response);
}

/**
 * GET 요청 헬퍼
 */
export const get = (endpoint) => fetchApi(endpoint);
export const authGet = (endpoint) => fetchAuthApi(endpoint);

/**
 * POST 요청 헬퍼
 */
export const post = (endpoint, data) =>
  fetchApi(endpoint, {
    method: 'POST',
    body: JSON.stringify(data),
  });

export const authPost = (endpoint, data) =>
  fetchAuthApi(endpoint, {
    method: 'POST',
    body: JSON.stringify(data),
  });

/**
 * PUT 요청 헬퍼
 */
export const put = (endpoint, data) =>
  fetchApi(endpoint, {
    method: 'PUT',
    body: JSON.stringify(data),
  });

export const authPut = (endpoint, data) =>
  fetchAuthApi(endpoint, {
    method: 'PUT',
    body: JSON.stringify(data),
  });

/**
 * DELETE 요청 헬퍼
 */
export const del = (endpoint) =>
  fetchApi(endpoint, { method: 'DELETE' });

export const authDel = (endpoint) =>
  fetchAuthApi(endpoint, { method: 'DELETE' });
