import { existsSync } from "node:fs";
import path from "node:path";
import { resolveScraplingPython } from "../pythonRuntime.js";
import { processSupervisor } from "../processSupervisor.js";

export class ScraplingAdapter {
  constructor({ rootDir }) {
    this.rootDir = rootDir;
    this.python = resolveScraplingPython(rootDir);
    this.scriptPath = path.join(rootDir, "tools", "hermes_scrapling_enrich.py");
  }

  available() {
    return existsSync(this.scriptPath);
  }

  async enrich({ url, mode = "simple", timeout = 25 }) {
    if (!url) return { ok: false, error: "missing website", emails: [], phones: [], text: "" };
    const result = await runJsonProcess(this.python, [this.scriptPath], { url, mode, timeout });
    if (mode === "simple" && (!result.ok || looksProtected(result))) {
      const dynamic = await runJsonProcess(this.python, [this.scriptPath], { url, mode: "dynamic", timeout: timeout + 15 });
      if (dynamic.ok && !looksProtected(dynamic)) return dynamic;
      return runJsonProcess(this.python, [this.scriptPath], { url, mode: "stealth", timeout: timeout + 25 });
    }
    if (mode === "dynamic" && (!result.ok || looksProtected(result))) {
      return runJsonProcess(this.python, [this.scriptPath], { url, mode: "stealth", timeout: timeout + 20 });
    }
    return result;
  }
}

function looksProtected(result = {}) {
  const text = `${result.title || ""} ${result.text || ""} ${result.error || ""}`.toLowerCase();
  if (!text) return false;
  return /cloudflare|cf-browser-verification|checking your browser|attention required|just a moment|verify you are human|captcha|access denied|ddos protection|ray id/.test(text);
}

function runJsonProcess(command, args, payload) {
  return new Promise((resolve) => {
    const child = processSupervisor.spawn(command, args, {
      stdio: ["pipe", "pipe", "pipe"],
      detached: process.platform !== "win32"
    }, { label: "scrapling", killGroup: true });
    let stdout = "";
    let stderr = "";
    const timer = setTimeout(() => {
      processSupervisor.killChild(child, "SIGTERM");
      stderr += "\nTimed out";
      setTimeout(() => processSupervisor.killChild(child, "SIGKILL"), 5000).unref?.();
    }, (payload.timeout + 10) * 1000);

    child.stdout.on("data", (chunk) => { stdout += chunk.toString(); });
    child.stderr.on("data", (chunk) => { stderr += chunk.toString(); });
    child.on("close", () => {
      clearTimeout(timer);
      try {
        const jsonLine = stdout.trim().split(/\r?\n/).reverse().find((line) => line.trim().startsWith("{"));
        resolve(JSON.parse(jsonLine || stdout));
      } catch {
        resolve({ ok: false, error: stderr || stdout || "enrichment failed", emails: [], phones: [], text: "" });
      }
    });
    child.on("error", (error) => {
      clearTimeout(timer);
      resolve({ ok: false, error: error.message, emails: [], phones: [], text: "" });
    });
    child.stdin.end(JSON.stringify(payload));
  });
}
