/* eslint-disable @typescript-eslint/no-require-imports, no-eval */
import {
  type BotName,
  getBotDir,
  getBotPidFile,
  getBotLogDir,
  getBotLogFile,
} from "./paths";

// Importação dinâmica para evitar o Turbopack tentar resolver módulos Node.js
const childProcess = eval('require("child_process")') as typeof import("child_process");
const fs = eval('require("fs")') as typeof import("fs");
const path = eval('require("path")') as typeof import("path");

export interface ProcessInfo {
  pid: number;
  running: boolean;
  uptime: string | null;
  memory: string | null;
}

export function getPid(botName: BotName): number | null {
  const pidFile = getBotPidFile(botName);
  try {
    const content = fs.readFileSync(pidFile, "utf-8").trim();
    const pid = parseInt(content, 10);
    return isNaN(pid) ? null : pid;
  } catch {
    return null;
  }
}

export function isPidRunning(pid: number): boolean {
  try {
    process.kill(pid, 0);
    return true;
  } catch {
    return false;
  }
}

export function getProcessInfo(botName: BotName): ProcessInfo {
  const pid = getPid(botName);

  if (pid === null || !isPidRunning(pid)) {
    if (pid !== null) {
      try { fs.unlinkSync(getBotPidFile(botName)); } catch { /* ignore */ }
    }
    return { pid: 0, running: false, uptime: null, memory: null };
  }

  let uptime: string | null = null;
  let memory: string | null = null;

  try {
    const psOutput = childProcess.execSync(`ps -p ${pid} -o etime=,rss= 2>/dev/null`, {
      encoding: "utf-8",
    }).trim();

    if (psOutput) {
      const parts = psOutput.trim().split(/\s+/);
      if (parts.length >= 2) {
        uptime = parts[0];
        const rssKb = parseInt(parts[1], 10);
        if (!isNaN(rssKb)) {
          memory = `${(rssKb / 1024).toFixed(1)} MB`;
        }
      }
    }
  } catch { /* ignore */ }

  return { pid, running: true, uptime, memory };
}

export function startBot(botName: BotName): { success: boolean; pid?: number; message: string } {
  const botDir = getBotDir(botName);
  const indexPath = path.join(botDir, "index.js");

  if (!fs.existsSync(indexPath)) {
    return { success: false, message: `Arquivo de entrada não encontrado: ${indexPath}` };
  }

  const info = getProcessInfo(botName);
  if (info.running) {
    return { success: false, pid: info.pid, message: `Bot ${botName} já está rodando (PID ${info.pid})` };
  }

  const logDir = getBotLogDir(botName);
  if (!fs.existsSync(logDir)) {
    fs.mkdirSync(logDir, { recursive: true });
  }

  const logFile = getBotLogFile(botName);
  const logFd = fs.openSync(logFile, "a");

  const child = childProcess.spawn("node", ["index.js"], {
    cwd: botDir,
    detached: true,
    stdio: ["ignore", logFd, logFd],
    env: { ...process.env, NODE_ENV: "production" },
  });

  const pid = child.pid;

  if (!pid) {
    fs.closeSync(logFd);
    return { success: false, message: `Falha ao iniciar bot ${botName}` };
  }

  fs.writeFileSync(getBotPidFile(botName), String(pid), "utf-8");
  child.unref();
  fs.closeSync(logFd);

  return { success: true, pid, message: `Bot ${botName} iniciado com PID ${pid}` };
}

export function stopBot(botName: BotName): { success: boolean; message: string } {
  const pid = getPid(botName);

  if (pid === null) {
    return { success: false, message: `Nenhum PID encontrado para ${botName}. Bot pode não estar rodando.` };
  }

  if (!isPidRunning(pid)) {
    try { fs.unlinkSync(getBotPidFile(botName)); } catch { /* ignore */ }
    return { success: true, message: `Bot ${botName} não estava rodando (PID ${pid} removido).` };
  }

  try {
    try { process.kill(-pid, "SIGTERM"); } catch { process.kill(pid, "SIGTERM"); }

    setTimeout(() => {
      try { if (isPidRunning(pid)) process.kill(pid, "SIGKILL"); } catch { /* ignore */ }
    }, 5000);

    try { fs.unlinkSync(getBotPidFile(botName)); } catch { /* ignore */ }

    return { success: true, message: `Bot ${botName} (PID ${pid}) foi parado.` };
  } catch (error) {
    return { success: false, message: `Falha ao parar ${botName}: ${error instanceof Error ? error.message : String(error)}` };
  }
}

export function restartBot(botName: BotName): { success: boolean; pid?: number; message: string } {
  const stopResult = stopBot(botName);
  const startResult = startBot(botName);

  if (!startResult.success) {
    return { success: false, message: `Parar: ${stopResult.message} | Iniciar falhou: ${startResult.message}` };
  }

  return { success: true, pid: startResult.pid, message: `Bot ${botName} reiniciado. ${stopResult.message} -> ${startResult.message}` };
}
