import * as i0 from '@angular/core';
import { Component, Input, NgModule, inject, ElementRef, Renderer2, Directive } from '@angular/core';
import * as i1 from '@angular/common';
import { CommonModule } from '@angular/common';
import * as i2 from '@seniorsistemas/angular-components/tooltip';
import { TooltipModule } from '@seniorsistemas/angular-components/tooltip';
import { TranslateService } from '@ngx-translate/core';

var EnumSeverity;
(function (EnumSeverity) {
    EnumSeverity["Default"] = "default";
    EnumSeverity["Info"] = "info";
    EnumSeverity["Warn"] = "warn";
    EnumSeverity["Error"] = "error";
    EnumSeverity["Success"] = "success";
})(EnumSeverity || (EnumSeverity = {}));

/**
 * @description Botão com borda que varia de estilo de acordo com a severidade informada.
 * Utilizado internamente por outros componentes da biblioteca.
 *
 * @category Shared
 */
class BorderButtonComponent {
    /** @description Nível de severidade que define a cor e estilo do botão. @default 'default' */
    severity = 'default';
    /** @description Opções de configuração do botão (rótulo, ação, etc.). */
    options;
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: BorderButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
    static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: BorderButtonComponent, selector: "s-border-button", inputs: { severity: "severity", options: "options" }, ngImport: i0, template: "<button\n    class=\"border-button\"\n    [ngClass]=\"{\n        'border-button--severity-default': severity === 'default',\n        'border-button--severity-info': severity === 'info',\n        'border-button--severity-warn': severity === 'warn',\n        'border-button--severity-error': severity === 'error',\n        'border-button--severity-success': severity === 'success',\n        'border-button--disabled': options?.disabled ? options?.disabled(severity) : false,\n    }\"\n    (click)=\"options?.onClick ? options?.onClick(severity) : null\"\n    [sTooltip]=\"options?.tooltip?.(severity)\"\n    tooltipPosition=\"left\"\n    [disabled]=\"options?.disabled ? options?.disabled(severity) : false\"\n>\n    <span class=\"border-button__label\">\n        {{ options?.label ? options?.label(severity) : null }}\n    </span>\n    @if (options?.icon ? options?.icon(severity) : false) {\n        <span class=\"border-button__icon {{ options?.icon(severity) }}\"></span>\n    }\n</button>\n", styles: [".border-button{padding:0 8px;border:1px solid;border-radius:12px;height:23px;max-width:320px;display:flex;justify-content:center;align-items:center;cursor:pointer}.border-button__label{font-family:Open Sans,sans-serif;font-size:12px;line-height:150%;width:100%;display:block;color:#333;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.border-button__icon{font-size:12px;color:#333;margin-left:8px}.border-button--severity-default{border-color:#ccc;background-color:#fff}.border-button--severity-info{border-color:#428bca;background-color:#d5e8ec;transition:background-color .5s ease,border-color .5s ease}.border-button--severity-info:enabled:hover{background-color:#9ecad4;cursor:pointer}.border-button--severity-info:enabled:active{transition:none;background-color:#67acbc;border-color:#67acbc}.border-button--severity-warn{border-color:#f8931f;background-color:#fce3ba;transition:background-color .5s ease,border-color .5s ease}.border-button--severity-warn:enabled:hover{background-color:#f8bf5e;cursor:pointer}.border-button--severity-warn:enabled:active{transition:none;background-color:#f5a319;border-color:#f5a319}.border-button--severity-error{border-color:#c13018;background-color:#fcd2d2;transition:background-color .5s ease,border-color .5s ease}.border-button--severity-error:enabled:hover{background-color:#f89696;cursor:pointer}.border-button--severity-error:enabled:active{transition:none;background-color:#f45b5b;border-color:#f45b5b}.border-button--severity-success{border-color:#0c9348;background-color:#e6ffb3;transition:background-color .5s ease,border-color .5s ease}.border-button--severity-success:enabled:hover{background-color:#c8ff5c;cursor:pointer}.border-button--severity-success:enabled:active{transition:none;background-color:#ade500;border-color:#ade500}.border-button--disabled:disabled:hover{cursor:default}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.TooltipDirective, selector: "[sTooltip]", inputs: ["sTooltip", "tooltipPosition", "showDelay", "displayTime", "tooltipEvent", "escape", "visible", "mobileBehavior", "focusedInputRef", "checkTruncatedText"] }] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: BorderButtonComponent, decorators: [{
            type: Component,
            args: [{ selector: 's-border-button', template: "<button\n    class=\"border-button\"\n    [ngClass]=\"{\n        'border-button--severity-default': severity === 'default',\n        'border-button--severity-info': severity === 'info',\n        'border-button--severity-warn': severity === 'warn',\n        'border-button--severity-error': severity === 'error',\n        'border-button--severity-success': severity === 'success',\n        'border-button--disabled': options?.disabled ? options?.disabled(severity) : false,\n    }\"\n    (click)=\"options?.onClick ? options?.onClick(severity) : null\"\n    [sTooltip]=\"options?.tooltip?.(severity)\"\n    tooltipPosition=\"left\"\n    [disabled]=\"options?.disabled ? options?.disabled(severity) : false\"\n>\n    <span class=\"border-button__label\">\n        {{ options?.label ? options?.label(severity) : null }}\n    </span>\n    @if (options?.icon ? options?.icon(severity) : false) {\n        <span class=\"border-button__icon {{ options?.icon(severity) }}\"></span>\n    }\n</button>\n", styles: [".border-button{padding:0 8px;border:1px solid;border-radius:12px;height:23px;max-width:320px;display:flex;justify-content:center;align-items:center;cursor:pointer}.border-button__label{font-family:Open Sans,sans-serif;font-size:12px;line-height:150%;width:100%;display:block;color:#333;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.border-button__icon{font-size:12px;color:#333;margin-left:8px}.border-button--severity-default{border-color:#ccc;background-color:#fff}.border-button--severity-info{border-color:#428bca;background-color:#d5e8ec;transition:background-color .5s ease,border-color .5s ease}.border-button--severity-info:enabled:hover{background-color:#9ecad4;cursor:pointer}.border-button--severity-info:enabled:active{transition:none;background-color:#67acbc;border-color:#67acbc}.border-button--severity-warn{border-color:#f8931f;background-color:#fce3ba;transition:background-color .5s ease,border-color .5s ease}.border-button--severity-warn:enabled:hover{background-color:#f8bf5e;cursor:pointer}.border-button--severity-warn:enabled:active{transition:none;background-color:#f5a319;border-color:#f5a319}.border-button--severity-error{border-color:#c13018;background-color:#fcd2d2;transition:background-color .5s ease,border-color .5s ease}.border-button--severity-error:enabled:hover{background-color:#f89696;cursor:pointer}.border-button--severity-error:enabled:active{transition:none;background-color:#f45b5b;border-color:#f45b5b}.border-button--severity-success{border-color:#0c9348;background-color:#e6ffb3;transition:background-color .5s ease,border-color .5s ease}.border-button--severity-success:enabled:hover{background-color:#c8ff5c;cursor:pointer}.border-button--severity-success:enabled:active{transition:none;background-color:#ade500;border-color:#ade500}.border-button--disabled:disabled:hover{cursor:default}\n"] }]
        }], propDecorators: { severity: [{
                type: Input
            }], options: [{
                type: Input
            }] } });

