import {helperFunctions} from '../lib/helperFunctions';
import {domEventsHandler} from '../util/domEventsHandler';

class _proactiveChat {

    constructor() {
        this.params = {};
        this.timeoutStatuscheck = null;
        this.timeoutActivity = null;
        this.attributes = null;
        this.chatEvents = null;
        this.dynamicInvitations = [];

        this.iddleTimeoutActivity = null;
        this.checkMessageTimeout = null;
        this.nextRescheduleTimeout = null;
        this.initCall = true;
        this.inProgress = false;
    }

    setParams(params, attributes, chatEvents) {
        this.params = params;
        this.attributes = attributes;
        this.chatEvents = chatEvents;

        if (this.attributes.events.length > 0) {
            this.storeEvents(this.attributes.events);
        } else {
            this.initInvitation();
        }

        if (this.attributes.conversion != '') {
            this.storeConversion(this.attributes.conversion);
        }

        // check invitaiton then tag is added
        this.attributes.eventEmitter.addListener('tagAdded', () => {
            this.initInvitation({init: 0});
        });

        this.attributes.eventEmitter.addListener('eventAdded', () => {
            this.storeEvents(this.attributes.events);
        });

        this.attributes.eventEmitter.addListener('conversionAdded', () => {
            this.storeConversion(this.attributes.conversion);
        });

        this.attributes.eventEmitter.addListener('checkMessageOperator', () => {
            this.initInvitation({init: 0});
        });

        this.attributes.eventEmitter.addListener('endChat', () => {
             this.initInvitation({init: 0});
        });

        this.attributes.onlineStatus.subscribe((data) => {
            if (data == true) {
                this.initInvitation({init: 0});
            } else {
                const chatParams = this.attributes['userSession'].getSessionAttributes();
                if (!chatParams['id'] && this.attributes.proactive.invitation) {
                    this.attributes.proactive = {};
                    if (this.attributes.mainWidget.isLoaded !== false) {
                        this.chatEvents.sendChildEvent('proactive', [{}]);
                    }
                    this.attributes.mainWidget.hideInvitation();
                    this.attributes.eventEmitter.emitEvent('closeWidget', [{'sender' : 'closeButton'}]);
                }
            }
        });
    }

    showInvitation(params, init) {
        const chatParams = this.attributes['userSession'].getSessionAttributes();

        // Show invitation only if widget is not open
        if ((init === 0 && (this.attributes.widgetStatus.value === true && !this.attributes.mode == 'embed')) || chatParams['id']) {
            return;
        }

        if (params.inject_html && params.invitation) {
            var th = document.getElementsByTagName('head')[0];
            var s = document.createElement('script');
            s.setAttribute('type','text/javascript');
            s.setAttribute('src', this.attributes.LHC_API.args.lhc_base_url + this.attributes['lang'] + 'chat/htmlsnippet/'+params.invitation+'/inv/0/?ts='+Date.now());
            th.appendChild(s);
        }

        if (!params.only_inject) {
            this.attributes.proactive = params;

            if (this.attributes.mainWidget.isLoaded === false) {
                this.attributes.mainWidget.bootstrap();
            } else {
                this.chatEvents.sendChildEvent('proactive', [params]);
            }

            clearTimeout(this.checkMessageTimeout);
            clearTimeout(this.nextRescheduleTimeout);
        }
    }

    storeEvents(events) {
        const chatParams = this.attributes['userSession'].getSessionAttributes();
        if (!chatParams['id'] && this.attributes['onlineStatus'].value == true) {
            helperFunctions.makeRequest(this.attributes.LHC_API.args.lhc_base_url + this.attributes['lang'] + 'chat/logevent/(vid)/' + this.attributes.userSession.getVID(), {params: {'data' : JSON.stringify(events)}}, (data) => {
                this.initInvitation({init: 0});
            })
        }
    }

    storeConversion(conversion) {
        const chatParams = this.attributes['userSession'].getSessionAttributes();
        if (!chatParams['id'] && this.attributes['onlineStatus'].value == true) {
            helperFunctions.makeRequest(this.attributes.LHC_API.args.lhc_base_url + this.attributes['lang'] + 'widgetrestapi/logconversions/(vid)/' + this.attributes.userSession.getVID(), {params: {'data' : JSON.stringify(conversion)}}, (data) => {

            });
        }
    }

