import { LasalRuntimeSigElement, SigPolymer } from '../../sigmatek/sig-element/sig-element.js';
import "../sig-control-input/sig-control-input.js";
import "../sig-control-button/sig-control-button.js";
import "../sig-control-input/sig-control-input-css.js";
import "../sig-control-button/sig-control-button-css.js";

export class ListviewAgStandardFilter extends LasalRuntimeSigElement {

    static get is() {
        return "sig-control-listview-ag-filter";
    }

    static get importMeta() {
        return import.meta;
    }

    constructor() {
        super();
        this.valueGetter = null;
        this.filterObj = { value: '' };
        this.filterChangedCallback = null;
        this.filterOptionsDefaults = { type: "alpha" };
        this.filterOptions = null;
        this.gridApi = null;
        this.parent = null;
        this.column = '';
        this.hidePopup = null;
        this.firstRenderDone = false;
        this.button = null;
        this.input = null;
        this.scalefilter = false;
        this.preventCloseDelay = 250;
        this.runtimeEvtID = null;

        this.windowApi = (window.sigApi && window.sigApi.windowManager) ? window.sigApi.windowManager : null;
        this.defaultStylingApi = (window.sigApi && window.sigApi.defaultStyleManager) ? window.sigApi.defaultStyleManager : null;
        this.keyboardApi = (window.sigApi && window.sigApi.keyboard) ? window.sigApi.keyboard : null;

        this.removeFilterHandler = (evt) => {
            if (evt.detail.sourceEvent && typeof evt.detail.sourceEvent.stopPropagation === 'function')
                evt.detail.sourceEvent.stopPropagation();
            evt.stopPropagation();
            this.filterObj.value = '';
            if (this.input) this.input.value = '';
            this.filterChangedCallback();
        };

        this.windowClosedHandler = (evt) => {
            if (evt.detail) {
                const closedWindow = document.getElementById(evt.detail);
                if (closedWindow instanceof HTMLElement &&
                    closedWindow.slot !== 'keyboard' &&
                    typeof this.hidePopup === 'function') {
                    this.hidePopup();
                }
            }
        };

        this.keyboardOpenHandler = () => {
            if (this.input.iskeyboardopen)
                this.parent.sigApp.classList.add('ag-custom-component-popup');
        };

        this.keyboardClosedHandler = () => {
            this.sigSetTimeout(() => {
                this.parent.sigApp.classList.remove('ag-custom-component-popup');
            }, this.preventCloseDelay);
        };
    }

    static get template() {
        return SigPolymer.html`
        <style include="sig-element-css sig-control-input-css sig-control-button-css">
        :host([isdesignmode]) {
            position: absolute;
        }

        :host {
            
            display: block;
            overflow:hidden;
            height: var(--theme-sig-element-height, 60px);
            width: var(--theme-sig-element-width, 150px);
            padding: 5px;
            background-color: var(--theme-sig-control-listview-ag-filter-background-color, rgba(255,255,255,1));
            border-width: var(--theme-sig-control-listview-ag-filter-border-width, 0px);
            border-color: var(--theme-sig-control-listview-ag-filter-border-color, transparent);
            border-style: var(--theme-sig-control-listview-ag-filter-border-style, none);
        }

        :host * {
            
            @apply --notextselect;
            margin: 0;
            padding: 0;
        }

        .clearfix:after {
            @apply --clearfix
        }

        #filterWrapper {
            position: relative;
            width: 100%;
            height: 100%;
        }

        #button, #input {
            position: initial;
            display:block;
            height: var(--theme-sig-element-height, 20px);
            width:100%;
        }

        #button {
            margin-top:5px;
        }
    </style>
    <div id="filterWrapper">
        <sig-control-input id='input' class="input"></sig-control-input>
        <sig-control-button id='button' on-tap="_updateFilter" class="button"></sig-control-button>
    </div>
           `;
    }

    ready() {
        super.ready();
        if (this.isdesignmode) {
            this.shadowRoot.querySelector("#button").sigbtntext = 'Filter';
        }
    }

