/*
    ! /startup/screen/init.js – Splash Screen Initialization Module
    ? This module will initialize the startup loading screen
*/

module.exports = async () => {

    // % load node dependencies
    const { app, BrowserWindow, Menu } = require('electron');
    const path = require('path');

    // % splash screen variables
    let splashWin; // reference to the splash screen window
    let isReady = false; // initial ready state
    let pendingUpdate = null; // initial pending update state
    let animationInterval = null; // initial animation interval null

    // $ create window function
    const createWindow = () => {
        // ~ initialize browser window
        splashWin = new BrowserWindow({
            title: "LupiNex Broadcast Studio",

            // § window measures
            width: 600,
            height: 300,

            // § window settings
            frame: false,
            transparent: true,
            alwaysOnTop: true,
            closable: false,
            show: false,

            // § window webprefs
            webPreferences: {
                preload: path.join(__dirname, 'preload.js'),
                nodeIntegration: false,
                contextIsolation: true
            }
        });

        // ~ check if window is ready to be displayed
        splashWin.once('ready-to-show', () => {
            splashWin.show(); // show the splash screen
            isReady = true; // set ready state to true
            if (pendingUpdate) updateWindow(pendingUpdate.progress, pendingUpdate.message); // execute a pending update
        });

        // ~ ignore mouse events
        splashWin.setIgnoreMouseEvents(true);

        // ~ remove application menu
        Menu.setApplicationMenu(null);

        // ~ load html file
        splashWin.loadFile(path.join(__dirname, 'index.html'));

        // ~ return window reference
        return splashWin;
    };

    // $ update window function
    const updateWindow = (progress, message, isStatic = false) => {
        // ~ stop running intervals if applicable
        if (animationInterval) clearInterval(animationInterval);

        // ~ create dot animation if not static
        if (!isStatic) {
            let dots = 0; // initial dot count

            // § create interval
            animationInterval = setInterval(() => {
                dots = (dots + 1) % 4; // calculate dot count
                const animatedMessage = message + ".".repeat(dots); // add dots to message
                sendToWebContents(progress, animatedMessage); // execute update function
            }, 750);
        }

        // ~ send status immediately
        sendToWebContents(progress, message);
    };

    // ~ helper function to send update data
    const sendToWebContents = (progress, message) => {
        // § wait if electron is not ready
        if (!isReady) {
            pendingUpdate = { progress, message };
            return;
        }

        // § send message to electron ipc
        if (splashWin && !splashWin.isDestroyed()) {
            splashWin.webContents.send('update-splash', { 
                ...(progress !== null && { progress }), 
                message 
            });
        }
    };

    // $ close window function
    const closeWindow = () => {
        if (splashWin && !splashWin.isDestroyed()) splashWin.close();
    };

    // $ electron lifecycle
    app.whenReady().then(() => { createWindow() });

    // $ return window functions
    return {
        update: updateWindow,
        close: closeWindow
    };
};