class BorderButtonModule {
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: BorderButtonModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
    static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "18.2.14", ngImport: i0, type: BorderButtonModule, declarations: [BorderButtonComponent], imports: [CommonModule, TooltipModule], exports: [BorderButtonComponent] });
    static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: BorderButtonModule, imports: [CommonModule, TooltipModule] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: BorderButtonModule, decorators: [{
            type: NgModule,
            args: [{
                    imports: [CommonModule, TooltipModule],
                    declarations: [BorderButtonComponent],
                    exports: [BorderButtonComponent]
                }]
        }] });

/**
 * A decorator that can be used to disable functions based on a boolean property on the component.
 *
 * @param disabledField The name of the boolean property that will be used to determine if the decorated
 * function should be disabled. Defaults to 'disabled'.
 * @returns A decorator function that can be used to decorate a function.
 *
 * @example
 * class MyComponent {
 *   disabled = true;
 *
 *   @CheckDisabled()
 *   onClick() {
 *     console.log('Button was clicked');
 *   }
 * }
 */
function CheckDisabled(disabledField = 'disabled') {
    return function (_target, _propertyKey, descriptor) {
        const originalMethod = descriptor.value;
        descriptor.value = function (...args) {
            const self = this;
            if (self[disabledField]) {
                return;
            }
            return originalMethod.apply(this, args);
        };
        return descriptor;
    };
}

/**
 * Diretiva para melhorar a acessibilidade dos botões do paginador PrimeNG
 * Adiciona tabindex="0" aos botões habilitados e tabindex="-1" aos desabilitados
 * Adiciona aria-labels traduzidos para os botões do paginador
 */
