import installExtension, { REACT_DEVELOPER_TOOLS } from 'electron-devtools-installer';
import { app, session, BrowserWindow, ipcMain } from 'electron';
import express from 'express';
import cors from 'cors';
import RPC from 'discord-rpc';
import { createProxyMiddleware } from 'http-proxy-middleware';

const PORT = 39511;
const statics: string[] = [];
let server: any;

// This allows TypeScript to pick up the magic constant that's auto-generated by Forge's Webpack
// plugin that tells the Electron app where to look for the Webpack-bundled app code (depending on
// whether you're running in development or production).
declare const MAIN_WINDOW_WEBPACK_ENTRY: string;

// Handle creating/removing shortcuts on Windows when installing/uninstalling.
if (require('electron-squirrel-startup')) { // eslint-disable-line global-require
    app.quit();
}

app.commandLine.appendSwitch('disable-web-security');
app.commandLine.appendSwitch('disable-site-isolation-trials');

const createWindow = (): void => {
    session.defaultSession.webRequest.onBeforeSendHeaders((details, callback) => {
        // We abuse the `iframe` name attribute to sneak in the target URL, to later use as a proxy target
        details.requestHeaders['X-Ace-ProxyTarget'] = details.frame.name;

        callback({
            requestHeaders: details.requestHeaders,
        });
    });

    // Create the browser window.
    const mainWindow = new BrowserWindow({
        width: 1200,
        height: 800,
        fullscreenable: true,
        frame: false,
        icon: 'extraResources/icon.ico',
        webPreferences: {
            webSecurity: false,
            nodeIntegration: true,
            enableRemoteModule: true,
            contextIsolation: false,
        },
    });

    mainWindow.setMenuBarVisibility(false);

    // and load the index.html of the app.
    mainWindow.loadURL(MAIN_WINDOW_WEBPACK_ENTRY);

    installExtension(REACT_DEVELOPER_TOOLS)
        .then((name) => console.log(`Added Extension:  ${name}`))
        .catch((err) => console.log('An error occurred: ', err));

    // Open the DevTools.
    mainWindow.webContents.openDevTools();
};

// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.on('ready', createWindow);

ipcMain.on('load-project', (event, arg) => {
    if (server) server.close(() => console.log('server closed'));
    statics.push(arg);
    server = express();
    server.use(cors());
    statics.forEach((s) => server.use(express.static(s)));
    server.use(createProxyMiddleware({
        target: 'http://localhost:9696/',
        router: (req) => req.header('X-Ace-ProxyTarget'),
        changeOrigin: false,
    }));
    server = server.listen(PORT);
});

// Quit when all windows are closed, except on macOS. There, it's common
// for applications and their menu bar to stay active until the user quits
// explicitly with Cmd + Q.
app.on('window-all-closed', () => {
    if (process.platform !== 'darwin') {
        app.quit();
    }
});

app.on('activate', () => {
    // On OS X it's common to re-create a window in the app when the
    // dock icon is clicked and there are no other windows open.
    if (BrowserWindow.getAllWindows().length === 0) {
        createWindow();
    }
});

// Discord RPC Handling

const DISCORD_CLIENT_ID = '891850893530652712';

const client = new RPC.Client({ transport: 'ipc' });

console.log('Logging in to Discord RPC...');

// Log in to RPC with client id
client.login({ clientId: DISCORD_CLIENT_ID }).catch(console.error);

// Handle state updates from renderer
ipcMain.on('set-rpc-state', (_, state: string) => {
    client.setActivity({
        largeImageKey: 'ace-icon-large',
        state,
    });
});

ipcMain.on('set-rpc-state-with-time', (_, state: string, startTimestamp) => {
    client.setActivity({
        largeImageKey: 'ace-icon-large',
        state,
        startTimestamp,
    });
});

ipcMain.on('update-rpc-permission', (_, allowed: boolean) => {
    if (allowed) {
        client.setActivity({
            largeImageKey: 'ace-icon-large',
            state: 'Idling',
        });
    } else {
        client.clearActivity();
    }
});