const app = require('electron').remote.app;
const log = require('electron-log');
const moment = require('moment');
const path = require('path');

const checkContentObject = require('./check-content-object');
const getContentItemIndex = require('./get-content-item-index');
const RamDisk = require('../RamDisk.js');

const isDebug = false;
/**
 *
 * @param {object} ads
 * @param {object} info
 * @param {string} defaultVideoSrc
 * @param {number} defaultVideoDuration
 * @returns {{blocksStartTime: Array, contentStartTime: Array}}
 */
module.exports = (ads, info, defaultVideoSrc, defaultVideoDuration) => {
    try {
        const failResult = { blocksStartTime: [], contentStartTime: [] };

        const isAds = checkContentObject(ads);
        const isInfo = checkContentObject(info);

        if (isDebug) {
            console.log(`%c [get-start-block-time] isAds: ${isAds}; isInfo: ${isInfo};`, 'color: green;');
        }

        if ( !isAds && !isInfo && defaultVideoDuration < 1 ) {
            return failResult;
        }

        if(typeof window === 'undefined') log.error("WINDOW UNDEFINED");

        if(!window) return failResult;
        if(typeof window.userDataSelf === 'undefined') window.userDataSelf = app.getPath('userData');

        const appUserData = window.userDataSelf;
        const hoursSecs = 3600;
        const blockDuration = (ads.block_dur >= 0 ? parseInt(ads.block_dur, 10) * 60 : hoursSecs);
        const blockDurationMs = blockDuration * 1000;
        const nowMoment = moment();
        const startOfHoursMs = Math.round(nowMoment.startOf('hours').format('x'));
        const currentHours = parseInt(nowMoment.format('HH'), 10);
        const blocksStartTime = [];
        const contentStartTime = [];
        let adsScriptIndex = 0;
        let infoScriptIndex = 0;
        let infoItemIndex = 0;
        let whileIndex = hoursSecs;
        let lastContentDurationMs = 0;
        let thisBlockTimes = [];
        const ramDisk = new RamDisk();
        const setNewItem = (item, key) => {
            const isItem = !!(item);
            const contentItemIndex = (isItem ? getContentItemIndex(item, currentHours) : null);

            if ( isItem && contentItemIndex < 0 ) {
                return false;
            }

            const newContentIndex = thisBlockTimes.length;
            const contentDurationMs = Math.round((isItem ? parseFloat(item.content_duration[contentItemIndex]) : defaultVideoDuration) * 1000);
            const getStartTime = () => {
                let startTime = blocksStartTime[blocksStartTime.length - 1];

                if ( newContentIndex !== 0 ) {
                    startTime = thisBlockTimes[newContentIndex - 1].startTime + lastContentDurationMs;//defaultVideoDurationMs
                }

                return Math.round(startTime);
            };
            const getVolume = () => {
                let volume = 0;

                if ( isItem && item.content_volume_range[contentItemIndex] ) {
                    volume = item.content_volume_range[contentItemIndex];

                    if ( volume > 1 ) {
                        volume = Math.round(volume) / 100;
                    }

                    volume = parseFloat(volume);
                }

                return volume;
            };
            const itemStartTime = getStartTime();
            let filePath = (isItem ? path.join(appUserData, item.content_server_path[contentItemIndex]) : defaultVideoSrc);

            if (filePath) {
                const newFilePath = ramDisk.save(filePath);

                filePath = (newFilePath || filePath);
            }

            thisBlockTimes[newContentIndex] = {
                startTime: itemStartTime,
                startTimePlain: moment(itemStartTime).format('HH:mm:ss.SSS'),
                filePath: filePath,
                volume: getVolume(),
                durationMs: contentDurationMs,
                id: (isItem ? item.id : null),
                startPlayingTime: 0,
                playingTime: 0,
                contentItemIndex: contentItemIndex,
                key: key,
                content_take_away: (isItem ? item.content_take_away : false),
                infoItemIndex: (key === '_info' ? infoItemIndex : null),
                name: (isItem ? item.content_name : ''),
                content_file_path: (isItem ? item.content_file_path : null)
            };

            lastContentDurationMs = contentDurationMs;

            return thisBlockTimes[newContentIndex];
        };
        let adsScriptDurationFact = 0;

        while ( whileIndex ) {
            const newBlockIndex = blocksStartTime.length;

            blocksStartTime[newBlockIndex] = (() => {
                let result = startOfHoursMs;

                if ( newBlockIndex !== 0 && blockDurationMs === 0 && isAds ) {
                    adsScriptDurationFact = parseFloat(ads.script[adsScriptIndex].script_duration_fact);
                    result = blocksStartTime[newBlockIndex - 1] + Math.round(adsScriptDurationFact * 1000);
                } else if ( newBlockIndex !== 0 ) {
                    result = blocksStartTime[newBlockIndex - 1] + blockDurationMs;
                }

                return result;
            })();
            contentStartTime[newBlockIndex] = (() => {
                thisBlockTimes = [];

                if ( isAds ) {
                    ads.script[adsScriptIndex].script_content.forEach((item) => setNewItem(item, '_ads'));

                    adsScriptIndex = (ads.script[adsScriptIndex + 1] ? adsScriptIndex + 1 : 0);
                }

                if ( blockDurationMs > 0 && isInfo ) {
                    let isBreak = false;

                    for ( let i = 0; i < hoursSecs; i++ ) {
                        for ( let itemIndex = 0; itemIndex < info.script[infoScriptIndex].script_content.length; itemIndex++ ) {
                            const item = info.script[infoScriptIndex].script_content[infoItemIndex];

                            const newItem = setNewItem(item, '_info');

                            if ( newItem.startTime + newItem.durationMs >= blocksStartTime[newBlockIndex] + blockDurationMs ) {
                                isBreak = true;

                                break;
                            }

                            infoItemIndex = (infoItemIndex + 1 < info.script[infoScriptIndex].script_content.length ? infoItemIndex + 1 : 0);
                        }

                        infoScriptIndex = (info.script[infoScriptIndex + 1] ? infoScriptIndex + 1 : 0);

                        if ( isBreak ) {
                            break;
                        }
                    }
                } else if ( blockDurationMs > 0 && defaultVideoDuration >= 1 ) {
                    const item = null;
                    const key = null;

                    for ( let i = 0; i < hoursSecs; i++ ) {
                        const newItem = setNewItem(item, key);

                        if ( newItem.startTime + newItem.durationMs >= blocksStartTime[newBlockIndex] + blockDurationMs ) {
                            break;
                        }
                    }
                }

                return thisBlockTimes;
            })();

            whileIndex -= (() => {
                let minus = blockDuration;

                if ( minus === 0 && isAds ) {
                    minus = adsScriptDurationFact;
                }

                return minus;
            })();

            if ( whileIndex <= 0 ) {
                for ( let i = newBlockIndex; i > 0; i-- ) {
                    const lastContentItem = contentStartTime[i][contentStartTime[i].length - 1];
                    const startInHours = parseInt(moment(lastContentItem.startTime).format('HH'), 10);

                    if ( startInHours !== currentHours ) {
                        blocksStartTime.pop();
                        contentStartTime.pop();

                        thisBlockTimes = contentStartTime[contentStartTime.length - 1];
                    } else {
                        break;
                    }
                }

                if ( blockDurationMs === 0 && defaultVideoDuration >= 1 ) {
                    const item = null;
                    const key = null;
                    const nextHoursTimestamp = parseInt(nowMoment.add(1, 'hours').format('x'), 10);

                    for ( let i = 0; i < hoursSecs; i++ ) {
                        const newItem = setNewItem(item, key);

                        if ( newItem.startTime + newItem.durationMs >= nextHoursTimestamp ) {

                            break;
                        }
                    }
                }

                break;
            }
        }

        return { blocksStartTime: blocksStartTime, contentStartTime: contentStartTime };
    } catch (err) {
        log.error('getStartBlocksTime()', err);
    }
};
