import type { FetchOptions } from 'ofetch'
import { useStorage } from '@vueuse/core'

type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE'

interface HttpRequestOptions<T = unknown> extends FetchOptions {
  data?: T
}

export const useHttpService = () => {
  const config = useRuntimeConfig()
  const token = useStorage('id_token', 'GuestAccess')

  /**
   * Constructs the full API URL
   */
  const getFullUrl = (endpoint: string): string => {
    return `${config.public.NUXT_PUBLIC_BASE_URL}${config.public.NUXT_PUBLIC_API_NAME}${endpoint}`
  }

  /**
   * Base fetch method with common configuration
   */
  const baseFetch = async <T = any>(
    method: HttpMethod,
    url: string,
    options: HttpRequestOptions = {}
  ) => {
    const headers = {
      ...options.headers,
      ...(token.value ? { Authorization: token.value } : {})
    }

    try {
      const response = await $fetch<T>(getFullUrl(url), {
        method,
        headers,
        ...options,
        body: options.data || options.body
      })

      return response
    } catch (error) {
      // Handle errors globally or rethrow for specific handling
      console.error(`HTTP ${method} error for ${url}:`, error)
      throw error
    }
  }

  return {
    /**
     * GET request
     */
    getRequest: <T = any>(url: string, options?: HttpRequestOptions) => 
      baseFetch<T>('GET', url, options),

    /**
     * POST request
     */
    postRequest: <T = any>(url: string, data?: any, options?: HttpRequestOptions) =>
      baseFetch<T>('POST', url, { ...options, data }),

    /**
     * PUT request
     */
    putRequest: <T = any>(url: string, data?: any, options?: HttpRequestOptions) =>
      baseFetch<T>('PUT', url, { ...options, data }),

    /**
     * PATCH request
     */
    patchRequest: <T = any>(url: string, data?: any, options?: HttpRequestOptions) =>
      baseFetch<T>('PATCH', url, { ...options, data }),

    /**
     * DELETE request
     */
    deleteRequest: <T = any>(url: string, options?: HttpRequestOptions) =>
      baseFetch<T>('DELETE', url, options)
  }
}