const { execFile } = require("child_process");

const WIN_SERVICE_NAME = "SirayaPrinterService";
const LINUX_SERVICE_NAME = "siraya-printer";

function execFileAsync(cmd, args, opts = {}) {
  return new Promise((resolve, reject) => {
    execFile(cmd, args, opts, (err, stdout, stderr) => {
      if (err) {
        reject(new Error(stderr?.toString() || err.message || String(err)));
      } else {
        resolve(stdout?.toString() || "");
      }
    });
  });
}

function execPs(script, opts = {}) {
  return execFileAsync(
    "powershell.exe",
    ["-NoProfile", "-ExecutionPolicy", "Bypass", "-Command", script],
    { windowsHide: true, ...opts },
  );
}

async function execElevatedNet(subcommand, serviceName) {
  const safeSub = String(subcommand).replace(/'/g, "''");
  const safeName = String(serviceName).replace(/'/g, "''");
  const ps = `
$p = Start-Process net -ArgumentList '${safeSub}','${safeName}' -Verb RunAs -Wait -PassThru
if ($null -eq $p) { exit 1 }
exit $p.ExitCode
`;
  await execPs(ps);
}

async function execSystemctl(args, { elevated = false } = {}) {
  const cmd = elevated ? "pkexec" : "systemctl";
  const fullArgs = elevated ? ["systemctl", ...args] : args;
  return execFileAsync(cmd, fullArgs, { env: process.env });
}

async function getServiceStatus() {
  if (process.platform === "linux") {
    try {
      const out = await execSystemctl(["is-active", LINUX_SERVICE_NAME]);
      const state = out.trim();
      const running = state === "active";
      return { installed: true, running, state: running ? "running" : state };
    } catch {
      try {
        await execSystemctl(["cat", LINUX_SERVICE_NAME]);
        return { installed: true, running: false, state: "stopped" };
      } catch {
        return { installed: false, running: false, state: "not_installed" };
      }
    }
  }

  if (process.platform !== "win32") {
    return { installed: false, running: false, state: "unsupported" };
  }

  try {
    const out = await execFileAsync("sc", ["query", WIN_SERVICE_NAME], {
      windowsHide: true,
    });
    const running = /STATE\s*:\s*\d+\s+RUNNING/i.test(out);
    return { installed: true, running, state: running ? "running" : "stopped" };
  } catch {
    return { installed: false, running: false, state: "not_installed" };
  }
}

async function startService() {
  if (process.platform === "linux") {
    await execSystemctl(["start", LINUX_SERVICE_NAME], { elevated: true });
    return getServiceStatus();
  }
  await execElevatedNet("start", WIN_SERVICE_NAME);
  return getServiceStatus();
}

async function stopService() {
  if (process.platform === "linux") {
    await execSystemctl(["stop", LINUX_SERVICE_NAME], { elevated: true });
    return getServiceStatus();
  }
  await execElevatedNet("stop", WIN_SERVICE_NAME);
  return getServiceStatus();
}

async function restartService() {
  if (process.platform === "linux") {
    try {
      await execSystemctl(["stop", LINUX_SERVICE_NAME], { elevated: true });
    } catch {
      /* may already be stopped */
    }
    await execSystemctl(["start", LINUX_SERVICE_NAME], { elevated: true });
    return getServiceStatus();
  }
  try {
    await execElevatedNet("stop", WIN_SERVICE_NAME);
  } catch {
    /* ignore */
  }
  await execElevatedNet("start", WIN_SERVICE_NAME);
  return getServiceStatus();
}

module.exports = {
  getServiceStatus,
  startService,
  stopService,
  restartService,
  LINUX_SERVICE_NAME,
  WIN_SERVICE_NAME,
};