    init(params) {
        this.valueGetter = params.valueGetter;
        this.filterChangedCallback = params.filterChangedCallback;
        this.filterOptions = Object.assign(this.filterOptionsDefaults, params.options);
        this.gridApi = params.api;
        this.parent = params.context.parent;
        this.column = params.column;
        this.filterIcon = this.parent.shadowRoot.querySelector(`div[col-id="${this.column.colId}"] span[ref="eFilter"]`);
        this.sigApp = document.querySelector('sig-app');

        if (this.isMobile()) {
            this.parent.sigAddEventListener('touchend', this.removeFilterHandler, 'jsEvent', this.filterIcon);
            this.runtimeEvtID = this.parent.sigAddEventListener('SYSWIN_KEYBOARD_CLOSE', this.keyboardClosedHandler, 'runtimeEvent');
        } else {
            this.parent.sigAddEventListener('tap', this.removeFilterHandler, 'polymerEvent', this.filterIcon);
        }

        this.parent.sigAddEventListener('jspanelclosed', this.windowClosedHandler, 'jsEvent', document);
    }

    getGui() {
        return this;
    }

    _updateFilter() {
        this.filterObj.value = this.input.value;
        this.filterChangedCallback();
        this.hidePopup();
        this.hidePopup = null;
    };

    async afterGuiAttached(params) {
        const filterStyleClass = this.defaultStylingApi.getStyleClassByPropName(this.parent.id, this.tagName.toLowerCase());
        const styling = this.defaultStylingApi.getStylingByClassName('sig-control-listview-ag-filter', filterStyleClass);
        const filterType = (styling.props.filtertype) ? styling.props.filtertype.value : 'keyboard';
        const headerName = (this.column && this.column.colDef && this.column.colDef.headerName) ? this.column.colDef.headerName : '';

        switch (filterType) {
            case 'window':
                params.hidePopup();
                this.windowApi.systemWindow_prompt(this.parent.texts.filterWindowTitle, `${this.parent.texts.filterFor} "${headerName}"`, '', 0).then(value => {
                    this.filterObj.value = value;
                    this.filterChangedCallback();
                }).catch((error) => {
                    this._log(error, 'ERROR');
                    return error;
                });
                break;
            case 'keyboard':
                params.hidePopup();
                this.keyboardApi.open(this.filterOptions.type, `${this.parent.texts.filterFor} "${headerName}"`, {
                    keyboardplaceholder: this.parent.texts.filterPlaceholder
                }, this.filterObj, 'value').then((value) => {
                    this.filterObj.value = value;
                    this.filterChangedCallback();
                }, () => { });
                break;
            default:
                this.hidePopup = params.hidePopup;


                if (window.sigApi && this.firstRenderDone && this.input) {
                    this.utilsApi = sigApi.sigUtils;
                    this.input.constApi = window.sigApi.SIG_CONST;
                    this.input.vmApi = window.sigApi.vm;
                    this.input.keyboardApi = window.sigApi.keyboard;
                    this.input.eventMediatorApi = window.sigApi.eventMediator;
                    this.input.eventsApi = window.sigApi.events;
                    this.input.propertiesApi = window.sigApi.properties;
                    this.input.datapointApi = window.sigApi.datapointManager;
                    this.input.unitApi = window.sigApi.unitManager;
                    this.input.app = document.getElementsByTagName('sig-app')[0];
                    this.input.__dpUnitObj = {};
                }

                if (styling && styling.props && !this.firstRenderDone) {
                    this._applyProperties(this, styling);

                    this.input = this.shadowRoot.querySelector("#input");
                    this.button = this.shadowRoot.querySelector("#button");
                    this.input.titletext = `${this.parent.texts.filterFor} "${headerName}"`;
                    this.button.sigbtntext = `${this.parent.texts.applyFilter}`;
                    this.input.type = this.filterOptions.type;

                    if (this.isMobile()) this.parent.sigAddEventListener('touchstart', this.keyboardOpenHandler, 'jsEvent', this.input);

                    this.firstRenderDone = true;
                }

                if (this.parentElement.parentElement && this.parentElement.parentElement.classList.contains('ag-menu')) {
                    this.parentElement.parentElement.style.borderWidth = "0px";
                }
                this.classList.remove('sig-element-not-ready');
                this._positionFilter();
        }
    }

