const { app, BrowserWindow, ipcMain } = require('electron');
const { fork } = require('child_process');
const path = require('path');
const log = require('electron-log');

const sessionId = new Date().toISOString().replace(/[:.]/g, '-');
log.transports.file.resolvePath = () => path.join(app.getPath('userData'), 'logs', `${sessionId}.log`);

log.transports.file.level = 'info';
log.format = '[{y}-{m}-{d} {h}:{i}:{s}.{ms}] [{level}] {text}';

let win;
let backend;
const net = require('net');

function waitForServer(port, host = '127.0.0.1', timeout = 10000) {
    return new Promise((resolve, reject) => {
        const start = Date.now();

        const check = () => {
            const socket = new net.Socket();

            socket
                .once('connect', () => {
                    socket.destroy();
                    resolve();
                })
                .once('error', () => {
                    socket.destroy();
                    if (Date.now() - start > timeout) {
                        reject(new Error('Backend timeout'));
                    } else {
                        setTimeout(check, 200);
                    }
                })
                .connect(port, host);
        };

        check();
    });
}

function startBackend() {
    backend = fork(path.join(__dirname, 'server.js'), [], {
        stdio: ['pipe', 'pipe', 'pipe', 'ipc'],
        env: {
            ...process.env,
            IS_PACKAGED: app.isPackaged ? 'true' : 'false'
        }
    });

    log.info('Starting backend process...');

    backend.stdout.on('data', (data) => {
        log.info(`[Backend]: ${data.toString().trim()}`);
    });

    backend.stderr.on('data', (data) => {
        log.error(`[Backend ERROR]: ${data.toString().trim()}`);
    });

    backend.on('exit', (code) => {
        log.warn(`Backend process exited with code: ${code}`);
    });
}

let splash;

function createSplash() {
    splash = new BrowserWindow({
        width: 400,
        height: 300,
        frame: false,
        transparent: false,
        alwaysOnTop: true,
        resizable: false,
        hasShadow: false,
        backgroundColor: '#00000000'
    });

    splash.loadFile('loading.html');
}

function createWindow() {
    win = new BrowserWindow({
        width: 1200,
        height: 800,
        frame: false,
        titleBarStyle: "hidden",
        webPreferences: {
            preload: path.join(__dirname, "preload.js"),
            nodeIntegration: false,
            contextIsolation: true
        }
    });

    win.setMenu(null);
    win.maximize();

    win.loadURL('http://localhost:54322');

    win.on('closed', () => {
        win = null;
    });
}

ipcMain.on("win:minimize", () => win.minimize());
ipcMain.on("win:maximize", () => {
    if (win.isMaximized()) {
        win.unmaximize();
    } else {
        win.maximize();
    }
});
ipcMain.on("win:close", () => win.close());

process.on('uncaughtException', (err) => {
    log.error('Critical unhandled error in Main:', err);
});

app.whenReady().then(async () => {
    startBackend();
    createSplash();
    try {
        await waitForServer(54322);
        createWindow();
        splash.close();
    } catch (e) {
        splash.close();
        log.error(e);
        app.quit();
    }
});

app.on('window-all-closed', () => {
    log.info('Closing all windows...');
    if (backend) {
        backend.kill();
        log.info('Backend process terminated.');
    }
    if (process.platform !== 'darwin') {
        app.quit();
    }
});