import {
  app,
  globalShortcut,
  BrowserWindow,
  Menu,
  Tray,
  webContents,
  shell,
  ipcMain,
} from "electron";
import config from "./config";
const Fuse = require("fuse.js");
const loudness = require("loudness");
import { autoUpdater } from "electron-updater";

const path = require("path");
const isDevelopment = !app.isPackaged;
const assetsDirectory = path.join(__dirname, "main-assets");
let pinnedSpotlight = false;
const openCommand = process.platform === "win32" ? "Alt+Space" : "Option+Space";
const closeCommand = "Esc";
let mainWindow: BrowserWindow | undefined;
let getMainWindow = (): BrowserWindow | undefined => mainWindow;
const gotTheLock = app.requestSingleInstanceLock();

console.log("[main/index.ts] electron version", app.getVersion());
const createTray = () => {
  tray = new Tray(path.join(assetsDirectory, "sunTemplate.png"));
  const contextMenu = Menu.buildFromTemplate([
    {
      label: "Open Spotlight",
      type: "normal",
      click: () => {
        showWindow();
      },
    },
    {
      label: "Open Devtool",
      type: "normal",
      click: () => {
        getMainWindow()?.webContents.openDevTools({
          mode: "detach",
        });
      },
    },
    {
      label: "Quit",
      type: "normal",
      click: () => {
        getMainWindow()?.close();
        getMainWindow()?.destroy();
        app.quit();
      },
    },
  ]);
  tray.setToolTip("set");
  tray.setContextMenu(contextMenu);
  tray.on("click", function (event) {});
};

function registerIpc() {
  ipcMain.on("open-url", (event, arg) => {
    console.log("event open url", arg);
    shell.openExternal(arg.url);
  });
  ipcMain.on("pin-spotlight", (event, arg) => {
    pinnedSpotlight = true;
  });
  ipcMain.on("unpin-spotlight", (event, arg) => {
    pinnedSpotlight = false;
  });
  ipcMain.on("unmute-volume", async (event, arg) => {
    console.log("unmute");
    await loudness.setMuted(false);
  });
  ipcMain.on("mute-volume", async (event, arg) => {
    await loudness.setMuted(true);
    console.log("mute");
  });
  ipcMain.on("search-request", (event, arg) => {
    let data = [] as any;
    if (data.length > config.output.max) {
      //max nr of items shown
      getMainWindow()?.setSize(
        config.mainWindow.width,
        config.mainWindow.height +
          config.output.heightPerItem * config.output.max
      );
    } else {
      //lower nr of items
      getMainWindow()?.setSize(
        config.mainWindow.width,
        config.mainWindow.height + config.output.heightPerItem * data.length
      );
    }
    event.sender.send("search-reply", data);
  });

  // to be used in the future if i want to reset other things
  ipcMain.on("reset", (event, arg) => {
    if (arg) {
      switch (arg) {
        case "size":
          getMainWindow().setSize(
            config.mainWindow.width,
            config.mainWindow.height
          );
          break;
      }
    }
  });
  ipcMain.on("app-version", (event) => {
    event.sender.send("app-version", { version: app.getVersion() });
  });
}

function createWindow() {
  // Create the browser window.
  mainWindow = new BrowserWindow(config.mainWindow);
  mainWindow.setBackgroundColor("#ffffff");

  const port = process.env.PORT || 3344;

  if (isDevelopment) {
    console.log("app", port);
    void getMainWindow()?.loadURL(`http://localhost:${port}`);
  } else {
    void getMainWindow()?.loadFile("./renderer/index.html");
    // and load the index.html of the app.
    // mainWindow.loadURL(url.format({
    //   pathname: path.join(process.cwd(), './src/index.html'),
    //   protocol: 'file:',
    //   slashes: true
    // }))
  }
  getMainWindow()?.webContents.focus();

  registerIpc();
  getMainWindow()?.on("closed", function () {
    mainWindow = undefined;
  });
  getMainWindow()?.on("show", () => {
    getMainWindow()?.webContents.executeJavaScript(
      `document.getElementById('oms-input')?.focus()`
    );
  });
  getMainWindow()?.on("ready-to-show", () => {
    autoUpdater.checkForUpdatesAndNotify();
  });
}

if (!gotTheLock) {
  console.log("!got the lock");
  app.quit();
} else {
  app.on("second-instance", (event, commandLine, workingDir) => {
    console.log("second-instance");
    if (mainWindow) {
      if (mainWindow.isMinimized()) mainWindow.restore();
      mainWindow.focus();
    }
  });

  // This method will be called when Electron has finished
  // initialization and is ready to create browser windows.
  // Some APIs can only be used after this event occurs.
  app.whenReady().then(() => {
    if (process.platform === "darwin") {
      app.dock.hide();
    }
    createTray();

    const ret = globalShortcut.register(openCommand, () => {
      showWindow();
    });

    if (!ret) {
      console.error("registration failed");
    }

    const rett = globalShortcut.register(closeCommand, () => {
      if (!pinnedSpotlight) {
        getMainWindow()?.hide();
      }
    });

    console.log(globalShortcut.isRegistered(openCommand));
  });
}
let tray: Tray | undefined;
function showWindow() {
  if (!mainWindow) {
    createWindow();
  }

  getMainWindow()?.show();
  getMainWindow()?.focus();
  getMainWindow()?.webContents.focus();
}

// Quit when all windows are closed.
app.on("window-all-closed", function () {
  console.log("window-all-closed");
  globalShortcut.unregister(openCommand);
  globalShortcut.unregisterAll();
  // On OS X it is common for applications and their menu bar
  // to stay active until the user quits explicitly with Cmd + Q
  if (process.platform !== "darwin") {
    app.quit();
  }
});

app.on("browser-window-blur", (event, win) => {
  console.log("electron window blur");
  if (!pinnedSpotlight) {
    getMainWindow()?.hide();
  }
  globalShortcut.unregister(closeCommand);
});

app.on("browser-window-focus", (event, win) => {
  const rett = globalShortcut.register(closeCommand, () => {
    if (!pinnedSpotlight) {
      getMainWindow()?.hide();
    }
  });

  console.log(globalShortcut.isRegistered(openCommand));
});

app.on("activate", function () {
  console.log("activate");
  // On OS X it's common to re-create a window in the app when the
  // dock icon is clicked and there are no other windows open.
  if (mainWindow === null) {
    showWindow();
  }
});

autoUpdater.on("update-available", () => {
  getMainWindow()?.webContents.send("update-available");
  console.log("update downloaded");
});
autoUpdater.on("update-downloaded", () => {
  console.log("update downloaded");
  getMainWindow()?.webContents.send("update-downloaded");
});
