import State from "../domain/State";
import { querySelectorAllDeep } from 'query-selector-shadow-dom';
import cssStyle from "./cssStyle";
import RuleService from "../domain/rules/RuleService";

export default class ActionBorderView {

    stylesheetElement: Element;

    constructor() {
        this.stylesheetElement = null;
    } 

    init(state: State, ruleService: RuleService): Promise<void> {
        return new Promise(resolve => {
            this.attachStyleSheet(document.head);

            ruleService.attachRulesToElements();
            for (const [dom_element, rules] of ruleService.elementRules) {
                const rootNode = dom_element.getRootNode()
                if (rootNode !== document) {
                    this.attachStyleSheet(rootNode);
                }
                dom_element.setAttribute("aifex_frequency", null);
                if (state.isActive) {
                    dom_element.setAttribute("aifex_style", "true");
                } else {
                    dom_element.setAttribute("aifex_style", "false");
                }
                for (const rule of rules) {
                    dom_element.setAttribute(`aifex_${rule.prefix}`, "true");
                }
            }
            resolve();
        })
    }

    refresh(state: State, ruleService: RuleService): Promise<void> {
        return this.init(state, ruleService).then(() => {
            const promises = [];
            for (const [element, actionList] of state.elementActionListMap) {
                promises.push(new Promise(resolve => {
                    let maxProbability = 0;
                    for (let action of actionList) {
                        if (action.probability > maxProbability) {
                            maxProbability = action.probability;
                        }
                    }
                    if (maxProbability > 0.6) {
                        element.setAttribute("aifex_frequency", "often")
                    } else if (maxProbability > 0.3) {
                        element.setAttribute("aifex_frequency", "sometimes")
                    } else if (maxProbability > 0.01) {
                        element.setAttribute("aifex_frequency", "rarely")
                    } else {
                        element.setAttribute("aifex_frequency", "never")
                    }
                    resolve();
                }))
            }
            return Promise.all(promises).then()
        })
    }

    private attachStyleSheet(node) {
        const nodeChilds: Element[] = Array.from(node.children);
        if (nodeChilds.some(node => node.hasAttribute("aifex_stylesheet"))) {
            return;
        }
        if (this.stylesheetElement) {
            node.appendChild(this.stylesheetElement.cloneNode(true));
        } else {
            this.stylesheetElement = document.createElement("style");
            this.stylesheetElement.setAttribute("type", "text/css");
            this.stylesheetElement.setAttribute("aifex_stylesheet", "true");
    
            const cssNode = document.createTextNode(cssStyle);
            this.stylesheetElement.appendChild(cssNode);
            node.appendChild(this.stylesheetElement);
        }
    }

    clear(ruleService): Promise<void> {
        return new Promise((resolve) => {
            const dom_elements = querySelectorAllDeep("[aifex_style]")
            for (const dom_element of dom_elements) {
                if (!ruleService.elementRules.has(dom_element)) {
                    dom_element.removeAttribute("aifex_frequency");
                    dom_element.removeAttribute("aifex_style");
                }
            }
            resolve();
        })
    }

    hide(): Promise<void> {
        return new Promise(resolve => {
            const dom_elements = querySelectorAllDeep("[aifex_style]");
            for (const element of dom_elements) {
                element.setAttribute("aifex_style", false);
            }
            resolve();
        })
    }

    show(): Promise<void> {
        return new Promise(resolve => {
            const dom_elements = querySelectorAllDeep("[aifex_style]");
            for (const element of dom_elements) {
                element.setAttribute("aifex_style", true);
            }
            resolve();
        })
    }

}