/**
 * AdGuard Home API Client für RebreakMagic DNS-over-HTTPS Client-Provisioning.
 * Docs: https://github.com/AdguardTeam/AdGuardHome/tree/master/openapi
 */

export interface AdGuardClientOptions {
  use_global_settings?: boolean;
  filtering_enabled?: boolean;
  parental_enabled?: boolean;
  safebrowsing_enabled?: boolean;
  safesearch_enabled?: boolean;
  blocked_services?: string[];
  upstreams?: string[];
  tags?: string[];
}

interface AdGuardClientPayload {
  name: string;
  ids: string[];
  use_global_settings?: boolean;
  filtering_enabled?: boolean;
  parental_enabled?: boolean;
  safebrowsing_enabled?: boolean;
  safesearch_enabled?: boolean;
  blocked_services?: string[];
  upstreams?: string[];
  tags?: string[];
}

/**
 * Erstellt einen AdGuard Persistent Client mit gegebener Client-ID (DNS-Token).
 * AdGuard nutzt die Client-ID im DoH-URL-Path: /dns-query/{clientId}
 *
 * @param name - Interner Client-Name (z.B. "magic_<deviceId>")
 * @param clientId - DNS-Token (wird in DoH URL embedded)
 * @param options - Filtering/Blocking-Optionen
 */
export async function createAdGuardClient(
  name: string,
  clientId: string,
  options: AdGuardClientOptions = {},
): Promise<void> {
  const config = useRuntimeConfig();
  const baseUrl = config.adguardBaseUrl || "https://dns.rebreak.org";
  const user = config.adguardUser;
  const password = config.adguardPassword;

  if (!user || !password) {
    throw createError({
      statusCode: 500,
      message: "ADGUARD_USER and ADGUARD_PASSWORD required for Magic features",
    });
  }

  const payload: AdGuardClientPayload = {
    name,
    ids: [clientId],
    ...options,
  };

  const authHeader = `Basic ${Buffer.from(`${user}:${password}`).toString("base64")}`;
  const headers = {
    Authorization: authHeader,
    "Content-Type": "application/json",
  };

  try {
    const response = await $fetch(`${baseUrl}/control/clients/add`, {
      method: "POST",
      headers,
      body: payload,
    });
    return response as void;
  } catch (err: any) {
    // AdGuard antwortet mit 400, wenn schon ein Client mit diesem Namen ODER
    // dieser Client-ID existiert. Das passiert bei Re-Registrierung wenn ein
    // früherer Versuch den Client anlegte, aber die DB-Row nie geschrieben wurde
    // (z.B. Prozess-Crash zwischen clients/add und DB-Upsert). Statt hart zu
    // failen → idempotent auf clients/update zurückfallen und den bestehenden
    // Client auf den frisch generierten clientId umbiegen.
    const status = err?.status ?? err?.response?.status ?? err?.statusCode;
    if (status === 400) {
      try {
        const response = await $fetch(`${baseUrl}/control/clients/update`, {
          method: "POST",
          headers,
          body: { name, data: payload },
        });
        return response as void;
      } catch (updErr: any) {
        console.error(
          "[AdGuard] Client update (after add-conflict) failed:",
          updErr,
        );
        throw createError({
          statusCode: 502,
          message: `AdGuard API error (update): ${updErr.message || "unknown"}`,
        });
      }
    }
    console.error("[AdGuard] Client creation failed:", err);
    throw createError({
      statusCode: 502,
      message: `AdGuard API error: ${err.message || "unknown"}`,
    });
  }
}

/**
 * Löscht einen AdGuard Persistent Client.
 * @param name - Interner Client-Name (z.B. "magic_<deviceId>")
 */
export async function deleteAdGuardClient(name: string): Promise<void> {
  const config = useRuntimeConfig();
  const baseUrl = config.adguardBaseUrl || "https://dns.rebreak.org";
  const user = config.adguardUser;
  const password = config.adguardPassword;

  if (!user || !password) {
    throw createError({
      statusCode: 500,
      message: "ADGUARD_USER and ADGUARD_PASSWORD required for Magic features",
    });
  }

  const authHeader = `Basic ${Buffer.from(`${user}:${password}`).toString("base64")}`;

  try {
    const response = await $fetch(`${baseUrl}/control/clients/delete`, {
      method: "POST",
      headers: {
        Authorization: authHeader,
        "Content-Type": "application/json",
      },
      body: { name },
    });
    return response as void;
  } catch (err: any) {
    console.error("[AdGuard] Client deletion failed:", err);
    throw createError({
      statusCode: 502,
      message: `AdGuard API error: ${err.message || "unknown"}`,
    });
  }
}
