const { npm_package_dependencies_neuro_ad: asSubmodule } = process.env;
const { forMain, forRenderInside } = require('./configs-constants/eventNames.js');
const moment = require("moment");

const runNeuroAd = () => {
    const { ipcRenderer, remote } = require('electron');
    const moment = require('moment');
    const fs = require("fs");
    const path = require("path");
    const mime = require('mime-types');
    const _ = require('lodash');
    const log = require('electron-log');// error // warn // info // verbose // debug // silly
    const isDev = require('electron-is-dev');
    const os = require('os');

    if (asSubmodule) {
        // require('./modules/page/indoor-nav-helper');
    } else {
        const logger = require('./modules/logger');

        require('./modules/unhandled-errors')();

        logger.init();
    }

    const findContent = require('./modules/jsondata/find-content-for-today');
    // const repeats = require('./modules/repeats');
    const getStartBlocksTime = require('./modules/neuro-ad-content/get-start-blocks-time');
    const getVideoDuration = require('./modules/get-video-duration');
    const contentController = require('./modules/page/content-controller');
    const infoPopup = require('./modules/info-popup');
    const RamDisk = require('./modules/RamDisk.js');

    contentController.init(document);

    moment.locale('en');

    const isLowCpu = (os.cpus().length < 4);
    let savedJsonDir = '';
    let appUserData = '';

    let defaultVideoSrc = '';
    let defaultVideoDuration = 0;
    let playRaf;// requestAnimationFrame()
    const maxLoopFps = (isLowCpu ? 10 : 60);
    let lastRunLoopTime = 0;
    let newData;
    let blocksStartTime = [];
    let contentStartTime = [];
    let currentBlockIndex = -1;
    let currentContentIndex = -1;
    let lastUpdateHour = null;

    let updateRepeat = false;
    let currentPlayingItem = false;
    const options = Object.freeze({
        startPlayMaxDiffMs: 30
    });
    let gVolume = 0;
    let muted = false;

    (isDev ? document.body.classList.add('development') : null);

    const updateOnlineStatus = () => {
        const isOnline = navigator.onLine;

        log.info('network-connection:', isOnline);

        ipcRenderer.send(forMain.onlineStatus, isOnline);
        infoPopup.common.updateOnlineStatus(isOnline);

        return isOnline;
    };

    ipcRenderer.on('msg', (event, arg) => {
        switch ( arg.type ) {
            case('init'):
                if ( !playRaf ) {
                    playRaf = requestAnimationFrame(loop);
                }
                break;
            case('device_orientation'):
                let  videoPath = './video/main'+(arg.msg === 'vertical' ? '.mp4' : '_horizontal.webm');
                defaultVideoSrc = path.join(__dirname, videoPath);
                try {
                    if (fs.existsSync(arg.pathToDefaultVideo)) {
                        defaultVideoSrc = arg.pathToDefaultVideo
                    } else {
                        console.log('NeuroAd дефолтный файл не найден: ',arg.pathToDefaultVideo);
                    }
                } catch (err) {
                    console.error('NeuroAd Ошибка при проверке дефолтного файла:', `${err}`);
                }
                console.log('defaultVideoSrc: ', defaultVideoSrc);


                setTimeout(() => {
                    getVideoDuration(defaultVideoSrc)
                        .then((videoDuration) => {
                            let intervalId = setInterval(() => {
                                if (updateOnlineStatus()) {
                                    clearInterval(intervalId);

                                    window.addEventListener('online',  updateOnlineStatus);
                                    window.addEventListener('offline',  updateOnlineStatus);
                                }
                            }, 3333);

                            defaultVideoDuration = videoDuration;
                            ipcRenderer.send(forMain.pageReadyForPlay, true);
                        });
                }, 200);
                break;
            case('createWebSocket'):
                if (!asSubmodule) {
                    require('./modules/page/webSockets')(arg.msg);
                }
                break;
            case('appUserDataPath'):
                appUserData = arg.msg;
                break;
            case('savedJsonDir'):
                savedJsonDir = arg.msg;
                break;
            case('newData'):
                log.info('new data');

                if ( typeof arg.msg.data === 'object' ) {
                    newData = arg.msg.data;
                    createPlaylist(newData);
                }
                break;
            case('g_volume'):
                gVolume = parseFloat(arg.msg > 1 ? Math.round(arg.msg) / 100 : arg.msg);
                log.info('global volume', gVolume, arg.msg);
                break;
        }
    });

    window.addEventListener('keydown', function (event) {
        const keyChar = event.code.substr(3).toLowerCase();

        if ( keyChar === 'i' && event.ctrlKey && event.altKey && event.shiftKey ) {
            infoPopup.popup.toggle();
        }
    });

    /**
     * @param {object} data
     */
    const createPlaylist = data => {
        try {
            ipcRenderer.emit('play');

            if (!defaultVideoDuration) {
                return;
            }

            log.warn('createPlaylist');

            const blocksTimes = getStartBlocksTime(findContent(data, '_ads'), findContent(data, '_info'), defaultVideoSrc, defaultVideoDuration);//
            let isEqual = false;

            if ( blocksTimes.blocksStartTime.length > 0 && blocksTimes.contentStartTime.length > 0 ) {
                if ( contentStartTime && contentStartTime.length > 0 ) {
                    isEqual = true;

                    contentStartTime.forEach((item, itemIndex) => {
                        if ( item && item.length > 0 ) {
                            item.forEach((innerItem, innerItemIndex) => {
                                let current = (blocksTimes.contentStartTime[itemIndex] ? blocksTimes.contentStartTime[itemIndex][innerItemIndex] : false);
                                current = (current ? _.omit(current, ['playingTime', 'startPlayingTime']) : false);
                                const newItem = (innerItem ? _.omit(innerItem, ['playingTime', 'startPlayingTime']) : false);

                                if ( !_.isEqual(current, newItem) ) {
                                    isEqual = false;
                                }
                            });
                        }
                    });
                }

                if ( !isEqual ) {
                    //TO DO Логи плейлиста пока отключены до доработки
                    // log.info('new content !!',blocksTimes);
                    currentBlockIndex = -1;
                    currentContentIndex = -1;
                    blocksStartTime = blocksTimes.blocksStartTime;
                    contentStartTime = blocksTimes.contentStartTime;

                    // contentStartTime.forEach((item) => {
                    //     log.info(item)
                    // })

                    // log.info(blocksTimes);


                    // log.info(filePath, fileHash)
                    // if (filePath && fileHash) {
                    //     ramDisk.save(filePath);
                    // }

                    // let filePath = (item ? item.content_server_path[contentItemIndex] : defaultVideoSrc);
                    // let fileHash = (item ? item.content_hash[contentItemIndex] : '');

                    infoPopup.playlist.newPlaylist(blocksStartTime, contentStartTime);
                } else {
                    // log.info('CONTENT EQUAL');
                }

                lastUpdateHour = moment().startOf('hours').unix();
            } else {
                log.error('don\'t find content for this hours');
            }
        } catch (err) {
            log.error(err);
        }
    };

    const loop = function (time) {
        try {
            playRaf = requestAnimationFrame(loop);

            if (lastRunLoopTime && (time - lastRunLoopTime) < (1000 / maxLoopFps)) {
                return;
            }

            lastRunLoopTime = time;

            if (!defaultVideoDuration) {
                log.warn(`default video duration is "${defaultVideoDuration}", can't create playlist`);

                return;
            }

            if ( contentStartTime.length === 0 ) {
                createPlaylist();
            } else if ( contentStartTime.length > 0 ) {
                // log.error(contentStartTime[0]);
                const timestampMs = Math.round(moment().format('x'));
                let removeItemsLength = 0;

                if ( currentPlayingItem && currentPlayingItem.startPlayingTime >= 0 && currentPlayingItem.playingTime >= 0 ) {
                    let maxTime = Math.round(currentPlayingItem.durationMs > 1000 * 5 ? currentPlayingItem.durationMs - 200 : currentPlayingItem.durationMs - 100);
                    currentPlayingItem.playingTime = timestampMs - currentPlayingItem.startPlayingTime;

                    if ( updateRepeat && currentPlayingItem.playingTime >= maxTime ) {
                        updateRepeat = false;
                        // repeats.update(currentPlayingItem.id, currentPlayingItem.startTime);
                    }
                }

                if ( blocksStartTime.length > 0 ) {
                    blocksStartTime.forEach((time, index) => {
                        if ( time < timestampMs ) {
                            removeItemsLength++;
                        } else if ( time >= timestampMs && time < timestampMs + options.startPlayMaxDiffMs ) {
                            removeItemsLength++;
                            log.info('start playing new block');
                        }
                    });
                }

                if ( removeItemsLength > 0 ) {
                    let a = blocksStartTime.splice(0, removeItemsLength);
                    currentBlockIndex = currentBlockIndex + removeItemsLength;
                    log.info(blocksStartTime.length, moment(a[a.length - 1]).format('HH:mm:ss.SSS'));
                    currentContentIndex = -1;

                }

                if ( contentStartTime[currentBlockIndex].length > 0 ) {
                    for ( let i = 0; i < contentStartTime[currentBlockIndex].length; i++ ) {
                        const item = contentStartTime[currentBlockIndex][i];

                        if ( item.startTime <= timestampMs && (Math.round(item.startTime + item.durationMs) > timestampMs) ) {
                            if ( currentContentIndex !== i ) {
                                currentContentIndex = i;
                                document.dispatchEvent(new CustomEvent('neuroad-startPlay', { detail: { itemInfo: item } })); // кастомный эвент в document
                                play(item);
                            }
                            break;
                        }
                    }

                    if ( currentContentIndex < 0 || currentContentIndex === contentStartTime[currentBlockIndex].length - 1 ) {
                        if(lastUpdateHour === null || lastUpdateHour < moment().startOf('hours').unix())
                            createPlaylist(newData);
                    }
                }
            }
        } catch (err) {
            log.error('loop()', err);
        }
    };

    /**
     * @param {object} item
     */
    const play = function (item) {
        try {
            updateRepeat = true;
            currentPlayingItem = item;

            const contentElem = contentController.get(item.filePath);
            const now = moment().format('x');
            const startDiff = now - item.startTime;

            contentController.show(item.filePath);
            contentController.saveCurrentContentData(item);

            if ( currentPlayingItem.startPlayingTime >= 0 ) {
                currentPlayingItem.startPlayingTime = now;

                updateRepeat = (startDiff >= options.startPlayMaxDiffMs ? false : updateRepeat);
            } else {
                updateRepeat = false;
            }

            if ( contentElem.tagName === 'VIDEO' ) {
                contentElem.volume = gVolume * item.volume;
                contentElem.muted = muted;
                contentElem.currentTime = (startDiff >= options.startPlayMaxDiffMs ? startDiff / 1000 : 0);

                contentElem.play()
                    .then()
                    .catch((err) => {
                        log.error('play() content error', err);
                        blocksStartTime = [];
                        contentStartTime = [];
                        currentBlockIndex = -1;
                        currentContentIndex = -1;
                    });
            }

            document.dispatchEvent(new CustomEvent(forRenderInside.playItem, { detail: item }));

            infoPopup.playlist.updatePlayedInfo(currentPlayingItem);

            log.info('play item', item, 'set volume:', contentElem.volume, 'muted:', contentElem.muted);
        } catch (err) {
            log.error('play()', err);
        }
    };

    if (asSubmodule) {
        document.addEventListener('neuroad_mute', () => muted = true);
        document.addEventListener('neuroad_unmute', () => muted = false);
    }

    ipcRenderer.send(forMain.pageReady, true);
};

if (!asSubmodule) {
    runNeuroAd();
}

module.exports = runNeuroAd;
