type AuthUser = {
  id: string
  email: string
  name: string
  role?: string
  type?: string
}

const getApiBase = () => {
  if (typeof window !== 'undefined') {
    return ''
  }

  const viteEnv = (import.meta as ImportMeta & {
    env?: Record<string, string | undefined>
  }).env

  return viteEnv?.VITE_API_BASE_URL || process.env.VITE_API_BASE_URL || process.env.API_URL || ''
}

const getErrorMessage = async (response: Response) => {
  const text = await response.text()

  if (!text) {
    return `Request failed with status ${response.status}`
  }

  try {
    const data = JSON.parse(text) as { message?: string; error?: string }
    return data.message || data.error || text
  } catch {
    return text
  }
}

const authFetch = async <T>(path: string, init?: RequestInit): Promise<T> => {
  const headers = new Headers(init?.headers)
  const hasBody = init?.body !== undefined && init?.body !== null

  if (hasBody && !headers.has('content-type')) {
    headers.set('content-type', 'application/json')
  }

  const response = await fetch(`${getApiBase()}${path}`, {
    ...init,
    credentials: 'include',
    headers,
  })

  if (!response.ok) {
    throw new Error(await getErrorMessage(response))
  }

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

  return await response.json() as T
}

export const signInWithPassword = async (email: string, password: string) => {
  return await authFetch<{
    redirect: boolean
    token: string
    url?: string
    user: AuthUser
  }>('/api/auth/sign-in/email', {
    method: 'POST',
    body: JSON.stringify({
      email,
      password,
    }),
  })
}

export const requestMagicLink = async (email: string) => {
  return await authFetch<{ status: boolean }>('/api/auth/sign-in/magic-link', {
    method: 'POST',
    body: JSON.stringify({ email }),
  })
}

export const verifyMagicLink = async (token: string) => {
  return await authFetch<{
    token: string
    user: AuthUser
    session: {
      id: string
      userId: string
      expiresAt: string
    }
  }>(`/api/auth/magic-link/verify?token=${encodeURIComponent(token)}`, {
    method: 'GET',
  })
}

export const signOut = async () => {
  return await authFetch('/api/auth/sign-out', {
    method: 'POST',
    body: JSON.stringify({}),
  })
}
