import fs from "fs";
import path from "path";
import os from "os";
import { spawn } from "child_process";
import net from "net";

export interface ChromeVersionResponse {
  webSocketDebuggerUrl: string;
}

const userDataDir = path.join(os.tmpdir(), "chrome-debug-profile");

export const getLocalISOString = (date = new Date()) => {
  const offset = date.getTimezoneOffset();
  const offsetAbs = Math.abs(offset);
  const hours = Math.floor(offsetAbs / 60)
    .toString()
    .padStart(2, "0");
  const minutes = (offsetAbs % 60).toString().padStart(2, "0");
  const sign = offset > 0 ? "-" : "+";

  return new Date(date.getTime() - offset * 60000)
    .toISOString()
    .replace("Z", `${sign}${hours}:${minutes}`);
};

function getChromePath(): string {
  const platform = os.platform();

  const paths: Record<NodeJS.Platform, string[]> = {
    darwin: [
      "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome",
      "/Applications/Google Chrome Canary.app/Contents/MacOS/Google Chrome Canary",
      "/Applications/Chromium.app/Contents/MacOS/Chromium",
    ],
    win32: [
      process.env.LOCALAPPDATA + "\\Google\\Chrome\\Application\\chrome.exe",
      process.env.PROGRAMFILES + "\\Google\\Chrome\\Application\\chrome.exe",
      process.env["PROGRAMFILES(X86)"] +
        "\\Google\\Chrome\\Application\\chrome.exe",
    ],
    linux: [
      "/usr/bin/google-chrome",
      "/usr/bin/google-chrome-stable",
      "/usr/bin/chromium",
      "/usr/bin/chromium-browser",
    ],
    aix: [],
    freebsd: [],
    openbsd: [],
    sunos: [],
    android: [],
    haiku: [],
    cygwin: [],
    netbsd: [],
  };

  const platformPaths = paths[platform] || [];

  for (const path of platformPaths) {
    try {
      if (fs.existsSync(path)) {
        return path;
      }
    } catch (err) {
      continue;
    }
  }

  throw new Error("Could not find Chrome/Chromium installation");
}

export function launchChromeWithDebugging() {
  try {
    const chromePath = getChromePath();
    const args = [
      "--remote-debugging-port=9222",
      `--user-data-dir=${userDataDir}`,
      "--remote-allow-origins=*",
      "--incognito",
      // "--headless",
      // `--proxy-server=46.3.202.240:2120`,
      // `--proxy-server=http://jN8AqiMh:Pd9FEs6N@212.193.184.228:64616`,
    ];

    console.log(`Launching Chrome at: ${chromePath}`);

    const chromeProcess = spawn(chromePath, args, {
      detached: true,
      stdio: "ignore",
    });

    chromeProcess.unref();

    chromeProcess.on("error", (err) => {
      console.error("Failed to start Chrome:", err);
    });

    chromeProcess.on("exit", (code) => {
      if (code !== 0) {
        console.error(`Chrome process exited with code ${code}`);
      }
    });

    console.log("Chrome launched successfully with debugging port 9222");
    return chromeProcess;
  } catch (error) {
    console.error("Failed to launch Chrome:", error);
    process.exit(1);
  }
}

export async function waitForChromeReady(port = 9222, timeout = 30000) {
  const startTime = Date.now();

  return new Promise((resolve, reject) => {
    function check() {
      const client = net.createConnection({ port }, () => {
        client.end();
        resolve("");
      });

      client.on("error", () => {
        if (Date.now() - startTime > timeout) {
          reject(new Error("Timeout waiting for Chrome to start"));
        } else {
          setTimeout(check, 500);
        }
      });
    }

    check();
  });
}

export function randomDelay(min: number, max: number): Promise<void> {
  const delay = Math.floor(Math.random() * (max - min) + min);
  return new Promise((resolve) => setTimeout(resolve, delay));
}
