const API_BASE_STORAGE_KEY = 'x-financial-api-base-url'
const AUTH_USER_STORAGE_KEY = 'x-financial-auth-user'

function readCurrentUserHeaders() {
  if (typeof window === 'undefined') {
    return {}
  }

  const raw = window.sessionStorage.getItem(AUTH_USER_STORAGE_KEY)
  if (!raw) {
    return {}
  }

  try {
    const payload = JSON.parse(raw)
    const username = String(payload?.username || '').trim()
    const name = String(payload?.name || username).trim()
    const roleCodes = Array.isArray(payload?.roleCodes) ? payload.roleCodes.filter(Boolean) : []
    const isAdmin = Boolean(payload?.isAdmin)

    if (!username && !name) {
      return {}
    }

    return {
      'x-auth-username': username,
      'x-auth-name': name,
      'x-auth-role-codes': roleCodes.join(','),
      'x-auth-is-admin': String(isAdmin)
    }
  } catch {
    return {}
  }
}

function normalizeApiBaseUrl(value) {
  return String(value || '/api/v1').replace(/\/$/, '')
}

function isLoopbackHost(hostname) {
  const normalized = String(hostname || '').trim().toLowerCase()
  return normalized === '127.0.0.1' || normalized === 'localhost' || normalized === '0.0.0.0' || normalized === '::1'
}

function resolveBrowserReachableApiBaseUrl(value) {
  const normalized = normalizeApiBaseUrl(value)

  if (typeof window === 'undefined') {
    return normalized
  }

  try {
    const apiUrl = new URL(normalized)
    const browserHost = window.location.hostname

    if (isLoopbackHost(apiUrl.hostname) && browserHost && !isLoopbackHost(browserHost)) {
      apiUrl.hostname = browserHost
      return normalizeApiBaseUrl(apiUrl.toString())
    }
  } catch {
    return normalized
  }

  return normalized
}

function readStoredApiBaseUrl() {
  if (typeof window === 'undefined') {
    return ''
  }

  return resolveBrowserReachableApiBaseUrl(window.localStorage.getItem(API_BASE_STORAGE_KEY) || '')
}

let runtimeApiBaseUrl = normalizeApiBaseUrl('/api/v1')

if (typeof window !== 'undefined') {
  window.localStorage.removeItem(API_BASE_STORAGE_KEY)
}

export function setRuntimeApiBaseUrl(value) {
  runtimeApiBaseUrl = resolveBrowserReachableApiBaseUrl(value)

  if (typeof window !== 'undefined') {
    window.localStorage.setItem(API_BASE_STORAGE_KEY, runtimeApiBaseUrl)
  }
}

export function getRuntimeApiBaseUrl() {
  return runtimeApiBaseUrl
}

function buildUrl(path) {
  if (!path.startsWith('/')) {
    return `${runtimeApiBaseUrl}/${path}`
  }

  return `${runtimeApiBaseUrl}${path}`
}

export async function apiRequest(path, options = {}) {
  const {
    contentType = 'application/json',
    responseType = 'json',
    headers: customHeaders,
    ...fetchOptions
  } = options

  const headers = {
    ...readCurrentUserHeaders(),
    ...(customHeaders || {})
  }

  if (contentType !== null && typeof headers['Content-Type'] === 'undefined') {
    headers['Content-Type'] = contentType
  }

  let response

  try {
    response = await fetch(buildUrl(path), {
      ...fetchOptions,
      headers
    })
  } catch {
    throw new Error('无法连接 FastAPI 后端服务，请确认后端已启动且浏览器可访问后端端口。')
  }

  if (responseType === 'blob') {
    if (!response.ok) {
      let payload = null

      try {
        payload = await response.json()
      } catch {
        payload = null
      }

      throw new Error(payload?.detail || '接口请求失败，请稍后重试。')
    }

    return response.blob()
  }

  let payload = null
  try {
    payload = await response.json()
  } catch {
    payload = null
  }

  if (!response.ok) {
    throw new Error(payload?.detail || '接口请求失败，请稍后重试。')
  }

  return payload
}
