import { BrowserWindow, shell, ipcMain, nativeTheme, screen, powerMonitor, app } from 'electron'
import { join } from 'path'
import fs from 'fs'
import { WORKING_DIR } from './constants';
import { boot } from './boot/bootloader';

export async function startApplication() {
	let preloaderWindow = createPreloaderWindow();
	await fs.promises.mkdir(WORKING_DIR, { recursive: true });
	createAppWindow(preloaderWindow);
}

export function createPreloaderWindow() {
	let preloaderWindow = new BrowserWindow({
		width: 150,
		height: 150,
		frame: false,
		transparent: true,
		center: true,
		resizable: false,
		alwaysOnTop: true
	});

	preloaderWindow.loadFile(join(__dirname, '../../resources/preload.html'));

	return preloaderWindow;
}

export function createAppWindow(preloaderWindow?: BrowserWindow): void {
	const mainWindow = new BrowserWindow({
		width: 385,
		height: 555,
		minWidth: 385,
		minHeight: 555,
		show: false,
		title: 'Rosetta Messager',
		icon: join(__dirname, '../../resources/R.png'),
		frame: false,
		autoHideMenuBar: true,
		backgroundColor: '#000',
		webPreferences: {
			preload: join(__dirname, '../preload/preload.js'),
			sandbox: false,
			nodeIntegration: true,
			nodeIntegrationInSubFrames: true,
			nodeIntegrationInWorker: true,
			webSecurity: false,
			allowRunningInsecureContent: true,
			autoplayPolicy: 'no-user-gesture-required'
		}
	});

	powerMonitor.on('lock-screen', () => {
		if (mainWindow && !mainWindow.isDestroyed()) {
			mainWindow.reload();
		}
	});

	foundationIpcRegistration(mainWindow);

	mainWindow.webContents.on('did-finish-load', () => {
		if (preloaderWindow && !preloaderWindow.isDestroyed()) {
			preloaderWindow.close();
		}
		mainWindow.show();
	});

	mainWindow.webContents.setWindowOpenHandler((details) => {
		shell.openExternal(details.url)
		return { action: 'deny' }
	});

	boot(mainWindow);
}

export function foundationIpcRegistration(mainWindow: BrowserWindow) {
	let bounceId: number | null = null;
	ipcMain.removeAllListeners('window-resize');
	ipcMain.removeAllListeners('window-resizeble');
	ipcMain.removeAllListeners('window-theme');
	ipcMain.removeAllListeners("write-file");
	ipcMain.removeAllListeners("read-file");
	ipcMain.removeAllListeners("mkdir");
	ipcMain.removeHandler('open-dev-tools');
	ipcMain.removeHandler('window-state');
	ipcMain.removeHandler('window-toggle');
	ipcMain.removeHandler('window-close');
	ipcMain.removeHandler('window-minimize');
	ipcMain.removeHandler('showItemInFolder');
	ipcMain.removeHandler('openExternal');
	ipcMain.removeHandler('window-top');
	ipcMain.removeHandler('window-priority-normal');

	ipcMain.handle('window-top', () => {
		if (mainWindow.isMinimized()) {
			mainWindow.restore();
		}
		mainWindow.setAlwaysOnTop(true, "screen-saver"); // самый высокий уровень
		mainWindow.setVisibleOnAllWorkspaces(true, { visibleOnFullScreen: true });

		mainWindow.show();
		mainWindow.focus();

		if (process.platform === "darwin") {
			/**
			 * Только в macos! Подпрыгивание иконки в Dock
			 */
			bounceId = app.dock!.bounce("critical");
		}
	})

	ipcMain.handle('window-priority-normal', () => {
		mainWindow.setAlwaysOnTop(false);
		mainWindow.setVisibleOnAllWorkspaces(false);
		if (process.platform === "darwin" && bounceId !== null) {
			/**
			 * Только в macos! Отмена подпрыгивания иконки в Dock
			 */
			app.dock!.cancelBounce(bounceId);
			bounceId = null;
		}
	})

	ipcMain.handle('open-dev-tools', () => {
		if (mainWindow.webContents.isDevToolsOpened()) {
			return;
		}
		mainWindow.webContents.openDevTools({ mode: 'detach' });
	});

	ipcMain.on('window-resize', (_, { width, height }) => {
		const { x: currentX, y: currentY } = mainWindow.getBounds();

		const display = screen.getDisplayMatching(mainWindow.getBounds());
		const displayBounds = display.workArea;

		let newX = currentX;
		let newY = currentY;

		if (currentX + width > displayBounds.x + displayBounds.width) {
			newX = displayBounds.x + displayBounds.width - width;
		}

		if (currentY + height > displayBounds.y + displayBounds.height) {
			newY = displayBounds.y + displayBounds.height - height;
		}

		mainWindow.setBounds({
			x: newX,
			y: newY,
			width: width,
			height: height
		});
		mainWindow.webContents.send('window-state-changed');
	});

	ipcMain.on('window-resizeble', (_, isResizeble) => {
		mainWindow.setResizable(isResizeble);
		mainWindow.webContents.send('window-state-changed');
	});

	ipcMain.on('window-theme', (_, theme) => {
		nativeTheme.themeSource = theme;
	})

	ipcMain.on("write-file", (_, filePath, content) => {
		fs.writeFile(filePath, content, (err) => {
			if (err) {
				console.error(err);
				return;
			}
		});
	});
	ipcMain.handle('window-state', () => {
		return {
			isMinimized: mainWindow.isMinimized(),
			isMaximized: mainWindow.isMaximized(),
			isFullScreen: mainWindow.isFullScreen(),
			isVisible: mainWindow.isVisible(),
			isFocused: mainWindow.isFocused(),
			isResizable: mainWindow.isResizable(),
			isClosable: mainWindow.isClosable(),
			isDestroyed: mainWindow.isDestroyed(),
			bounds: mainWindow.getBounds()
		};
	});

	ipcMain.handle('window-toggle', () => {
		if (mainWindow.isMaximized() || mainWindow.isFullScreen()) {
			mainWindow.setFullScreen(false);
			mainWindow.unmaximize();
		} else {
			mainWindow.setFullScreen(true);
		}
		setTimeout(() => {
			/**
			 * Разобраться с этой хуйней
			 */
			mainWindow.webContents.send('window-state-changed');
		}, 700);
	});

	ipcMain.handle('window-minimize', () => {
		mainWindow.minimize();
		mainWindow.webContents.send('window-state-changed');
	});

	ipcMain.handle('window-close', () => {
		mainWindow.hide();
		mainWindow.webContents.send('window-state-changed');
	});

	ipcMain.on("read-file", (_, filePath) => {
		fs.readFile(filePath, 'utf8', (err, data) => {
			if (err) {
				console.error(err);
				return;
			}
			mainWindow.webContents.send("read-file-reply", data);
		});
	});

	ipcMain.on("mkdir", (_, dirPath) => {
		fs.mkdir(dirPath, { recursive: true }, (err) => {
			if (err) {
				console.error(err);
				return;
			}
			mainWindow.webContents.send("mkdir-reply");
		});
	});
}
