export function normalizeApiBase(value: string): string {
  const base = value.replace(/\/+$/, '')
  if (/\/api$/.test(base)) return `${base}/v1`
  return /\/api\/v1$/.test(base) ? base : `${base}/api/v1`
}

const DASHBOARD_PROXY_API_BASE = '/dashboard/api/v1'

function isLocalBrowserHost(hostname: string): boolean {
  return hostname === 'localhost' || hostname === '127.0.0.1' || hostname === '::1'
}

function shouldUseDashboardProxy(configuredApiBase?: string): boolean {
  if (typeof window === 'undefined') return false
  if (!configuredApiBase) return true
  if (configuredApiBase.startsWith('/')) return false

  const currentHostname = window.location?.hostname
  if (!currentHostname || isLocalBrowserHost(currentHostname)) return false

  try {
    return new URL(configuredApiBase).hostname !== currentHostname
  } catch {
    return false
  }
}

export function resolveApiBase(): string {
  if (typeof window === 'undefined') {
    return normalizeApiBase(process.env.API_INTERNAL_URL || 'http://localhost:4000/api/v1')
  }

  const configuredApiBase = process.env.NEXT_PUBLIC_API_URL
  return normalizeApiBase(shouldUseDashboardProxy(configuredApiBase) ? DASHBOARD_PROXY_API_BASE : (configuredApiBase || DASHBOARD_PROXY_API_BASE))
}

export const API_BASE = resolveApiBase()

export const EMPLOYEE_PROFILE_KEY = 'employee_profile'

export async function apiFetch<T>(path: string, options?: RequestInit): Promise<T> {
  const isFormData = typeof FormData !== 'undefined' && options?.body instanceof FormData

  const headers: Record<string, string> = {
    ...(options?.headers as Record<string, string> ?? {}),
  }

  if (!isFormData) {
    headers['Content-Type'] = 'application/json'
  }

  const res = await fetch(`${resolveApiBase()}${path}`, {
    ...options,
    headers,
    credentials: 'include',
  })

  let json: any
  try {
    json = await res.json()
  } catch {
    throw new Error(`HTTP ${res.status}: ${res.statusText}`)
  }

  if (!res.ok) {
    const err = new Error(json?.message ?? json?.error ?? `Request failed with status ${res.status}`) as any
    err.code = json?.error
    err.statusCode = res.status
    throw err
  }

  return (json?.data ?? json) as T
}

export async function apiFetchServer<T>(path: string, token: string, options?: RequestInit): Promise<T> {
  const isFormData = typeof FormData !== 'undefined' && options?.body instanceof FormData
  const res = await fetch(`${resolveApiBase()}${path}`, {
    ...options,
    headers: {
      ...(isFormData ? {} : { 'Content-Type': 'application/json' }),
      'Authorization': `Bearer ${token}`,
      ...(options?.headers as Record<string, string> ?? {}),
    },
    cache: 'no-store',
  })

  let json: any
  try {
    json = await res.json()
  } catch {
    throw new Error(`HTTP ${res.status}: ${res.statusText}`)
  }

  if (!res.ok) {
    const err = new Error(json?.message ?? `Request failed with status ${res.status}`) as any
    err.statusCode = res.status
    throw err
  }

  return (json?.data ?? json) as T
}
