"use strict";
const {app, protocol, dialog, ipcMain, Menu} = require("electron");
const path                                   = require("path");
const fs                                     = require("fs/promises");
const fsn                                    = require("fs");

const AppInfo         = require("../package.json");
const WindowManager   = require("./WindowManager");
const FontManager     = require("./FontManager");
const SettingsManager = require("./SettingsManager");
const MainMenu        = require("./MainMenu");
const {parser}        = require("./Parser");

app.commandLine.appendSwitch("disable-http-cache");

class Ation {
	windowManager;
	fontManager;
	settingsManager;
	mainMenu;
	watcher;
	currentFile;

	constructor() {
		if (Ation.Instances > 0)
			throw new Error("Only one Instance of Ation possible");
		this.currentFile     = "";
		this.watcher         = null;
		this.windowManager   = new WindowManager(this);
		this.fontManager     = new FontManager();
		this.settingsManager = new SettingsManager(this);
		this.mainMenu        = new MainMenu(this);

		app.on("open-file", (_, path) => {
			this.fileToOpen = path;
		});

		ipcMain.handle("Ation::appVersion", () => AppInfo.version);
		ipcMain.on("Ation::closeFile", () => this.closeFile());

		app.whenReady().then(async () => {
			this.settingsManager.change();

			if (this.fileToOpen)
				this.openFile(this.fileToOpen);
			protocol.registerFileProtocol("slideimg", (request, callback) => {
				const uri       = request.url.replace(/^slideimg:\/\//, "");
				const extension = path.extname(uri).replace(/^\./, "");

				if (["png", "jpg", "jpeg", "svg", "bmp", "gif", "tiff"].includes(extension.toLowerCase()))
					callback(uri);
			});

		});
	}

	async openFile(filePath = null, change = false) {
			if (!this.windowManager.mainWindow)
				return null;

			if (!filePath) {
				const result = await dialog.showOpenDialog(this.windowManager.mainWindow, {
					title   : "open file",
					filters : [
						{
							name       : "Markdown files",
							extensions : [".md"]
						}
					]
				});

				if (result.canceled || result.filePaths.length < 1)
					return;
				filePath = result.filePaths[0];
			}

			try {
				const fileContents = await fs.readFile(filePath, {encoding : "utf-8"});
				const basePath     = path.dirname(filePath);
				const data         = parser(fileContents);

				if (!change) 
					this.currentFile = filePath;
				if (this.watcher)
					this.watcher.close();
				this.watcher = fsn.watch(filePath, (eventType, path) => {
					if (path.match(/~$/)) // handling unix swap files here
						setTimeout(() => this.openFile(this.currentFile, true), 1000);
					else
						this.openFile(this.currentFile, true);
				});
				Menu.getApplicationMenu().getMenuItemById("close-file").enabled = this.currentFile !== "";
				this.windowManager.mainWindow.send("Ation::openFile", [basePath, data]);
			} catch (error) {
				console.log(error);
				return;
			}
	}

	closeFile() {
		this.currentFile = "";
		if (this.watcher)
			this.watcher.close();
		this.watcher = null;
		this.windowManager.mainWindow.send("Ation::closeFile");
		Menu.getApplicationMenu().getMenuItemById("close-file").enabled = this.currentFile !== "";
	}
}
Ation.Instances = 0;

module.exports = Ation;