export interface ApiResponse<T = any> {
  success: boolean
  data: T
  error: string | null
}

export interface FetchOptions extends RequestInit {
  timeout?: number
  retries?: number
  validateJson?: boolean
}

export async function apiFetch<T = any>(url: string, options: FetchOptions = {}): Promise<ApiResponse<T>> {
  const { timeout = 30000, retries = 2, validateJson = true, ...fetchOptions } = options

  let lastError: Error | null = null

  for (let attempt = 0; attempt <= retries; attempt++) {
    try {
      const controller = new AbortController()
      const timeoutId = setTimeout(() => controller.abort(), timeout)

      const response = await fetch(url, {
        ...fetchOptions,
        signal: controller.signal,
      })

      clearTimeout(timeoutId)

      if (!response.ok) {
        throw new Error(`HTTP ${response.status}: ${response.statusText}`)
      }

      const text = await response.text()

      if (!text || text.trim() === "") {
        return { success: true, data: [] as any, error: null }
      }

      if (validateJson) {
        try {
          const json = JSON.parse(text)

          if (json && typeof json === "object" && "success" in json) {
            return json
          }

          if (Array.isArray(json)) {
            return { success: true, data: json, error: null }
          }

          if (json && typeof json === "object") {
            return { success: true, data: json, error: null }
          }

          return { success: true, data: json, error: null }
        } catch (parseError) {
          console.error("[apiFetch] JSON parse error:", parseError)
          return { success: false, data: [] as any, error: "Invalid JSON response" }
        }
      }

      return { success: true, data: text as any, error: null }
    } catch (error: any) {
      lastError = error

      if (error.name === "AbortError") {
        console.error(`[apiFetch] Timeout on attempt ${attempt + 1}/${retries + 1}`)
      } else {
        console.error(`[apiFetch] Error on attempt ${attempt + 1}/${retries + 1}:`, error.message)
      }

      if (attempt < retries) {
        await new Promise((resolve) => setTimeout(resolve, 1000 * (attempt + 1)))
      }
    }
  }

  return {
    success: false,
    data: [] as any,
    error: lastError?.message || "Network request failed",
  }
}

export function createApiUrl(path: string, params?: Record<string, any>): string {
  const url = new URL(path, typeof window !== "undefined" ? window.location.origin : "http://localhost:3000")

  if (params) {
    Object.entries(params).forEach(([key, value]) => {
      if (value !== undefined && value !== null) {
        url.searchParams.append(key, String(value))
      }
    })
  }

  return url.toString()
}
