import { querySelectorAllDeep } from 'query-selector-shadow-dom';
import cssStyle from "./cssStyle";
import ActionState from '../domain/ActionsAndElements';
import {logger} from "../framework/Logger";

const WARM_COLOR_THRESHOLD = 0.6;
const MEDIUM_COLOL_THRESHOLD = 0.3;
const COLD_COLOR_THRESHOLD = 0.01;

export default class ActionProbabilityView {

    stylesheetElement: HTMLElement | undefined;
    private _lastElementWithAIFEXStyle : Set<HTMLElement>;

    constructor() {
        this._lastElementWithAIFEXStyle = new Set();
    }

    show(actionState: ActionState, elementListMatchedByRule: HTMLElement[]): void {
        logger.debug(`ActionProbabilityView show (elements : ${elementListMatchedByRule.length})`);
        this._lastElementWithAIFEXStyle.forEach(element => {
            element.removeAttribute("aifex_frequency");
            element.removeAttribute("aifex_style");
        })
        this.attachStyleSheet(document.head);

        for (const domElement of elementListMatchedByRule) {
            domElement.setAttribute("aifex_style", "true");
        }

        for (const action of actionState.actionList) {
            for (const htmlElement of action.htmlElementList) {
                const rootNode = htmlElement.getRootNode();
                if (rootNode instanceof HTMLElement) {
                    this.attachStyleSheet(rootNode);
                }
                this._lastElementWithAIFEXStyle.add(htmlElement);

                for (const rule of action.ruleList) {
                    htmlElement.setAttribute(`aifex_${rule.prefix}`, "true");
                }

                let maxProbability = 0;
                if (action.probability > maxProbability) {
                    maxProbability = action.probability;
                }

                this._lastElementWithAIFEXStyle.add(htmlElement);
                htmlElement.setAttribute("aifex_style", "true");
                if (maxProbability > WARM_COLOR_THRESHOLD) {
                    htmlElement.setAttribute("aifex_frequency", "often")
                } else if (maxProbability > MEDIUM_COLOL_THRESHOLD) {
                    htmlElement.setAttribute("aifex_frequency", "sometimes")
                } else if (maxProbability > COLD_COLOR_THRESHOLD) {
                    htmlElement.setAttribute("aifex_frequency", "rarely")
                } else {
                    htmlElement.setAttribute("aifex_frequency", "never")
                }
            }
        }
    }

    hide(): void {
        const domElements = querySelectorAllDeep("[aifex_style]")
        for (const domElement of domElements) {
            domElement.removeAttribute("aifex_frequency");
            domElement.removeAttribute("aifex_style");
        }
    }

    private attachStyleSheet(parentNode : HTMLElement): void {
        const nodeChilds: Element[] = Array.from(parentNode.children);
        if (nodeChilds.some(node => node.hasAttribute("aifex_stylesheet"))) {
            return;
        }
        if (this.stylesheetElement) {
            parentNode.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);
            parentNode.appendChild(this.stylesheetElement);
        }
    }

}