import { Agent } from 'undici'
import type { IntegrationAdapter, Resource } from './types.js'

interface ProxmoxResourceEntry {
  type: string
  name?: string
  status?: string
  vmid?: number
  node?: string
}

function authHeader(apiKey: string): Record<string, string> {
  return { Authorization: `PVEAPIToken=${apiKey}` }
}

// Proxmox ships with a self-signed cert by default, which Node's fetch rejects out of the box.
const insecureDispatcher = new Agent({ connect: { rejectUnauthorized: false } })

// undici's fetch() wraps the real failure (DNS, TLS, connection refused/timed out) in a generic
// "fetch failed" TypeError — unwrap err.cause so the actual reason reaches the UI.
function describeFetchError(err: unknown): string {
  if (err instanceof Error) {
    const cause = (err as { cause?: unknown }).cause
    if (cause instanceof Error) return `${err.message}: ${cause.message}`
    return err.message
  }
  return 'Connection failed'
}

export const proxmox: IntegrationAdapter = {
  async testConnection(config, secrets) {
    const baseUrl = config.baseUrl?.replace(/\/$/, '')
    const apiKey = secrets.apiKey
    if (!baseUrl) return { ok: false, message: 'Missing baseUrl' }
    if (!apiKey) return { ok: false, message: 'Missing API token' }
    try {
      const res = await fetch(`${baseUrl}/api2/json/version`, {
        headers: authHeader(apiKey),
        dispatcher: insecureDispatcher,
      } as RequestInit)
      if (!res.ok) return { ok: false, message: `HTTP ${res.status}` }
      return { ok: true, message: 'Connected' }
    } catch (err) {
      return { ok: false, message: describeFetchError(err) }
    }
  },

  async listResources(config, secrets): Promise<Resource[]> {
    const baseUrl = config.baseUrl?.replace(/\/$/, '')
    const apiKey = secrets.apiKey
    if (!baseUrl || !apiKey) return []
    const res = await fetch(`${baseUrl}/api2/json/cluster/resources?type=vm`, {
      headers: authHeader(apiKey),
      dispatcher: insecureDispatcher,
    } as RequestInit)
    if (!res.ok) return []
    const body = (await res.json()) as { data: ProxmoxResourceEntry[] }
    return body.data.map((entry) => ({
      name: entry.name ?? `vm-${entry.vmid}`,
      status: entry.status === 'running' ? 'healthy' : entry.status === 'stopped' ? 'unknown' : 'warning',
      detail: `${entry.type} on ${entry.node} — ${entry.status}`,
    }))
  },
}