class PaginatorAccessibilityDirective {
    el = inject(ElementRef);
    renderer = inject(Renderer2);
    translateService = inject(TranslateService);
    observer = null;
    equalWebSpanMarker = 'data-equalweb-sr-only';
    isObserverPaused = false;
    observedPaginatorElement = null;
    ngOnInit() {
        // Aguarda o próximo ciclo para garantir que o paginador foi renderizado
        setTimeout(() => {
            this.updatePaginatorButtons();
            this.observePaginatorChanges();
        });
    }
    ngOnDestroy() {
        if (this.observer) {
            this.observer.disconnect();
        }
    }
    updatePaginatorButtons() {
        const paginatorElement = this.el.nativeElement.querySelector('p-paginator');
        if (!paginatorElement) {
            return;
        }
        // Atualiza botões de navegação (first, prev, next, last)
        const navigationSelectors = {
            '.p-paginator-first': this.translateService.instant('platform.angular_components.aria_first_page'),
            '.p-paginator-prev': this.translateService.instant('platform.angular_components.aria_previous_page'),
            '.p-paginator-next': this.translateService.instant('platform.angular_components.aria_next_page'),
            '.p-paginator-last': this.translateService.instant('platform.angular_components.aria_last_page'),
            '.p-select-label': this.translateService.instant('platform.angular_components.aria_page_selection')
        };
        Object.entries(navigationSelectors).forEach(([selector, label]) => {
            const button = paginatorElement.querySelector(selector);
            if (button) {
                const isDisabled = this.isButtonDisabled(button);
                this.updateTabIndex(button, isDisabled);
                if (isDisabled) {
                    this.renderer.removeAttribute(button, 'data-ind-readable');
                }
                else {
                    this.renderer.setAttribute(button, 'data-ind-readable', 'true');
                }
                this.renderer.setAttribute(button, 'aria-label', label);
                this.applyEqualWebTextFix(button, label, isDisabled);
            }
        });
        // Atualiza botões de página numérica
        const pageButtons = paginatorElement.querySelectorAll('.p-paginator-page');
        pageButtons.forEach((button) => {
            const pageNumber = this.getPaginatorPageNumber(button);
            if (pageNumber) {
                const isDisabled = this.isButtonDisabled(button);
                const isSelected = button.classList.contains('p-paginator-page-selected');
                const ariaLabel = isSelected
                    ? this.translateService.instant('platform.angular_components.aria_current_page', { page: pageNumber })
                    : this.translateService.instant('platform.angular_components.aria_page_number', { page: pageNumber });
                this.renderer.setAttribute(button, 'aria-label', ariaLabel);
                this.updateTabIndex(button, isDisabled);
                this.applyEqualWebTextFix(button, ariaLabel, isDisabled);
                if (isSelected) {
                    this.renderer.setAttribute(button, 'aria-current', 'page');
                }
                else {
                    this.renderer.removeAttribute(button, 'aria-current');
                }
            }
        });
    }
    isButtonDisabled(button) {
        return button.hasAttribute('disabled') || button.classList.contains('p-disabled');
    }
    updateTabIndex(button, isDisabled) {
        if (isDisabled) {
            this.renderer.removeAttribute(button, 'tabindex');
            return;
        }
        this.renderer.setAttribute(button, 'tabindex', '0');
    }
    getPaginatorPageNumber(button) {
        const buttonElement = button;
        // Evita pegar texto do span sr-only criado pela diretiva.
        const visualLabel = buttonElement.querySelector(`span:not([${this.equalWebSpanMarker}])`);
        const visualText = visualLabel?.textContent?.trim();
        if (visualText) {
            return visualText;
        }
        // Fallback para casos em que o PrimeNG renderiza sem span interno.
        const srOnlyText = buttonElement.querySelector(`span[${this.equalWebSpanMarker}="true"]`)?.textContent?.trim() || '';
        const fullText = buttonElement.textContent?.trim() || '';
        return fullText.replace(srOnlyText, '').trim();
    }
    applyEqualWebTextFix(button, accessibleText, isDisabled) {
        const buttonElement = button;
        // Oculta spans visuais do PrimeNG para o script do EqualWeb.
        const visualSpans = buttonElement.querySelectorAll(`span:not([${this.equalWebSpanMarker}])`);
        visualSpans.forEach((span) => {
            this.renderer.setAttribute(span, 'aria-hidden', 'true');
        });
        const existingSrOnly = buttonElement.querySelector(`span[${this.equalWebSpanMarker}="true"]`);
        // Não mantém texto extra em botões desabilitados.
        if (isDisabled) {
            if (existingSrOnly) {
                this.renderer.removeChild(buttonElement, existingSrOnly);
            }
            return;
        }
        if (existingSrOnly) {
            this.renderer.removeAttribute(existingSrOnly, 'tabindex');
            this.renderer.setProperty(existingSrOnly, 'textContent', accessibleText);
            return;
        }
        const srOnlySpan = this.renderer.createElement('span');
        this.renderer.addClass(srOnlySpan, 'sr-only');
        this.renderer.setAttribute(srOnlySpan, this.equalWebSpanMarker, 'true');
        this.renderer.removeAttribute(srOnlySpan, 'tabindex');
        const srOnlyText = this.renderer.createText(accessibleText);
        this.renderer.appendChild(srOnlySpan, srOnlyText);
        this.renderer.appendChild(buttonElement, srOnlySpan);
    }
    observePaginatorChanges() {
        const paginatorElement = this.el.nativeElement.querySelector('p-paginator');
        if (!paginatorElement) {
            return;
        }
        this.observedPaginatorElement = paginatorElement;
        // Observa mudanças no paginador (quando botões são habilitados/desabilitados)
        this.observer = new MutationObserver(() => {
            this.updateWithObserverPaused();
        });
        this.startObserving();
    }
    updateWithObserverPaused() {
        if (!this.observer || this.isObserverPaused) {
            return;
        }
        this.isObserverPaused = true;
        this.observer.disconnect();
        try {
            this.updatePaginatorButtons();
        }
        finally {
            this.startObserving();
            this.isObserverPaused = false;
        }
    }
    startObserving() {
        if (!this.observer || !this.observedPaginatorElement) {
            return;
        }
        this.observer.observe(this.observedPaginatorElement, {
            attributes: true,
            childList: true,
            subtree: true,
            attributeFilter: ['disabled', 'class', 'tabindex']
        });
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: PaginatorAccessibilityDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
    static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.14", type: PaginatorAccessibilityDirective, isStandalone: true, selector: "[sPaginatorAccessibility]", ngImport: i0 });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: PaginatorAccessibilityDirective, decorators: [{
            type: Directive,
            args: [{
                    selector: '[sPaginatorAccessibility]',
                    standalone: true
                }]
        }] });

