const chokidar = require("chokidar");
const ipcTypes = require("../../src/ipc.types");
const path = require("path");
const { DecodeEstimate } = require("../decoder/decoder");
const { BrowserWindow } = require("electron");
const _ = require("lodash");
const { store } = require("../electron-store");
const {
  NewNotification,
} = require("../notification-wrapper/notification-wrapper");

var watcher;

async function StartWatcher() {
  const filePaths =
    store.get("filePaths").map((fp) => path.join(fp, "**.[eE][nN][vV]")) || [];
  console.log("StartWatcher -> filePaths", filePaths);

  if (filePaths.length === 0) {
    NewNotification({
      title: "RPS Watcher cannot start",
      body: "Please set the appropriate file paths and try again.",
    }).show();
    return [];
  }

  if (watcher) {
    try {
      console.log("Trying to close watcher - it already existed.111");
      await watcher.close();

      console.log("Watcher closed successfully!");
    } catch (error) {
      console.log("Error trying to close Watcher.", error);
    }
  }

  watcher = chokidar.watch(filePaths, {
    //ignored: /[\/\\]\./,
    persistent: true,
    ignoreInitial: true,
    awaitWriteFinish: {
      pollInterval: 100,
      stabilityThreshold: 2000,
    },
  });

  watcher
    .on("add", async function (path) {
      console.log("File", path, "has been added");
      HandleNewFile(path);
    })
    .on("addDir", function (path) {
      console.log("Directory", path, "has been added");
    })
    .on("change", async function (path) {
      console.log("File", path, "has been changed");
      HandleNewFile(path);
    })
    .on("unlink", function (path) {
      console.log("File", path, "has been removed");
    })
    .on("unlinkDir", function (path) {
      console.log("Directory", path, "has been removed");
    })
    .on("error", function (error) {
      console.log("Error happened", error);
      const b = BrowserWindow.getFocusedWindow();
      b.webContents.send(ipcTypes.fileWatcher.toRenderer.error, error);
    })
    .on("ready", onWatcherReady)
    .on("raw", function (event, path, details) {
      // This event should be triggered everytime something happens.
      // console.log("Raw event info:", event, path, details);
    });

  return filePaths;
}

function onWatcherReady() {
  console.log("Ready!");
  const b = BrowserWindow.getAllWindows()[0];
  b.webContents.send(ipcTypes.default.fileWatcher.toRenderer.startSuccess);
  NewNotification({
    title: "RPS Watcher Started",
    body: "Newly exported estimates will be automatically uploaded.",
  }).show();
}

async function StopWatcher() {
  await watcher.close();
  console.log("Watcher stopped.");
  const b = BrowserWindow.getAllWindows()[0];
  b.webContents.send(ipcTypes.default.fileWatcher.toRenderer.stopSuccess);
  NewNotification({
    title: "RPS Watcher Stopped",
    body: "Estimates will not be automatically uploaded.",
  }).show();
}

exports.StartWatcher = StartWatcher;
exports.StopWatcher = StopWatcher;
exports.watcher = watcher;

async function HandleNewFile(path) {
  const b = BrowserWindow.getAllWindows()[0];
  b.webContents.send(ipcTypes.default.estimate.toRenderer.estimateDecodeStart);
  const newJob = await DecodeEstimate(path);
  const newJobLow = _.transform(newJob, function (result, val, key) {
    result[key.toLowerCase()] = val;
  });

  if (newJobLow && newJob) {
    b.webContents.send(
      ipcTypes.default.estimate.toRenderer.estimateDecodeSuccess,
      newJobLow
    );

    NewNotification({
      title: "Job Uploaded",
      body: "A new job has been uploaded.",
    }).show();
  } else {
    NewNotification({
      title: "Job Ignored",
      body:
        "The job was not uploaded because it does not meet RPS requirements.",
    }).show();
  }
}
