export type ApiSession = {
  baseUrl: string
  token: string
}

type RequestOptions = {
  method?: string
  body?: unknown
  token?: string
}

let configuredBaseUrl = normalizeBaseUrl(import.meta.env.VITE_API_BASE_URL ?? 'http://127.0.0.1:18080')

export function setApiBaseUrl(baseUrl: string) {
  configuredBaseUrl = normalizeBaseUrl(baseUrl)
}

export function getApiBaseUrl() {
  return configuredBaseUrl
}

export async function login(email: string, password: string): Promise<ApiSession> {
  const response = await apiRequest<{ token: string }>('/api/auth/login', {
    method: 'POST',
    body: { email, password },
  })
  return { baseUrl: configuredBaseUrl, token: response.token }
}

export async function apiRequest<T>(path: string, options: RequestOptions = {}): Promise<T> {
  const isFormData = typeof FormData !== 'undefined' && options.body instanceof FormData
  const requestBody = options.body === undefined ? undefined : isFormData ? options.body : JSON.stringify(options.body)
  const response = await fetch(`${configuredBaseUrl}${path}`, {
    method: options.method ?? 'GET',
    headers: {
      ...(isFormData ? {} : { 'Content-Type': 'application/json' }),
      ...(options.token ? { Authorization: `Bearer ${options.token}` } : {}),
    },
    body: requestBody as BodyInit | undefined,
  })

  if (!response.ok) {
    let message = `请求失败：${response.status}`
    try {
      const payload = await response.json()
      if (typeof payload.error === 'string') message = payload.error
    } catch {
      // Keep the status-based message when the server does not return JSON.
    }
    throw new Error(message)
  }

  if (response.status === 204) {
    return undefined as T
  }

  const text = await response.text()
  if (text.trim() === '') {
    return undefined as T
  }
  return JSON.parse(text) as T
}

function normalizeBaseUrl(value: string) {
  const trimmed = value.trim()
  return trimmed.endsWith('/') ? trimmed.slice(0, -1) : trimmed
}
