import { ApiClientError } from "@/shared/api/http-client"

function trimBaseUrl(baseUrl: string): string {
  return baseUrl.replace(/\/$/, "")
}

function parseFilename(contentDisposition: string | null, fallback: string): string {
  if (!contentDisposition) return fallback
  const utfMatch = /filename\*=UTF-8''([^;]+)/i.exec(contentDisposition)
  if (utfMatch?.[1]) {
    try {
      return decodeURIComponent(utfMatch[1])
    } catch {
      return utfMatch[1]
    }
  }
  const plainMatch = /filename="([^"]+)"/i.exec(contentDisposition)
  if (plainMatch?.[1]) return plainMatch[1]
  return fallback
}

export async function downloadSystemDatabaseBackup(
  baseUrl: string,
): Promise<{ blob: Blob; filename: string }> {
  const res = await fetch(`${trimBaseUrl(baseUrl)}/api/system/database/backup`)
  if (!res.ok) {
    const payload = await res.json().catch(() => undefined)
    const msg =
      typeof payload === "object" &&
      payload !== null &&
      "error" in payload &&
      typeof (payload as { error?: unknown }).error === "string"
        ? (payload as { error: string }).error
        : res.statusText
    throw new ApiClientError(msg, res.status, payload)
  }
  const blob = await res.blob()
  const filename = parseFilename(res.headers.get("Content-Disposition"), "mikrotik-manager.db")
  return { blob, filename }
}

export async function restoreSystemDatabaseBackup(baseUrl: string, file: File): Promise<void> {
  const body = await file.arrayBuffer()
  const res = await fetch(`${trimBaseUrl(baseUrl)}/api/system/database/restore`, {
    method: "POST",
    headers: { "Content-Type": "application/octet-stream" },
    body,
  })
  if (!res.ok) {
    const payload = await res.json().catch(() => undefined)
    const msg =
      typeof payload === "object" &&
      payload !== null &&
      "error" in payload &&
      typeof (payload as { error?: unknown }).error === "string"
        ? (payload as { error: string }).error
        : res.statusText
    throw new ApiClientError(msg, res.status, payload)
  }
}
