import { findHandler } from '@/services/mock/registry'
import { camelize } from '@/utils/convert-to-camel-snake'

const sleep = (ms) => new Promise((r) => setTimeout(r, ms))

const stripUrl = (url) => (url ? url.split('?')[0] : '')

const safeParse = (value) => {
  try {
    return camelize(JSON.parse(value))
  } catch {
    return value
  }
}

const mockAdapter = async (config) => {
  const url = stripUrl(config.url || '')
  const method = (config.method || 'get').toUpperCase()
  const match = findHandler(method, url)

  if (!match) {
    const err = new Error(`No mock registered for ${method} ${url}`)
    err.response = {
      status: 404,
      statusText: 'Not Mocked',
      data: { message: err.message },
    }
    err.config = config
    throw err
  }

  await sleep(150)

  const query = config.params ? camelize(config.params) : {}
  let data = config.data
  if (data instanceof FormData) {
    /* leave as-is */
  } else if (typeof data === 'string') {
    data = safeParse(data)
  } else if (data) {
    data = camelize(data)
  }

  const result = await match.entry.handler({
    method,
    url,
    params: match.params,
    query,
    data,
    headers: config.headers,
  })

  return {
    data: result,
    status: 200,
    statusText: 'OK',
    headers: {},
    config,
  }
}

export const isMocksEnabled = () => import.meta.env.VITE_USE_MOCKS === 'true'

import.meta.glob('@/services/mock/routes/*.js', { eager: true })

export const setupMocks = (instance) => {
  if (!isMocksEnabled()) return
  instance.defaults.adapter = mockAdapter
}

export { register } from '@/services/mock/registry'
