/**
 * Waha WhatsApp API Client
 * Waha CORE (free) only supports a single session named "default".
 * Using NOWEB engine (no Chromium needed — works on ARM Mac).
 */

const WAHA_URL = process.env.WAHA_API_URL || "http://localhost:3005";
const WAHA_API_KEY = process.env.WAHA_API_KEY || "";
const SESSION_NAME = "default";

async function wahaFetch(path: string, options: RequestInit = {}) {
  // 8-second timeout so a dead/unreachable WAHA server never hangs the app
  const controller = new AbortController();
  const timer = setTimeout(() => controller.abort(), 8_000);

  let res: Response;
  try {
    res = await fetch(`${WAHA_URL}${path}`, {
      ...options,
      signal: controller.signal,
      headers: {
        "Content-Type": "application/json",
        ...(WAHA_API_KEY ? { "X-Api-Key": WAHA_API_KEY } : {}),
        ...options.headers,
      },
    });
  } finally {
    clearTimeout(timer);
  }

  if (res.status === 404) return null;

  if (!res.ok) {
    const text = await res.text();
    throw new Error(`Waha ${res.status}: ${text}`);
  }

  const contentType = res.headers.get("content-type") || "";
  if (contentType.includes("application/json")) {
    return res.json();
  }

  // For binary (QR PNG), return as base64 data URL
  if (contentType.includes("image/")) {
    const buffer = await res.arrayBuffer();
    const base64 = Buffer.from(buffer).toString("base64");
    return { value: `data:${contentType};base64,${base64}` };
  }

  return res.text();
}

/**
 * Create or restart the default Waha session.
 */
export async function createSession() {
  // Docker containers can't reach localhost — use WAHA_WEBHOOK_URL or host.docker.internal
  const webhookUrl = process.env.WAHA_WEBHOOK_URL || "http://host.docker.internal:3000/api/webhooks/waha";

  // Check current status
  let status: string | null = null;
  try {
    const existing = await getSessionStatus();
    status = existing?.status || null;
  } catch { /* doesn't exist */ }

  if (status === "SCAN_QR_CODE" || status === "WORKING") {
    // Already running — return as-is
    return { status };
  }

  if (status === "STOPPED" || status === "FAILED") {
    // Exists but stopped — update config and start
    try {
      await wahaFetch(`/api/sessions/${SESSION_NAME}`, {
        method: "PUT",
        body: JSON.stringify({
          config: {
            webhooks: [{ url: webhookUrl, events: ["message", "message.ack", "session.status"] }],
          },
        }),
      });
    } catch { /* ignore config update errors */ }

    await wahaFetch(`/api/sessions/${SESSION_NAME}/start`, { method: "POST" });
    // Wait for it to reach SCAN_QR_CODE
    await new Promise(r => setTimeout(r, 3000));
    return await getSessionStatus();
  }

  // No session exists — create
  try {
    await wahaFetch("/api/sessions", {
      method: "POST",
      body: JSON.stringify({
        name: SESSION_NAME,
        start: true,
        config: {
          webhooks: [{ url: webhookUrl, events: ["message", "message.ack", "session.status"] }],
        },
      }),
    });
  } catch (e) {
    // "already exists" — try starting instead
    if (String(e).includes("already exists")) {
      await wahaFetch(`/api/sessions/${SESSION_NAME}/start`, { method: "POST" });
    } else {
      throw e;
    }
  }

  await new Promise(r => setTimeout(r, 3000));
  return await getSessionStatus();
}

export async function getSessionStatus() {
  return wahaFetch(`/api/sessions/${SESSION_NAME}`);
}

export async function getQRCode() {
  return wahaFetch(`/api/${SESSION_NAME}/auth/qr`);
}

export async function stopSession() {
  return wahaFetch(`/api/sessions/${SESSION_NAME}/stop`, { method: "POST" });
}

export async function deleteSession() {
  return wahaFetch(`/api/sessions/${SESSION_NAME}`, { method: "DELETE" });
}

/**
 * Quick health check — returns true if WAHA is reachable and session is WORKING.
 * Non-throwing: always returns a result.
 */
export async function checkWahaHealth(): Promise<{ ok: boolean; status?: string; error?: string }> {
  try {
    const controller = new AbortController();
    const timer = setTimeout(() => controller.abort(), 5_000);
    let res: Response;
    try {
      res = await fetch(`${WAHA_URL}/api/sessions/${SESSION_NAME}`, {
        signal: controller.signal,
        headers: { ...(WAHA_API_KEY ? { "X-Api-Key": WAHA_API_KEY } : {}) },
      });
    } finally {
      clearTimeout(timer);
    }
    if (!res.ok) return { ok: false, error: `HTTP ${res.status}` };
    const data: any = await res.json();
    const sessionStatus = data?.status ?? "UNKNOWN";
    return { ok: sessionStatus === "WORKING", status: sessionStatus };
  } catch (err: any) {
    const msg = err?.name === "AbortError" ? "WAHA timeout (is Docker running?)" : err?.message ?? String(err);
    return { ok: false, error: msg };
  }
}

export async function sendMessage(phone: string, text: string) {
  const chatId = phone.replace(/[\s\-\+]/g, "") + "@c.us";
  return wahaFetch(`/api/sendText`, {
    method: "POST",
    body: JSON.stringify({ session: SESSION_NAME, chatId, text }),
  });
}

export interface WaButton {
  id: string;
  text: string;
  label?: string;
}

/**
 * Send an interactive choice message.
 *
 * Uses a clear numbered menu — works 100% on every WhatsApp account.
 * Patient simply replies "1", "2", "3" (or the option text).
 */
export async function sendButtons(
  phone: string,
  text: string,
  buttons: WaButton[],
  footer?: string
) {
  const opts = buttons.slice(0, 9);
  const numberEmojis = ["1️⃣","2️⃣","3️⃣","4️⃣","5️⃣","6️⃣","7️⃣","8️⃣","9️⃣"];

  const lines = opts
    .map((b, i) => `${numberEmojis[i]} *${b.label || b.text}*`)
    .join("\n");

  const numbers = opts.map((_, i) => `*${i+1}*`).join(" / ");

  const fullText =
    `${text}\n\n${lines}\n\n_Reply with ${numbers}_` +
    (footer ? `\n\n🏥 _${footer}_` : "");

  console.log(`📋 Numbered menu sent to ${phone}`);
  return sendMessage(phone, fullText);
}

export function renderTemplate(template: string, vars: Record<string, string>): string {
  let result = template;
  for (const [key, value] of Object.entries(vars)) {
    result = result.replaceAll(`{{${key}}}`, value || "");
  }
  return result;
}

export { SESSION_NAME };
