
const MUTATION_REFRESH_CHECK = 1000;

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

export default class PageMutationHandler {

    lastMutation: number;
    observer: MutationObserver;
    mutationHasOccured: boolean

    onPageMutation: Function;

    constructor(onPageMutation: Function) {
        this.onPageMutation = onPageMutation
    }

    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 !!:',record);
                    break
                }
            }
            if (watchedPageHasMutated) {
                this.mutationHasOccured = true;
            }
        });
        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;
    }
}