import { useRequestFetch, useRuntimeConfig } from '#imports'
import { MODULES_API_URL, SERVER_API_URL, APP_API_URL } from '@/config/setting'
import { getTenantId } from '@/utils/domain'
import { getToken } from '@/utils/token-util'

type RequestConfig = {
  params?: Record<string, any>
  data?: any
  headers?: Record<string, any>
  responseType?: 'json' | 'blob' | 'text' | 'arrayBuffer'
}

type AxiosLikeResponse<T> = {
  data: T
}

type NuxtFetch = ReturnType<typeof useRequestFetch>
type NuxtFetchOptions = NonNullable<Parameters<NuxtFetch>[1]>
type NuxtFetchMethod = NonNullable<NuxtFetchOptions['method']>

function getFetch(): NuxtFetch {
  try {
    return useRequestFetch()
  } catch {
    return globalThis.$fetch as unknown as NuxtFetch
  }
}

function normalizeUrl(url: string) {
  const config = useRuntimeConfig()
  const serverBase = config.public.serverApiBase
  const modulesBase = config.public.modulesApiBase
  const appBase = config.public.appApiBase

  if (url.startsWith(serverBase)) {
    return SERVER_API_URL + url.slice(serverBase.length)
  }
  if (url.startsWith(modulesBase)) {
    return MODULES_API_URL + url.slice(modulesBase.length)
  }
  if (url.startsWith(appBase)) {
    return APP_API_URL + url.slice(appBase.length)
  }
  return url
}

function mergeHeaders(headers?: Record<string, any>) {
  const config = useRuntimeConfig()
  const tenantId = headers?.TenantId ?? headers?.tenantId ?? getTenantId(String(config.public.tenantId))
  const token = getToken()

  const merged: Record<string, string> = {
    TenantId: String(tenantId)
  }

  if (token) {
    merged.Authorization = token
  }

  if (headers) {
    for (const [key, value] of Object.entries(headers)) {
      if (value === undefined || value === null) continue
      merged[key] = String(value)
    }
  }

  return merged
}

function withDefaultModuleBase(url: string) {
  if (url.startsWith('http://') || url.startsWith('https://')) return url
  // 已带 /api 前缀的直接返回（避免重复拼接）
  if (url.startsWith('/api/_server') || url.startsWith('/api/_modules') || url.startsWith('/api/_file')) return url
  // App 模块走 /api/_app 前缀（proxy: server/api/_app/[...path].ts）
  if (url.startsWith('/api/app')) return '/api/_app' + url.slice('/api/app'.length)
  // 其余默认走 modules
  if (!url.startsWith('/')) return MODULES_API_URL + '/' + url
  return MODULES_API_URL + url
}

async function request<T>(
  method: NuxtFetchMethod,
  url: string,
  body?: any,
  config: RequestConfig = {}
): Promise<AxiosLikeResponse<T>> {
  const $fetch = getFetch()
  const normalized = withDefaultModuleBase(normalizeUrl(url))

  const data = await $fetch<T>(normalized, {
    method,
    query: config.params,
    body: body ?? config.data,
    headers: mergeHeaders(config.headers),
    responseType: config.responseType as any
  })

  return { data }
}

const requestClient = {
  get: <T>(url: string, config?: RequestConfig) => request<T>('GET', url, undefined, config),
  delete: <T>(url: string, config?: RequestConfig) => request<T>('DELETE', url, undefined, config),
  post: <T>(url: string, data?: any, config?: RequestConfig) => request<T>('POST', url, data, config),
  put: <T>(url: string, data?: any, config?: RequestConfig) => request<T>('PUT', url, data, config)
}

export default requestClient