    _positionFilter() {
        const filter = document.querySelector(".ag-popup-child");
        if (filter instanceof HTMLElement) {
            const filterComputedStyle = getComputedStyle(filter);

            const origPositionX = parseInt(filterComputedStyle.getPropertyValue('left'), 10);
            const origPositionY = parseInt(filterComputedStyle.getPropertyValue('top'), 10);
            const filterWidth = parseInt(filterComputedStyle.getPropertyValue('width'), 10);
            const filterHeight = parseInt(filterComputedStyle.getPropertyValue('height'), 10);

            const appScale = this.getScaleFactor(this.sigApp, 0);
            const componentScale = this.getScaleFactor(this.parent, 0);
            const pureScaleX = componentScale.x / appScale.x;
            const pureScaleY = componentScale.y / appScale.y;

            let scaledWidthDiff = 0, scaledHeightDiff = 0;
            if (this.scalefilter) {
                filter.style.transform += `scale( ${pureScaleX}, ${pureScaleY})`;
                scaledWidthDiff = (filterWidth - filterWidth * pureScaleX) / 2;
                scaledHeightDiff = (filterHeight - filterHeight * pureScaleY) / 2;
            }

            let posX, posY;
            posX = (origPositionX / appScale.x) - scaledWidthDiff;
            posY = (origPositionY / appScale.y) - scaledHeightDiff;

            if (posX + filterWidth - scaledWidthDiff > this.sigApp.clientWidth) {
                filter.style.right = -scaledWidthDiff + 'px';
                filter.style.left = 'initial';
            } else {
                filter.style.left = posX + 'px';
            }

            filter.style.top = posY + 'px';

            if (this.parent.context && this.parent.context.type === 'window') {
                const parentContext = document.getElementById(this.parent.context.instanceId);
                if (parentContext) filter.style.zIndex = parentContext.style.zIndex;
            }
        }
    }

    _applyProperties(node, properties = {}) {
        if (node instanceof HTMLElement) {
            if (properties.name)
                node.classList.add(properties.name);

            for (const prop in properties.props) {
                const value = properties.props[prop].value;

                switch (properties.props[prop].dest) {
                    case 1:
                        node[prop] = value;
                        break;
                    case 6:
                        this._applyFontObjectToNode(node, value);
                        break;
                    case 14:
                        if (prop !== 'elementMainClass') {
                            SigPolymer.afterNextRender(this, () => {
                                const shadowDomElement = node.shadowRoot.querySelector(prop);
                                if (shadowDomElement) {
                                    this._applyProperties(shadowDomElement, this.defaultStylingApi.getStylingByClassName(prop, value));
                                }
                            });
                        }
                        break;
                }
            };
        }
    }

    doesFilterPass(params) {
        let passed = true;
        this.filterObj.value.toLowerCase().split(' ').forEach((filterWord) => {
            const value = this.valueGetter(params);
            if (value && this._getTextContent(value.toString()).toLowerCase().indexOf(filterWord) < 0) {
                passed = false;
            }
        });
        return passed;
    }

    isFilterActive() {
        return this.filterObj.value != null && this.filterObj.value !== '';
    }

    getModel() {
        if (this.isFilterActive()) return { value: this.filterObj.value };
        return null;
    }

    setModel(model) {
        this.filterObj.value = model;
    }

    getModelAsString(model) {
        return this.filterObj.value;
    }

    destroy() {
        if (this.isMobile()) {
            if (this.filterIcon) this.parent.sigRemoveEventListener('touchend', this.removeFilterHandler, 'jsEvent', this.filterIcon);
            if (this.input) this.parent.sigRemoveEventListener('touchstart', this.keyboardOpenHandler, 'jsEvent', this.input);
            this.parent.sigRemoveEventListener('SYSWIN_KEYBOARD_CLOSE', this.runtimeEvtID, 'runtimeEvent');
        } else {
            if (this.filterIcon) this.parent.sigRemoveEventListener('tap', this.removeFilterHandler, 'polymerEvent', this.filterIcon);
        }
        this.parent.sigRemoveEventListener('jspanelclosed', this.windowClosedHandler, 'jsEvent', document);

        this.valueGetter = null;
        this.filterObj = { value: '' };
        this.filterChangedCallback = null;
        this.filterOptions = null;
        this.gridApi = null;
        this.parent = null;
        this.column = null;
        this.input = null;
        this.button = null;
        this.filterIcon = null;
        this.sigApp = null;
        this.firstRenderDone = false;
        this.hidePopup = null;
        this.button = null;

        this.defaultStylingApi = null;
        this.windowApi = null;
        this.keyboardApi = null;
        this.runtimeEvtID = null;
    }

    _getTextContent(html) {
        let textContent = '';
        if (typeof html === 'string') {
            const elm = document.createElement('div');
            elm.innerHTML = html;
            textContent = elm.textContent || elm.innerText || '';
        }
        return textContent;
    }
}
customElements.define(ListviewAgStandardFilter.is, ListviewAgStandardFilter);
