import "dotenv/config";
import { electronApp, optimizer, is } from "@electron-toolkit/utils";
import { app, ipcMain, BrowserWindow, shell } from "electron";
import filesystemPlugin from "@takerofnotes/plugin-filesystem";
import supabasePlugin from "@takerofnotes/plugin-supabase";
import fs from "fs/promises";
import path, { join } from "path";
import __cjs_mod__ from "node:module";
const __filename = import.meta.filename;
const __dirname = import.meta.dirname;
const require2 = __cjs_mod__.createRequire(import.meta.url);
class PluginRegistry {
  constructor() {
    this.plugins = /* @__PURE__ */ new Map();
  }
  register(plugin) {
    if (!plugin.id) {
      throw new Error("Plugin must have an id");
    }
    this.plugins.set(plugin.id, plugin);
  }
  get(id) {
    return this.plugins.get(id);
  }
  list() {
    return Array.from(this.plugins.values()).map((plugin) => ({
      id: plugin.id,
      name: plugin.name,
      description: plugin.description,
      configSchema: plugin.configSchema
    }));
  }
}
const USER_DATA_STRING = "__DEFAULT_USER_DATA__";
class Config {
  constructor(defaultPlugin) {
    this.defaultPlugin = defaultPlugin;
    this.configPath = path.join(app.getPath("userData"), "config.json");
  }
  // Helper to replace placeholders with dynamic values
  _resolveDefaults(config) {
    if (Array.isArray(config)) {
      return config.map((item) => this._resolveDefaults(item));
    } else if (config && typeof config === "object") {
      const resolved = {};
      for (const [key, value] of Object.entries(config)) {
        resolved[key] = this._resolveDefaults(value);
      }
      return resolved;
    } else if (typeof config === "string" && config.includes(USER_DATA_STRING)) {
      return config.replace(USER_DATA_STRING, app.getPath("userData"));
    } else {
      return config;
    }
  }
  async load() {
    let parsed;
    try {
      const raw = await fs.readFile(this.configPath, "utf8");
      parsed = JSON.parse(raw);
    } catch (err) {
      parsed = null;
    }
    if (!parsed || !parsed.activeAdapter) {
      const defaultConfig = {};
      for (const field of this.defaultPlugin.configSchema) {
        defaultConfig[field.key] = field.default ?? null;
      }
      parsed = {
        ...parsed ? parsed : {},
        activeAdapter: this.defaultPlugin.id
      };
      parsed.adapters[this.defaultPlugin.id] = defaultConfig;
      await this.write(parsed);
    } else {
      parsed.adapterConfig = this._resolveDefaults(parsed.adapterConfig);
    }
    return parsed;
  }
  async write(configObject) {
    const dir = path.dirname(this.configPath);
    await fs.mkdir(dir, { recursive: true });
    const resolvedConfig = {
      ...configObject,
      adapterConfig: this._resolveDefaults(configObject.adapterConfig)
    };
    await fs.writeFile(
      this.configPath,
      JSON.stringify(resolvedConfig, null, 2),
      "utf8"
    );
  }
}
const preloadPath = join(__dirname, "../preload/index.mjs");
const rendererPath = join(__dirname, "../renderer/index.html");
function createWindow() {
  const mainWindow = new BrowserWindow({
    width: 354,
    height: 549,
    show: false,
    autoHideMenuBar: true,
    webPreferences: {
      preload: preloadPath,
      sandbox: false
    }
  });
  mainWindow.on("ready-to-show", () => {
    mainWindow.show();
  });
  mainWindow.webContents.setWindowOpenHandler((details) => {
    shell.openExternal(details.url);
    return { action: "deny" };
  });
  if (is.dev && process.env["ELECTRON_RENDERER_URL"]) {
    mainWindow.loadURL(process.env["ELECTRON_RENDERER_URL"]);
  } else {
    mainWindow.loadFile(rendererPath);
  }
}
function createNoteWindow(noteId) {
  const noteWindow = new BrowserWindow({
    width: 354,
    height: 549,
    autoHideMenuBar: true,
    webPreferences: {
      preload: preloadPath,
      contextIsolation: true,
      nodeIntegration: false,
      sandbox: false
    }
  });
  if (is.dev && process.env["ELECTRON_RENDERER_URL"]) {
    noteWindow.loadURL(
      `${process.env["ELECTRON_RENDERER_URL"]}/#/note/${noteId}`
    );
  } else {
    noteWindow.loadFile(rendererPath, {
      hash: `/note/${noteId}`
    });
  }
}
app.whenReady().then(async () => {
  ipcMain.on("open-note-window", (_, noteId) => {
    createNoteWindow(noteId);
  });
  const broadcastNoteChange = (event, data) => {
    BrowserWindow.getAllWindows().forEach((win) => {
      win.webContents.send(event, data);
    });
  };
  const registry = new PluginRegistry();
  registry.register(filesystemPlugin);
  registry.register(supabasePlugin);
  const config = new Config(filesystemPlugin);
  const initialConfig = await config.load();
  const setActivePlugin = async (pluginId) => {
    const currentConfig = await config.load();
    await config.write({ ...currentConfig, activeAdapter: pluginId });
    const plugin = registry.get(pluginId);
    const adapterConfig = currentConfig.adapters[pluginId] || {};
    const adapter = plugin.createAdapter(adapterConfig);
    await adapter.init();
    ipcMain.removeHandler("adapter:call");
    ipcMain.handle("adapter:call", async (_, method, args) => {
      if (!adapter[method]) {
        throw new Error(`Invalid adapter method: ${method}`);
      }
      return await adapter[method](...args);
    });
    broadcastNoteChange("plugin-changed", pluginId);
    return true;
  };
  await setActivePlugin(initialConfig.activeAdapter);
  ipcMain.handle("getConfig", async () => {
    return await config.load();
  });
  ipcMain.handle("setConfig", async (_, newConfig) => {
    await config.write(newConfig);
  });
  ipcMain.handle("listPlugins", async () => {
    return registry.list();
  });
  ipcMain.handle("setActivePlugin", async (_, pluginId) => {
    return await setActivePlugin(pluginId);
  });
  ipcMain.on("note-changed", (_, event, data) => {
    broadcastNoteChange(event, data);
  });
  electronApp.setAppUserModelId("com.electron");
  app.on("browser-window-created", (_, window) => {
    optimizer.watchWindowShortcuts(window);
  });
  createWindow();
  app.on("activate", function() {
    if (BrowserWindow.getAllWindows().length === 0) createWindow();
  });
});
app.on("window-all-closed", () => {
  if (process.platform !== "darwin") {
    app.quit();
  }
});
