function isBinaryValue(value) {
  if (!value) {
    return false
  }

  if (typeof File !== 'undefined' && value instanceof File) {
    return true
  }

  if (typeof Blob !== 'undefined' && value instanceof Blob) {
    return true
  }

  if (Array.isArray(value)) {
    return value.some((entry) => isBinaryValue(entry))
  }

  if (typeof value === 'object') {
    return Object.values(value).some((entry) => isBinaryValue(entry))
  }

  return false
}

function appendFormData(formData, key, value) {
  if (value === undefined || value === null || value === '') {
    return
  }

  if (typeof File !== 'undefined' && value instanceof File) {
    formData.append(key, value)
    return
  }

  if (typeof Blob !== 'undefined' && value instanceof Blob) {
    formData.append(key, value)
    return
  }

  if (Array.isArray(value)) {
    value.forEach((entry, index) => {
      appendFormData(formData, `${key}[${index}]`, entry)
    })
    return
  }

  if (typeof value === 'object') {
    Object.entries(value).forEach(([childKey, childValue]) => {
      appendFormData(formData, key ? `${key}[${childKey}]` : childKey, childValue)
    })
    return
  }

  formData.append(key, String(value))
}

function toFormData(payload) {
  const formData = new FormData()

  Object.entries(payload || {}).forEach(([key, value]) => {
    appendFormData(formData, key, value)
  })

  return formData
}

export function usePublicBooking() {
  const config = useRuntimeConfig()

  async function fetchQuote(payload) {
    const response = await $fetch(`${config.public.apiBaseUrl}/public-catalog/quote`, {
      method: 'POST',
      body: payload,
    })

    return response?.data || {}
  }

  async function createBooking(payload) {
    const body = isBinaryValue(payload) ? toFormData(payload) : payload
    const response = await $fetch(`${config.public.apiBaseUrl}/public-booking`, {
      method: 'POST',
      body,
    })

    return response?.data || {}
  }

  async function fetchBooking(token) {
    const response = await $fetch(`${config.public.apiBaseUrl}/public-booking/${token}`)
    return response?.data || {}
  }

  async function createCheckout(token) {
    const response = await $fetch(`${config.public.apiBaseUrl}/public-booking/${token}/checkout`, {
      method: 'POST',
    })

    return response?.data || {}
  }

  return {
    createBooking,
    createCheckout,
    fetchBooking,
    fetchQuote,
  }
}
