import { app, ipcMain } from "electron";
import log from "electron-log/main";
import { autoUpdater } from "electron-updater";
import path from "path";
import ipcTypes from "../../util/ipcTypes.json";
import ImportJob from "../decoder/decoder";
import store from "../store/store";
import { StartWatcher, StopWatcher } from "../watcher/watcher";
import {
  SettingsPpcFilPathGet,
  SettingsPpcFilPathSet,
  SettingsWatchedFilePathsAdd,
  SettingsWatchedFilePathsGet,
  SettingsWatchedFilePathsRemove,
  SettingsWatcherPollingGet,
  SettingsWatcherPollingSet,
  SettingEmsOutFilPathSet,
  SettingEmsOutFilPathGet,
} from "./ipcMainHandler.settings";
import {
  ipcMainHandleAuthStateChanged,
  ipMainHandleResetPassword,
} from "./ipcMainHandler.user";

// Log all IPC messages and their payloads
const logIpcMessages = (): void => {
  // Get all message types from ipcTypes.toMain
  Object.keys(ipcTypes.toMain).forEach((key) => {
    const messageType = ipcTypes.toMain[key];

    // Wrap the original handler with our logging
    const originalHandler = ipcMain.listeners(messageType)[0];
    if (originalHandler) {
      ipcMain.removeAllListeners(messageType);
    }
    ipcMain.on(messageType, (event, payload) => {
      log.info(
        `%c[IPC Main]%c${messageType}`,
        "color: red",
        "color: green",
        payload,
      );
      // Call original handler if it existed
      if (originalHandler) {
        originalHandler(event, payload);
      }
    });
  });
};

ipcMain.on(ipcTypes.toMain.test, () =>
  console.log("** Verify that ipcMain is loaded and working."),
);

//Auth handler
ipcMain.on(ipcTypes.toMain.authStateChanged, ipcMainHandleAuthStateChanged);
ipcMain.on(ipcTypes.toMain.user.resetPassword, ipMainHandleResetPassword);

//Add debug handlers if in development
if (import.meta.env.DEV) {
  log.debug("[IPC Debug Functions] Adding Debug Handlers");

  ipcMain.on(ipcTypes.toMain.debug.decodeEstimate, async (): Promise<void> => {
    const relativeEmsFilepath = `_reference/ems/MPI_1/3698420.ENV`;
    // Get the app's root directory and create an absolute path
    const rootDir = app.getAppPath();
    const absoluteFilepath = path.join(rootDir, relativeEmsFilepath);

    log.debug("[IPC Debug Function] Decode test Estimate", absoluteFilepath);
    await ImportJob(absoluteFilepath);

    const job2 = `/Users/pfic/Downloads/12285264/2285264.ENV`;
    const job3 = `/Users/pfic/Downloads/14033376/4033376.ENV`;
    await ImportJob(job2);
    await ImportJob(job3);
  });
}

//Settings Handlers
ipcMain.handle(
  ipcTypes.toMain.settings.filepaths.get,
  SettingsWatchedFilePathsGet,
);
ipcMain.handle(
  ipcTypes.toMain.settings.filepaths.add,
  SettingsWatchedFilePathsAdd,
);
ipcMain.handle(
  ipcTypes.toMain.settings.filepaths.remove,
  SettingsWatchedFilePathsRemove,
);
ipcMain.handle(
  ipcTypes.toMain.settings.watcher.getpolling,
  SettingsWatcherPollingGet,
);
ipcMain.handle(
  ipcTypes.toMain.settings.watcher.setpolling,
  SettingsWatcherPollingSet,
);

ipcMain.handle(ipcTypes.toMain.settings.getPpcFilePath, SettingsPpcFilPathGet);
ipcMain.handle(ipcTypes.toMain.settings.setPpcFilePath, SettingsPpcFilPathSet);
ipcMain.handle(
  ipcTypes.toMain.settings.getEmsOutFilePath,
  SettingEmsOutFilPathGet,
);
ipcMain.handle(
  ipcTypes.toMain.settings.setEmsOutFilePath,
  SettingEmsOutFilPathSet,
);

ipcMain.handle(ipcTypes.toMain.user.getActiveShop, () => {
  return store.get("app.bodyshop.shopname");
});

//Watcher Handlers
ipcMain.on(ipcTypes.toMain.watcher.start, () => {
  StartWatcher();
});

ipcMain.on(ipcTypes.toMain.watcher.stop, () => {
  StopWatcher();
});

ipcMain.on(ipcTypes.toMain.updates.download, () => {
  log.info("Download update requested from renderer.");
  autoUpdater.downloadUpdate();
});

ipcMain.on(ipcTypes.toMain.updates.checkForUpdates, () => {
  log.info("Checking for updates from renderer.");
  autoUpdater.checkForUpdates();
});

logIpcMessages();
