// This file is auto-generated by @hey-api/openapi-ts

import type { BodySerializer, QuerySerializer } from "./bodySerializer.gen.js"
import {
  type ArraySeparatorStyle,
  serializeArrayParam,
  serializeObjectParam,
  serializePrimitiveParam,
} from "./pathSerializer.gen.js"

export interface PathSerializer {
  path: Record<string, unknown>
  url: string
}

export const PATH_PARAM_RE = /\{[^{}]+\}/g

export const defaultPathSerializer = ({ path, url: _url }: PathSerializer) => {
  let url = _url
  const matches = _url.match(PATH_PARAM_RE)
  if (matches) {
    for (const match of matches) {
      let explode = false
      let name = match.substring(1, match.length - 1)
      let style: ArraySeparatorStyle = "simple"

      if (name.endsWith("*")) {
        explode = true
        name = name.substring(0, name.length - 1)
      }

      if (name.startsWith(".")) {
        name = name.substring(1)
        style = "label"
      } else if (name.startsWith(";")) {
        name = name.substring(1)
        style = "matrix"
      }

      const value = path[name]

      if (value === undefined || value === null) {
        continue
      }

      if (Array.isArray(value)) {
        url = url.replace(match, serializeArrayParam({ explode, name, style, value }))
        continue
      }

      if (typeof value === "object") {
        url = url.replace(
          match,
          serializeObjectParam({
            explode,
            name,
            style,
            value: value as Record<string, unknown>,
            valueOnly: true,
          }),
        )
        continue
      }

      if (style === "matrix") {
        url = url.replace(
          match,
          `;${serializePrimitiveParam({
            name,
            value: value as string,
          })}`,
        )
        continue
      }

      const replaceValue = encodeURIComponent(style === "label" ? `.${value as string}` : (value as string))
      url = url.replace(match, replaceValue)
    }
  }
  return url
}

export const getUrl = ({
  baseUrl,
  path,
  query,
  querySerializer,
  url: _url,
}: {
  baseUrl?: string
  path?: Record<string, unknown>
  query?: Record<string, unknown>
  querySerializer: QuerySerializer
  url: string
}) => {
  const pathUrl = _url.startsWith("/") ? _url : `/${_url}`
  let url = (baseUrl ?? "") + pathUrl
  if (path) {
    url = defaultPathSerializer({ path, url })
  }
  let search = query ? querySerializer(query) : ""
  if (search.startsWith("?")) {
    search = search.substring(1)
  }
  if (search) {
    url += `?${search}`
  }
  return url
}

export function getValidRequestBody(options: {
  body?: unknown
  bodySerializer?: BodySerializer | null
  serializedBody?: unknown
}) {
  const hasBody = options.body !== undefined
  const isSerializedBody = hasBody && options.bodySerializer

  if (isSerializedBody) {
    if ("serializedBody" in options) {
      const hasSerializedBody = options.serializedBody !== undefined && options.serializedBody !== ""

      return hasSerializedBody ? options.serializedBody : null
    }

    // not all clients implement a serializedBody property (i.e. client-axios)
    return options.body !== "" ? options.body : null
  }

  // plain/text body
  if (hasBody) {
    return options.body
  }

  // no body was provided
  return undefined
}