/**
 * Diretiva para corrigir a acessibilidade de checkboxes em tabelas PrimeNG.
 *
 * Propaga o `aria-label` dos custom elements wrapper (`p-tablecheckbox` e
 * `p-tableheadercheckbox`) para os `<input type="checkbox">` internos e
 * remove o atributo do wrapper, eliminando as violações WCAG 4.1.2:
 * - `label` (crítica): input sem nome acessível
 * - `aria-prohibited-attr` (séria): aria-label em custom element sem role ARIA
 *
 * Remove também o `aria-label` do `p-checkbox` intermediário e monitora
 * mutations de atributo para re-aplicar o label correto caso o binding
 * interno do PrimeNG sobrescreva o valor no input via change detection.
 *
 * Utiliza MutationObserver para tratar linhas adicionadas dinamicamente
 * (paginação, lazy loading).
 *
 * Uso: `<p-table sTableCheckboxAccessibility ...>`
 */
class TableCheckboxAccessibilityDirective {
    el = inject(ElementRef);
    childListObserver = null;
    attributeObserver = null;
    isChildListPaused = false;
    isAttributePaused = false;
    observedElements = [];
    inputLabelMap = new Map();
    static CHECKBOX_SELECTOR = 'p-tablecheckbox, p-tableheadercheckbox';
    static INNER_CHECKBOX_SELECTOR = 'p-checkbox';
    static INPUT_SELECTOR = 'input[type="checkbox"]';
    static ARIA_LABEL_ATTR = 'aria-label';
    ngOnInit() {
        setTimeout(() => {
            this.updateCheckboxLabels();
            this.observeTableChanges();
        });
    }
    ngOnDestroy() {
        this.childListObserver?.disconnect();
        this.attributeObserver?.disconnect();
        this.inputLabelMap.clear();
    }
    updateCheckboxLabels() {
        const host = this.el.nativeElement;
        const checkboxWrappers = host.querySelectorAll(TableCheckboxAccessibilityDirective.CHECKBOX_SELECTOR);
        checkboxWrappers.forEach((wrapper) => {
            const wrapperAriaLabel = wrapper.getAttribute(TableCheckboxAccessibilityDirective.ARIA_LABEL_ATTR);
            if (!wrapperAriaLabel?.trim()) {
                return;
            }
            const input = wrapper.querySelector(TableCheckboxAccessibilityDirective.INPUT_SELECTOR);
            if (!input) {
                return;
            }
            this.applyLabelToInput(input, wrapperAriaLabel);
            wrapper.removeAttribute(TableCheckboxAccessibilityDirective.ARIA_LABEL_ATTR);
            this.removeInnerCheckboxAriaLabel(wrapper);
        });
    }
    applyLabelToInput(input, label) {
        this.inputLabelMap.set(input, label);
        input.setAttribute(TableCheckboxAccessibilityDirective.ARIA_LABEL_ATTR, label);
    }
    removeInnerCheckboxAriaLabel(wrapper) {
        const innerCheckbox = wrapper.querySelector(TableCheckboxAccessibilityDirective.INNER_CHECKBOX_SELECTOR);
        if (innerCheckbox) {
            innerCheckbox.removeAttribute(TableCheckboxAccessibilityDirective.ARIA_LABEL_ATTR);
        }
    }
    observeTableChanges() {
        const host = this.el.nativeElement;
        const tbody = host.querySelector('tbody');
        const thead = host.querySelector('thead');
        if (tbody) {
            this.observedElements.push(tbody);
        }
        if (thead) {
            this.observedElements.push(thead);
        }
        if (this.observedElements.length === 0) {
            return;
        }
        this.childListObserver = new MutationObserver(() => {
            this.handleChildListMutation();
        });
        this.attributeObserver = new MutationObserver((mutations) => {
            this.handleAttributeMutations(mutations);
        });
        this.startObserving();
    }
    handleAttributeMutations(mutations) {
        if (this.isAttributePaused) {
            return;
        }
        this.isAttributePaused = true;
        try {
            mutations
                .filter((m) => m.attributeName === TableCheckboxAccessibilityDirective.ARIA_LABEL_ATTR)
                .forEach((mutation) => {
                const target = mutation.target;
                const tagName = target.tagName?.toLowerCase();
                if (tagName === 'p-checkbox') {
                    target.removeAttribute(TableCheckboxAccessibilityDirective.ARIA_LABEL_ATTR);
                }
                else if (tagName === 'input') {
                    this.enforceInputLabel(target);
                }
                else {
                    // Outros elementos não precisam de tratamento
                }
            });
        }
        finally {
            this.isAttributePaused = false;
        }
    }
    enforceInputLabel(input) {
        const correctLabel = this.inputLabelMap.get(input);
        if (!correctLabel) {
            return;
        }
        const currentLabel = input.getAttribute(TableCheckboxAccessibilityDirective.ARIA_LABEL_ATTR);
        if (currentLabel !== correctLabel) {
            input.setAttribute(TableCheckboxAccessibilityDirective.ARIA_LABEL_ATTR, correctLabel);
        }
    }
    handleChildListMutation() {
        if (!this.childListObserver || this.isChildListPaused) {
            return;
        }
        this.isChildListPaused = true;
        this.childListObserver.disconnect();
        try {
            this.updateCheckboxLabels();
        }
        finally {
            this.startObserving();
            this.isChildListPaused = false;
        }
    }
    startObserving() {
        const { childListObserver, attributeObserver, observedElements } = this;
        if (!childListObserver) {
            return;
        }
        observedElements.forEach((element) => {
            childListObserver.observe(element, {
                childList: true,
                subtree: true,
            });
            if (attributeObserver) {
                attributeObserver.observe(element, {
                    attributes: true,
                    subtree: true,
                    attributeFilter: [TableCheckboxAccessibilityDirective.ARIA_LABEL_ATTR],
                });
            }
        });
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: TableCheckboxAccessibilityDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
    static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.14", type: TableCheckboxAccessibilityDirective, isStandalone: true, selector: "[sTableCheckboxAccessibility]", ngImport: i0 });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: TableCheckboxAccessibilityDirective, decorators: [{
            type: Directive,
            args: [{
                    selector: '[sTableCheckboxAccessibility]',
                    standalone: true,
                }]
        }] });

/**
 * Generated bundle index. Do not edit.
 */

export { BorderButtonComponent, BorderButtonModule, CheckDisabled, EnumSeverity, PaginatorAccessibilityDirective, TableCheckboxAccessibilityDirective };
//# sourceMappingURL=seniorsistemas-angular-components-shared.mjs.map