    initInvitation(paramsExecution) {

        if (this.inProgress == true) {
            return ;
        }

        clearTimeout(this.checkMessageTimeout);

        const chatParams = this.attributes['userSession'].getSessionAttributes();

        const init = (paramsExecution && paramsExecution['init'] === 0) ? 0 : 1;

        if (!chatParams['id'] && this.attributes['onlineStatus'].value == true) {

            this.inProgress = true;

            let params = {
                'vid': this.attributes.userSession.getVID(),
                'dep': this.attributes.department.join(',')
            };

            if (this.attributes.LHC_API.args.priority) {
                params['priority'] = this.attributes.LHC_API.args.priority;
            }

            if (this.attributes.LHC_API.args.operator) {
                params['operator'] = this.attributes.LHC_API.args.operator;
            }

            if (this.attributes['identifier']) {
                params['idnt'] = this.attributes['identifier']
            }

            if (this.attributes['tag']) {
                params['tag'] = this.attributes['tag']
            }

            if (this.attributes['langOverride']) {
                params['lang'] = this.attributes['langOverride']
            }

            params['l'] = encodeURIComponent(window.location.href.substring(window.location.protocol.length));
            params['dt'] = encodeURIComponent(document.title);
            params['init'] = this.initCall == true ? 1 : init;

            this.initCall = false;

            helperFunctions.makeRequest(this.attributes.LHC_API.args.lhc_base_url + this.attributes['lang'] + 'widgetrestapi/checkinvitation', {params: params}, (data) => {

                this.inProgress = false;
                
                if (data.invitation) {
                    const params = {'vid_id' : data.vid_id, 'invitation' : data.invitation, 'inject_html' :  data.inject_html, 'qinv' : data.qinv};
                    setTimeout(() => {
                        this.showInvitation(params, init);
                    }, this.attributes.widgetStatus.value === true ? 0 : (data.delay ? data.delay + this.attributes['status_delay'] : this.attributes['status_delay']));
                } else {
                    if (this.attributes.LHC_API.args.check_messages) {
                        this.checkMessageTimeout = setTimeout(() => {
                            this.initInvitation({init: 0});
                        },this.params['interval'] * 1000);
                    }
                }

                if (data.next_reschedule) {
                    this.nextRescheduleTimeout = setTimeout(() => {
                        this.initInvitation({init: 0});
                    }, data.next_reschedule);
                }

                if (data.dynamic) {
                    data.dynamic.forEach((item) => {
                        this.dynamicInvitations.push(item.id);
                        if (item.type === 1) {
                            domEventsHandler.listen(document, 'mouseout', (e) => {
                                e = e ? e : window.event;
                                var from = e.relatedTarget || e.toElement;
                                if (!from || from.nodeName == "HTML") {
                                    this.showInvitation({'vid_id' : data.vid_id, 'invitation' : item.id, 'inject_html' :  item.inject_html, 'qinv' : data.qinv, 'only_inject' : item.only_inject});
                                    if (!item.every_time) {
                                        domEventsHandler.unlisten('lhc_inv_mouse_out_'+item.id);
                                    }
                                }
                            }, 'lhc_inv_mouse_out_' + item.id);
                        } else if (item.type === 2) {

                            var iddleTimeout = () => {

                                this.showInvitation({'vid_id' : data.vid_id, 'invitation' : item.id, 'inject_html' :  item.inject_html, 'qinv' : data.qinv, 'only_inject' : item.only_inject});

                                clearTimeout(this.iddleTimeoutActivity);

                                if (!item.every_time) {
                                    ['mousemove','mousedown','click','scroll','keypress','load'].forEach((element) => {
                                        domEventsHandler.unlisten('lhc_inv_iddl_win_'+element);
                                    });

                                    ['mousemove','scroll','touchstart','touchend'].forEach((element) => {
                                        domEventsHandler.unlisten('lhc_inv_iddl_doc_'+element);
                                    });
                                }
                            };

                            this.iddleTimeoutActivityReset = () => {
                                clearTimeout(this.iddleTimeoutActivity);
                                this.iddleTimeoutActivity = setTimeout( () => { iddleTimeout(); }, item.iddle_for *1000);
                            }

                            this.iddleTimeoutActivityReset();

                            ['mousemove','mousedown','click','scroll','keypress','load'].forEach((event) => {
                                    domEventsHandler.listen(window, event, this.iddleTimeoutActivityReset, 'lhc_inv_iddl_win_'+event);
                            });

                            ['mousemove','scroll','touchstart','touchend'].forEach((event) => {
                                domEventsHandler.listen(document, event, this.iddleTimeoutActivityReset, 'lhc_inv_iddl_doc_'+event);
                            });
                        }
                    })
                }
            });
        }
    }
}

const proactiveChat = new _proactiveChat();
export {proactiveChat};

