const DEFAULT_NOTION_API_BASE_URL = 'https://notion-api.nvme0n1p.dev'

function readRuntimeEnv(key: string): string | undefined {
  if (typeof process === 'undefined') return undefined
  const value = process.env[key]
  return value && value.trim() ? value.trim() : undefined
}

export class NotionApiError extends Error {
  status: number
  url: string

  constructor(message: string, status: number, url: string) {
    super(message)
    this.name = 'NotionApiError'
    this.status = status
    this.url = url
  }
}

function normalizeBaseUrl(value: string): string {
  return value.replace(/\/+$/, '')
}

export function getNotionApiServerBaseUrl(): string {
  return normalizeBaseUrl(
    readRuntimeEnv('NOTION_API_BASE_URL') ||
      readRuntimeEnv('PUBLIC_NOTION_API_BASE_URL') ||
      import.meta.env.NOTION_API_BASE_URL ||
      import.meta.env.PUBLIC_NOTION_API_BASE_URL ||
      DEFAULT_NOTION_API_BASE_URL,
  )
}

export function getNotionApiPublicBaseUrl(): string {
  return normalizeBaseUrl(
    readRuntimeEnv('PUBLIC_NOTION_API_BASE_URL') ||
      readRuntimeEnv('NOTION_API_BASE_URL') ||
      import.meta.env.PUBLIC_NOTION_API_BASE_URL ||
      import.meta.env.NOTION_API_BASE_URL ||
      DEFAULT_NOTION_API_BASE_URL,
  )
}

export function buildNotionApiUrl(path: string): string {
  return new URL(path, `${getNotionApiPublicBaseUrl()}/`).toString()
}

export async function fetchNotionApiJson<T>(path: string): Promise<T> {
  const url = new URL(path, `${getNotionApiServerBaseUrl()}/`).toString()
  const res = await fetch(url)

  if (!res.ok) {
    throw new NotionApiError(`Failed to fetch ${url}: ${res.status}`, res.status, url)
  }

  return (await res.json()) as T
}
