
const MUTATION_REFRESH_CHECK = 1000;

const DOM_IDS = ["AIFEX_probabilityPopup", "AIFEX_tab"]

export default class PageMutationHandler {

    lastMutation: number;
    observer: MutationObserver;
    mutationHasOccured: boolean;
    beRefreshing : boolean;
    willRefresh : boolean;

    onPageMutation: Function;

    constructor(onPageMutation: Function) {
        this.onPageMutation = onPageMutation
        this.beRefreshing = false;
        this.mutationHasOccured = false;
        this.willRefresh = false;
    }

    init() {
        this.lastMutation = Date.now();
        this.observer = new MutationObserver((records) => {
            let watchedPageHasMutated = false;
            for (const record of records) {
                //console.log('record', record);
                if (record.type === "childList") {
                    if (this.isWatchedNodeList(record.addedNodes) && ! this.isIncludedInAIFEXElement(record.addedNodes)) {
                        watchedPageHasMutated = true;
                    }
                }
            }
            if (watchedPageHasMutated) {
                //console.log('mutation');
                if (! this.beRefreshing) {
                    this.beRefreshing = true;
                    //console.log('refresh just after a mutation')
                    this.onPageMutation();
                    setTimeout(() => {
                        this.beRefreshing = false;
                    }, MUTATION_REFRESH_CHECK);
                } else {
                    if (!this.willRefresh) {
                        this.willRefresh = true;
                        setTimeout(() => {
                            this.beRefreshing = true;
                            //console.log('refresh later after a mutation')
                            this.onPageMutation();
                            setTimeout(() => {
                                this.beRefreshing = false;
                                this.willRefresh = false;
                            }, MUTATION_REFRESH_CHECK);
                        }, 2*MUTATION_REFRESH_CHECK);
                    }
                }
                
            }
        });
        let config = { attributes: false, childList: true, characterData: false, subtree: true};
        this.observer.observe(document.body, config);

        // setInterval(() => {
        //     if (this.mutationHasOccured) {
        //         this.onPageMutation();
        //     }
        // }, MUTATION_REFRESH_CHECK)
    }

    private isWatchedNodeList(nodeList : NodeList) : boolean {
        let isWatched : boolean = false;
        nodeList.forEach(node => {
            if (node instanceof HTMLElement) {
                if (node.tagName !== "SCRIPT" && node.tagName !== "IFRAME" && node.tagName !== "IMG") {
                    if (!node.style) {
                        isWatched = true;
                    }
                    if (!node.style.display) {
                        isWatched = true;
                    } 
                    if (node.style.display !== "none") {
                        isWatched = true;
                    }
                }
            }
        }) 
        return isWatched;
    }

    private isIncludedInAIFEXElement(nodeList : NodeList) : boolean {
        const AIFEXElementList = DOM_IDS.map(id => document.getElementById(id)).filter(element => element !== null);
        let isIncluded : boolean = true;
        nodeList.forEach(node => {
            if (node instanceof HTMLElement) {
                if (!AIFEXElementList.some((aifexNode) => {
                    return aifexNode.contains(node);
                })) {
                    isIncluded = false;
                }
            }
        })
        return isIncluded;
    }
}