class GOVBRPlataformaDataGrid {
    /**
     * @type {HTMLElement}
     */
    grid;
    /**
     * @type {Record<string, any>}
     */
    userControl;

    /**
     * @param {HTMLElement} grid
     * @param {Record<string, any>} userControl
     */
    static autoAdaptaGrid(grid, userControl) {
        const instance = new GOVBRPlataformaDataGrid();
        instance.grid = grid;
        instance.userControl = userControl;
        instance.init();
    }

    /**
     * Inicía o recurso de cálculo automático de linhas
     */
    init() {
        setTimeout(() => {
            const caption = /** @type {HTMLElement} */ (this.grid?.parentElement?.parentElement?.parentElement?.querySelector('.PaginationBarCaption'));
            if (caption) {
                caption.style.display = 'none';
            }
        });
        setTimeout(() => {
            try {
                if (this.userControl.CALCULA_LINHAS_AUTOMATICA) {
                    GOVBR.logs.debug('Cálculo de linhas automáticas ativado.', this.grid);
                    this.grid.classList.add('govbr-grid-auto-ajusta');
                    /**
                     * @type {number}
                     */
                    let debouncer = null;
                    let alturaNova = 0;
                    const observer = new MutationObserver(function (mutations) {
                        mutations.forEach(function (mutation) {
                            if (mutation.type === 'attributes') {
                                const tg = /** @type {HTMLElement} */ (mutation.target);
                                const alturaAtual = parseInt(getComputedStyle(tg).minHeight);
                                alturaNova = parseInt(tg.style.getPropertyValue('min-height')) || 0;
                                if (!debouncer) {
                                    debouncer = setTimeout(() => {
                                        debouncer = null;
                                    }, 250);
                                    if (alturaNova > alturaAtual) {
                                        tg.style.setProperty('min-height', alturaNova + 'px', 'important');
                                    }
                                }
                            }
                        });
                    });
                    observer.observe(this.grid, {
                        attributes: true,
                    });

                    window.addEventListener('resize', () => {
                        this.fnCalculaLinhas();
                    });
                    this.fnCalculaLinhas();
                } else {
                    this.grid.classList.remove('govbr-grid-auto-ajusta');
                }
            } catch (ex) {
                console.error(ex);
            }

            if (this.userControl.CONSULTA_INICIA_ABERTA) {
                if (this.userControl?.doAtualizaConsultaTamanhoLinha) {
                    this.userControl.doAtualizaConsultaTamanhoLinha();
                } else {
                    GOVBR.logs.error('Função "doAtualizaConsultaTamanhoLinha" não foi configurada, certifique-se que a tela possui o patter corretamente aplicado.');
                }
            }
        }, 250);
    }

    /**
     * Realiza o cálculo da altura do grid e atualiza o estilo corretamente.
     */
    fnCalculaLinhas() {
        GOVBR.logs.debug('Realizando cálculo de linhas automáticas.');
        let reset = false;
        /**
         * @type {[HTMLElement, string, any, [HTMLElement, string][], boolean][]}
         */
        let tree = (function (el) {
            const acc = [];
            while (el.parentElement) {
                acc.push(el.parentElement);
                el = el.parentElement;
            }
            return acc;
        })(this.grid).map((el) => [
            el,
            el.style.display,
            getComputedStyle(el),
            /** @type {HTMLElement[]} */ (Array.from(el.parentElement?.children || []))
                .filter((child) => child != el)
                .map((child) => [
                    child,
                    child.style.display,
                ]),
            null,
        ]);
        tree = tree.map(([e, _, computed, siblings]) => {
            let display = computed.display;
            reset = false;
            if (display == 'none') {
                display = 'block';
                siblings.forEach(([e, _]) => (e.style.display = 'none'));
                reset = true;
            }
            e.style.display = display;
            return [e, _, computed, siblings, reset];
        });
        GOVBR.logs.debug('Tree: ', tree);
        const bBox = this.grid.getBoundingClientRect();
        const tamanhoCabecalho = this.grid.querySelector('thead')?.clientHeight || 0;
        const tamanhoRodape = 60;
        const margemInf = parseInt(getComputedStyle(document.querySelector('#LAYOUTMAINTABLE_MPAGE,#LAYOUTMAINTABLE')).getPropertyValue('padding-bottom')) + 10;
        GOVBR.logs.debug('Tamanho da Página: ', document.body.clientHeight);
        GOVBR.logs.debug('Superior do Data Grid: ', bBox.top);
        GOVBR.logs.debug('Tamanho do Cabeçalho da Tabela: ', tamanhoCabecalho);
        GOVBR.logs.debug('Tamanho do Rodapé da Tabela: ', tamanhoRodape);
        GOVBR.logs.debug('Margem Inferior: ', margemInf);
        let tamanhoBase = document.body.clientHeight - bBox.top - tamanhoCabecalho - tamanhoRodape - margemInf || 0;
        GOVBR.logs.debug('Tamanho final: ', tamanhoBase);
        this.userControl.NUMERO_LINHAS = Math.max(5, Math.floor(tamanhoBase / 31));
        GOVBR.logs.debug('Linhas: ', this.userControl.NUMERO_LINHAS);
        this.grid.style.setProperty('--altura-grid', tamanhoBase + (tamanhoCabecalho - 1) + 'px');
        tree.forEach(([e, display, _, siblings, reset]) => {
            e.style.display = display;
            if (reset) {
                siblings.forEach(([e, display]) => (e.style.display = display));
            }
        });
    }
}

export { GOVBRPlataformaDataGrid };
