import { GOVBRSuggest } from '../../../suggest/1.2.0/GOVBRSuggest.mjs';

/**
 * Webcomponent que permite criar dropdowns - select customizáveis.
 */
export class GOVBRInputSelect extends HTMLElement {
    /**
     * @type {GOVBRSuggest}
     */
    _suggest;

    constructor() {
        super();
        this._suggest = new GOVBRSuggest(this.parentElement || null);
        this._suggest.forcePosicaoX = 'inicio-apos';
    }

    connectedCallback() {
        const shadow = this.attachShadow({ mode: 'open' });

        setTimeout(async () => {
            await GOVBRPlataformaJS.importarStyleSheet('', 'custom-inputs/lista', '', 'GOVBRInputSelect', shadow);
            await GOVBRPlataformaJS.importarStyleSheet('', 'fontawesome', '6.5.1', 'css/all.min', shadow);

            const input = document.createElement('input');
            shadow.append(input);
            input.type = 'text';
            input.id = this.dataId;
            input.name = this.dataId;
            input.value = this.dataValor;
            input.classList.add('govbr-plataforma-input-select-campo');
            if (this.dataRequired) {
                input.required = true;
            }
            if (this.dataLeitura) {
                input.readOnly = true;
                input.addEventListener('click', (e) => e.preventDefault());
            }
            input.setAttribute('tabindex', '-1');

            const containerLista = this.montaContainerSelecao(input);
            /**
             * @type {HTMLElement}
             */
            let titulo;
            /**
             * @type {HTMLElement}
             */
            let dropdown;
            if (this.dataInline) {
                shadow.insertBefore(containerLista, input);
            } else {
                dropdown = document.createElement('div');
                dropdown.classList.add('govbr-plataforma-input-select-lista-dropdown');
                /**
                 * @type {HTMLElement}
                 */
                let suggest;
                if (this.dataLeitura) {
                    dropdown.classList.add('govbr-plataforma-input-select-lista-dropdown-leitura');
                } else {
                    dropdown.addEventListener('click', () => {
                        if (suggest) {
                            return;
                        }
                        suggest = this._suggest.abreSuggest(dropdown, () => {
                            suggest = null;
                        });
                        suggest.classList.add('govbr-plataforma-input-select-suggest-lista-dropdown');
                        suggest.append(containerLista);
                    });
                }

                titulo = document.createElement('span');
                titulo.classList.add('govbr-plataforma-input-select-lista-dropdown-titulo');
                if (!input.value) {
                    titulo.classList.add('govbr-plataforma-input-select-lista-dropdown-titulo-vazio');
                } else {
                    titulo.classList.remove('govbr-plataforma-input-select-lista-dropdown-titulo-vazio');
                }
                titulo.innerText = this.getTituloValor(input.value);
                dropdown.append(titulo);

                const icone = document.createElement('i');
                icone.classList.add('fa-solid');
                icone.classList.add('fa-chevron-down');
                dropdown.append(icone);

                shadow.insertBefore(dropdown, input);

                input.addEventListener('focus', () => {
                    if (this.dataInline) {
                        const item = /** @type {HTMLElement} */ (containerLista.querySelector('.govbr-plataforma-input-select-lista-container-item'));
                        item?.focus?.();
                    } else {
                        dropdown.dispatchEvent(new MouseEvent('click'));
                    }
                });
                input.addEventListener('blur', () => {
                    this._suggest.fechaSuggest();
                });
            }
            input.addEventListener('change', () => {
                if (titulo) {
                    if (!input.value) {
                        titulo.classList.add('govbr-plataforma-input-select-lista-dropdown-titulo-vazio');
                    } else {
                        titulo.classList.remove('govbr-plataforma-input-select-lista-dropdown-titulo-vazio');
                    }
                    titulo.innerText = this.getTituloValor(input.value);
                }
                this.atualizaContainerSelecao(containerLista);
                this.dispatchEvent(new Event('change'));
            });
            this.atualizaContainerSelecao(containerLista);
        }, 0);
    }

