// Basic init
const electron = require("electron");
const { ScanList } = require("ethernet-ip-scanlist");
const _ = require("lodash");
const { app, BrowserWindow, ipcMain } = electron;

const sqlite3 = require("sqlite3").verbose();
const db = new sqlite3.Database("./MaxWaterSystem.db");

const tagConfig = require("./tagList.json");

// To avoid being garbage collected
let mainWindow;
let scanList;

app.on("ready", () => {

	mainWindow = new BrowserWindow({
		width: 1000,
		height: 1000
	});
	mainWindow.loadURL(`file://${__dirname}/app/index.html`);

	// Wait for allowing react app to fully load 
	// before starting to send initalized data.
	setTimeout(() => {
		setupDB();
		initPLC("10.20.4.36", tagConfig.scan_list);
	}, 2000);
	

});

function setupDB(){
	db.run("CREATE TABLE IF NOT EXISTS tag_history (id INTEGER PRIMARY KEY, tag TEXT, value TEXT, reason TEXT, timestamp TEXT)");
}

function clearAllHistory(){
	db.run("DELETE FROM tag_history WHERE id > 0");
}

function clearTagHistory(tagName){
	db.run(`DELETE FROM tag_history WHERE tagName = "${tagName}"`);
}

function sendTagHistoryToDB(tag){
	var stmt = db.prepare("INSERT INTO tag_history (tag, value, reason, timestamp) VALUES (?, ?, ?, ?)");
	stmt.run(tag.tagName, tag.value, tag.lastSendReason, tag.lastSendTime.format());
	stmt.finalize();
}

function getTagHistory(tagName){
	return new Promise((resolve, reject) => {
		db.all(`SELECT value, reason, timestamp FROM tag_history WHERE tag = "${tagName}" ORDER BY datetime(timestamp) DESC`, function(err, rows) {
			if (err) reject(err);
			resolve(rows);
		});
	});
}


function writeTag(tagName, tagValue){
	scanList.tags[tagName].enipTag.value = tagValue;
}

function initPLC(ipAddress, tagList){
	scanList = new ScanList(ipAddress);

	const setupTags = new Promise( (resolve) => {
		resolve(_.forEach(tagList, ({tag, vanityName, storePeriod, storeChangeDelta}) => {
			scanList.add(tag, vanityName, storePeriod, storeChangeDelta);
			if(tagConfig.history_tags.includes(tag)){
				getTagHistory(tag).then((historyRows) => {
					// console.log("tag:history", {tag, historyRows});
					mainWindow.webContents.send("tag:history", {tagName: tag, historyRows});
				}, (err) => {
					console.log("getHistoryTag Error:", err);
				});
			}
		}));
	});

	setupTags.then(() => {
		scanList.on("Updated", (tag) => {
			mainWindow.webContents.send("tag:valueupdate", tag);
		});

		scanList.on("newValue", (tag) => {
			sendTagHistoryToDB(tag);
		});

		scanList.start();
		const properties = { ...scanList.PLC.properties, ipAddress};
		mainWindow.webContents.send("plc:connected", properties);
	});

}


ipcMain.on("plc:initialize", (event, ipAddress, tagList) =>{
	initPLC(ipAddress, tagList);
});

ipcMain.on("tag:write", (event, tagName, value) => {
	writeTag(tagName, value);
});

ipcMain.on("tag:new", (event, {tagName, vanityName, storePeriod, storeChangeDelta}) => {
	scanList.add(tagName, vanityName, storePeriod, storeChangeDelta);
	scanList.stop();
	scanList.start();
});

ipcMain.on("tag:clearHistory", (event, tagName) => {
	clearTagHistory(tagName);
});

ipcMain.on("tag:clearAllHistory", () => {
	clearAllHistory();
});
