/**
 * Native resize via libagor-resize.so — C shared library that owns
 * GTK signal connections and calls begin_resize_drag with real event data.
 *
 * The C library:
 * 1. Connects button-press-event on GtkWindow + WebView children (in C)
 * 2. Stores mouseButton, xroot, yroot, dragTime from real GTK events
 * 3. Exports agor_resize_start(edge) that Bun calls via FFI
 *
 * This avoids JSCallback boundary crossing (which crashes in Bun).
 */

import { dlopen, FFIType } from "bun:ffi";
import { join } from "path";
import { existsSync } from "fs";

let lib: ReturnType<typeof dlopen> | null = null;

function loadLib(): ReturnType<typeof dlopen> | null {
  if (lib) return lib;

  // Search paths for the .so
  const candidates = [
    join(import.meta.dir, "../../agor-pty/native/libagor-resize.so"),
    join(import.meta.dir, "../../../agor-pty/native/libagor-resize.so"),
    "/home/hibryda/code/ai/agent-orchestrator/agor-pty/native/libagor-resize.so",
  ];

  const soPath = candidates.find(p => existsSync(p));
  if (!soPath) {
    console.error("[native-resize] libagor-resize.so not found. Searched:", candidates);
    return null;
  }

  try {
    lib = dlopen(soPath, {
      agor_resize_init: {
        args: [FFIType.ptr, FFIType.i32],
        returns: FFIType.void,
      },
      agor_resize_start: {
        args: [FFIType.i32],
        returns: FFIType.i32,
      },
    });
    console.log("[native-resize] Loaded:", soPath);
    return lib;
  } catch (err) {
    console.error("[native-resize] Failed to load:", err);
    return null;
  }
}

/**
 * Initialize native resize handler. Call once after window creation.
 */
export function initNativeResize(windowPtr: number | bigint, borderPx: number = 8): boolean {
  const l = loadLib();
  if (!l) return false;
  try {
    l.symbols.agor_resize_init(windowPtr as any, borderPx);
    return true;
  } catch (err) {
    console.error("[native-resize] init failed:", err);
    return false;
  }
}

// GdkWindowEdge mapping
const EDGE_MAP: Record<string, number> = {
  n: 1, s: 6, e: 4, w: 3,
  ne: 2, nw: 0, se: 7, sw: 5,
};

/**
 * Start a resize drag. Call from RPC when JS detects mousedown in border zone.
 * The C library uses stored mouse state from the real GTK button-press event.
 */
export function startNativeResize(edge: string): boolean {
  const l = loadLib();
  if (!l) return false;
  const gdkEdge = EDGE_MAP[edge];
  if (gdkEdge === undefined) {
    console.error("[native-resize] Unknown edge:", edge);
    return false;
  }
  try {
    const ok = l.symbols.agor_resize_start(gdkEdge);
    return ok === 1;
  } catch (err) {
    console.error("[native-resize] start failed:", err);
    return false;
  }
}