    /**
     * Monta o container para seleção dos itens.
     * @param {HTMLInputElement} input
     */
    montaContainerSelecao(input) {
        const container = document.createElement('ul');
        container.classList.add('govbr-plataforma-input-select-lista-container-itens');
        const lista = (this.dataLista || []).slice();
        if (this.dataMultiSelecao) {
            container.classList.add('govbr-plataforma-input-select-lista-container-multisselecao');
        } else {
            container.classList.add('govbr-plataforma-input-select-lista-container-simples');
            if (this.dataInline) {
                container.classList.add('govbr-plataforma-input-select-lista-container-radio');
            }
        }
        lista.forEach(({ valor, nome, html }) => {
            const li = document.createElement('li');
            li.classList.add('govbr-plataforma-input-select-lista-container-item');
            li.setAttribute('data-valor', valor);
            li.setAttribute('tabindex', '0');
            li.innerHTML = html;
            li.title = nome;
            const iconeSelecionado = document.createElement('i');
            iconeSelecionado.classList.add('govbr-plataforma-input-select-lista-container-icone-selecionado');
            iconeSelecionado.classList.add('fa-regular');
            const iconeDeselecionado = document.createElement('i');
            iconeDeselecionado.classList.add('govbr-plataforma-input-select-lista-container-icone-deselecionado');
            iconeDeselecionado.classList.add('fa-regular');
            if (this.dataMultiSelecao) {
                iconeSelecionado.classList.add('fa-square-check');
                iconeDeselecionado.classList.add('fa-square');
            } else {
                iconeSelecionado.classList.add('fa-circle-dot');
                iconeDeselecionado.classList.add('fa-circle');
            }
            li.addEventListener('click', () => {
                if (this.dataMultiSelecao) {
                    let valores;
                    try {
                        valores = JSON.parse(input.value || '[]');
                    } catch (ex) {
                        GOVBR.logs.error(ex);
                        valores = [];
                    }
                    const idx = valores.indexOf(valor);
                    if (idx > -1) {
                        valores.splice(idx, 1);
                    } else {
                        valores.push(valor);
                    }
                    input.value = JSON.stringify(valores);
                } else {
                    input.value = valor;
                    this._suggest.fechaSuggest();
                }
                this.dataValor = input.value;
                input.dispatchEvent(new Event('change'));
            });
            li.prepend(iconeSelecionado);
            li.prepend(iconeDeselecionado);
            container.append(li);
        });
        return container;
    }

    /**
     * Atualiza o(s) item(ns) selecionado(s) no container de itens.
     * @param {HTMLElement} container
     */
    atualizaContainerSelecao(container) {
        let valor = this.dataValor;
        /**
         * @type {string|string[]}
         */
        let valorObj = valor;
        if (this.dataMultiSelecao) {
            try {
                valorObj = JSON.parse(valor || '[]');
            } catch (ex) {
                GOVBR.logs.error(ex);
                valorObj = [];
            }
        }
        container.querySelectorAll('.govbr-plataforma-input-select-lista-container-item').forEach((item) => {
            const valorItem = item.getAttribute('data-valor');
            if (this.dataMultiSelecao) {
                if (valorObj.includes(valorItem)) {
                    item.classList.add('govbr-plataforma-input-select-lista-container-item-selecionado');
                } else {
                    item.classList.remove('govbr-plataforma-input-select-lista-container-item-selecionado');
                }
            } else if (valorObj === valorItem) {
                item.classList.add('govbr-plataforma-input-select-lista-container-item-selecionado');
            } else {
                item.classList.remove('govbr-plataforma-input-select-lista-container-item-selecionado');
            }
        });
    }

    /**
     * Retorna o título/nome a ser exibido para um valor.
     * @param {string} novoValor
     * @returns {string}
     */
    getTituloValor(novoValor) {
        if (this.dataMultiSelecao) {
            let valores;
            try {
                valores = JSON.parse(novoValor || '[]') || [];
            } catch (ex) {
                valores = [];
                GOVBR.logs.error(ex);
            }
            return (
                (this.dataLista || [])
                    .filter(({ valor }) => valores.includes(valor))
                    .map((e) => e.nome)
                    .join(', ') || 'Selecione...'
            );
        }
        return (this.dataLista || []).find(({ valor }) => valor === novoValor)?.nome || (novoValor ? '' : this.dataLista[0]?.nome || 'Selecione...');
    }

    get dataId() {
        return this.getAttribute('data-id');
    }
    get dataRequired() {
        return this.hasAttribute('data-required');
    }
    get dataLeitura() {
        return this.hasAttribute('data-leitura');
    }
    get dataInline() {
        return this.hasAttribute('data-inline');
    }
    get dataMultiSelecao() {
        return this.hasAttribute('data-multiselecao');
    }
    set dataValor(val) {
        this.setAttribute('data-valor', val);
        this.dispatchEvent(new Event('change'));
    }
    get dataValor() {
        if (!this.hasAttribute('data-valor')) {
            this.dataValor = (this.dataLista || [])[0]?.valor || '';
        }
        return this.getAttribute('data-valor');
    }

    get dataLista() {
        const itens = /** @type {GOVBRInputSelectItem[]} */ (Array.from(this.querySelectorAll(':scope > govbr-plataforma-input-select-item')));
        return itens.map((e) => {
            return {
                valor: e.dataValor,
                html: e.dataHtml,
                nome: e.dataNome,
            };
        });
    }
}

customElements.define('govbr-plataforma-input-select', GOVBRInputSelect);

export class GOVBRInputSelectItem extends HTMLElement {
    constructor() {
        super();
    }

    connectedCallback() {
        this.style.display = 'none';
    }

    get dataValor() {
        return this.getAttribute('data-valor') || '';
    }

    get dataHtml() {
        return this.hasAttribute('data-html') ? this.getAttribute('data-html') : this.innerHTML;
    }

    get dataNome() {
        return this.hasAttribute('data-nome') ? this.getAttribute('data-nome') : this.innerText.trim();
    }
}

customElements.define('govbr-plataforma-input-select-item', GOVBRInputSelectItem);
