import { fileURLToPath } from "node:url";
import path from "node:path";
import { loadConfig } from "./config.js";
import log4js from "log4js";
import { LocalServer } from "./localserver/localserver.js";
import { SocketClient } from "./socket/socketclient.js";
import {
  createCliLogger,
  isHeadless,
  startWaiting,
  stopWaiting,
} from "./commandlineutils.js";
import { handleCommandLine } from "./commandline.js";

if (!process.env.NODE_ENV) {
  process.env.NODE_ENV = "production";
}

const config = loadConfig();

const logger = log4js.getLogger("App");
logger.level = config.logLevel;

const cli = createCliLogger(logger);

let initPromise = null;

export async function init(options = {}) {
  if (initPromise) {
    return initPromise;
  }

  initPromise = startApp(options);
  return initPromise;
}

async function startApp(options = {}) {
  const headless = options.headless ?? isHeadless;
  cli.blank();

  const commandLineResult = await handleCommandLine(cli, logger);
  if (commandLineResult.handled) {
    return commandLineResult.result;
  }

  const runningServer = commandLineResult.runningServer;

  if (runningServer != false) {
    cli.warn("✘ Farm Control Server is already running.");
    cli.blank();
    return runningServer;
  }

  if (!headless && !options.skipWindow) {
    const { createDesktopWindow } = await import("./desktop/window.js");
    const { setupIPC } = await import("./desktop/rpc.js");

    startWaiting("Creating desktop window...", logger);
    try {
      const mainWindow = await createDesktopWindow().catch((err) => {
        cli.warn("Failed to create desktop window:", err);
        return null;
      });
      if (mainWindow) {
        await setupIPC(mainWindow);
      }
      await stopWaiting();
    } catch (err) {
      await stopWaiting();
      throw err;
    }
  } else if (headless) {
    cli.info("Running in headless mode. Skipping window creation.");
  }

  const socketClient = new SocketClient();
  global.socketClient = socketClient;

  const localServer = new LocalServer(socketClient);
  await localServer.start();

  socketClient.connect();

  process.on("SIGINT", async () => {
    startWaiting("Shutting down...", logger);
    cli.blank();
    socketClient.disconnect();
    localServer.stop();
    await stopWaiting();
    process.exit(0);
  });
}

const entryScript = process.argv[1]
  ? path.resolve(process.argv[1])
  : null;
const isDirectIndexEntry =
  entryScript &&
  entryScript.endsWith(`${path.sep}src${path.sep}index.js`) &&
  fileURLToPath(import.meta.url) === entryScript;

if (isDirectIndexEntry && !process.env.FC_HEADLESS_ENTRY) {
  init().catch((err) => {
    logger.error(err.message);
    cli.blank();
    process.exit(1);
  });
}
