const {
  app,
  shell,
  BrowserWindow,
  dialog,
  ipcMain,
  nativeTheme,
} = require("electron");

const Logger = require("electron-log");
const path = require("path");
const {
  confirmMove,
  conflictHandler,
  movingFailed,
} = require("./desktop/move-to-applications");
const MenuBuilder = require("./desktop/menu");
const { appUpdaterInstance } = require("./desktop/app-updater");

if (process.env.NODE_ENV === "development") {
  require(path.join(__dirname, "./server/index.js"));
} else {
  process.env.NODE_ENV = "production";
  require(path.join(__dirname, "./dist/server.js"));
}

let mainWindow = null,
  mainLinkUrl;
app.commandLine.appendSwitch("disable-gpu");

appUpdaterInstance.checkForUpdatesAndNotify();
Logger.catchErrors({
  showDialog: false,
  onError(error, versions, submitIssue) {
    dialog
      .showMessageBox({
        title: "An error occurred",
        message: error.message,
        detail: error.stack,
        type: "error",
        buttons: ["Ignore", "Report", "Exit"],
      })
      .then((result) => {
        if (result.response === 1) {
          submitIssue("https://github.com/mockswitch/support/issues/new", {
            title: `Error report for ${versions.app}`,
            body:
              "Error:\n```" + error.stack + "\n```\n" + `OS: ${versions.os}`,
          });
          return;
        }

        if (result.response === 2) {
          app.quit();
        }
      });
  },
});

function logEverywhere(s) {
  console.log(s);
  if (mainWindow && mainWindow.webContents) {
    mainWindow.webContents.executeJavaScript(`console.log("${s}")`);
  }
}

function processDeepLink(argv) {
  let deeplinkingUrl = argv.slice(1);
  if (deeplinkingUrl) {
    deeplinkingUrl = `${deeplinkingUrl}`;
    let actualUrl;
    const links = deeplinkingUrl.split(",");
    for (let index = 0; index < links.length; index += 1) {
      if (links[index].indexOf("auth_code") !== -1) {
        actualUrl = links[index];
        break;
      }
    }
    if (actualUrl) {
      logEverywhere(`deeplink argv url# ${actualUrl}`);
      const code = actualUrl.substring(
        actualUrl.indexOf("=") + 1,
        actualUrl.length
      );
      actualUrl = `http://localhost:${global.appPort}/auth/mockswitch/callback?auth_code=${code}`;
      logEverywhere(`deeplink ${actualUrl}`);
    }

    return actualUrl;
  }
}

async function createWindow() {
  mainWindow = new BrowserWindow({
    width: 1200,
    height: 800,
    autoHideMenuBar: true,
    useContentSize: true,
    resizable: true,
    frame: true,
    webPreferences: {
      devTools: !app.isPackaged,
      nativeWindowOpen: true,
      preload: path.join(__dirname, "preload.js"),
    },
  });
  logEverywhere(`process.platform ${process.platform}`);
  ipcMain.handle("dark-mode:toggle", () => {
    if (nativeTheme.shouldUseDarkColors) {
      nativeTheme.themeSource = "light";
    } else {
      nativeTheme.themeSource = "dark";
    }
    return nativeTheme.shouldUseDarkColors;
  });

  ipcMain.handle("dark-mode:dark", () => {
    nativeTheme.themeSource = "dark";
  });

  ipcMain.handle("dark-mode:light", () => {
    nativeTheme.themeSource = "light";
  });

  ipcMain.handle("dark-mode:system", () => {
    nativeTheme.themeSource = "system";
  });
  mainWindow.once("ready-to-show", () => {});

  const menuBuilder = new MenuBuilder(mainWindow);
  menuBuilder.buildMenu();

  mainWindow.on("close", () => {
    global.expressApp.emit("stop-server");
  });
  mainWindow.on("closed", () => {
    mainWindow = null;
  });
  function isSafeishURL(url) {
    return url.startsWith("http:") || url.startsWith("https:");
  }

  mainWindow.webContents.on("new-window", (event, url) => {
    event.preventDefault();
    if (isSafeishURL(url)) {
      shell.openExternal(url);
      if (url && url.indexOf("ssid") !== -1 && process.platform === "linux") {
        logEverywhere(`url ${url}`);
        app.quit();
      }
    }
  });
  if (process.platform === "linux") {
    const returnLink = processDeepLink(process.argv);
    if (returnLink && returnLink.indexOf("auth_code") !== -1) {
      mainLinkUrl = returnLink;
      logEverywhere(`mainLinkUrl ${mainLinkUrl}`);
    }
    logEverywhere(`returnLink ${returnLink}`);
  }

  global.expressApp.on("services-init", (port) => {
    logEverywhere(`${process.env.NODE_ENV} App Port`, port);
    mainWindow.loadURL(`http://localhost:${global.appPort}`);
    mainWindow.focus();
  });

  global.expressApp.on("main-init", (port) => {
    logEverywhere(`${process.env.NODE_ENV} App Port`, global.appPort, port);
    if (mainLinkUrl) {
      mainWindow.loadURL(mainLinkUrl);
    } else {
      mainWindow.loadURL(`http://localhost:${global.appPort}`);
    }
    mainWindow.focus();
  });
}

if (!app.isDefaultProtocolClient("mockswitch")) {
  app.setAsDefaultProtocolClient("mockswitch");
}

app.setAppLogsPath();

const gotTheLock = app.requestSingleInstanceLock();
if (gotTheLock) {
  app.on("second-instance", (e, argv) => {
    if (process.platform !== "darwin") {
      logEverywhere(`second-instance `);
      const parsedUrl = processDeepLink(argv);
      if (parsedUrl) {
        mainWindow.loadURL(parsedUrl);
        mainWindow.focus();
      }
    }
    if (mainWindow) {
      if (mainWindow.isMinimized()) {
        mainWindow.restore();
      }
      mainWindow.focus();
    }
  });
} else {
  app.quit();
  return;
}

app.on("will-finish-launching", () => {
  logEverywhere("will-finish-launching");
  app.on("open-url", (event, url) => {
    event.preventDefault();
    logEverywhere(`open-url# ${url}`);
    const code = url.substring(url.indexOf("=") + 1, url.length);
    logEverywhere(
      `code ${code} - http://localhost:${global.appPort}/auth/mockswitch/callback?auth_code=${code}`
    );
    mainWindow.loadURL(
      `http://localhost:${global.appPort}/auth/mockswitch/callback?auth_code=${code}`
    );
    mainWindow.focus();
  });
});

async function checkForMainWindow() {
  if (
    process.platform === "darwin" &&
    !app.isInApplicationsFolder() &&
    (await confirmMove(dialog))
  ) {
    try {
      app.moveToApplicationsFolder({
        conflictHandler: conflictHandler.bind(this, dialog),
      });
    } catch (e) {
      movingFailed(dialog);
    }
  }
  await createWindow();
}

app.on("ready", createWindow);

app.on("window-all-closed", () => {
  ipcMain.removeAllListeners();
  if (process.platform !== "darwin") {
    app.quit();
  }
});

app.on("activate", async () => {
  if (mainWindow === null) {
    await checkForMainWindow();
  }
});
