import * as i0 from '@angular/core';
import { input, model, output, forwardRef, Directive, NgModule } from '@angular/core';
import { NG_VALUE_ACCESSOR } from '@angular/forms';
import { NumericMaskDirective } from '@seniorsistemas/angular-components/numeric-mask';
import { CommonModule } from '@angular/common';

/**
 * @deprecated Este enum não tem mais efeito. O alinhamento do campo é sempre `'right'`.
 */
var BignumberAlignmentOption;
(function (BignumberAlignmentOption) {
    BignumberAlignmentOption["RIGHT"] = "right";
    BignumberAlignmentOption["LEFT"] = "left";
})(BignumberAlignmentOption || (BignumberAlignmentOption = {}));
/**
 * @deprecated Utilize a diretiva `BigNumberInput` ao invés desta.
 * @description Diretiva de máscara para campos de entrada de números de grande precisão,
 * adaptada do `CurrencyMaskDirective`. Permite configurar precisão, escala,
 * separadores decimais e de milhar de acordo com o locale da aplicação.
 *
 * @example
 * ```html
 * <input sBignumberInput [precision]="15" [scale]="2" [allowNegative]="false" />
 * ```
 *
 * @category Inputs
 */
class BignumberInputDirective extends NumericMaskDirective {
    /**
     * @description Número total de dígitos significativos aceitos pelo campo (parte inteira + parte decimal).
     *
     * Durante a digitação, o campo limita fisicamente o número de caracteres via `maxLength`.
     * Ao colar um valor que ultrapasse o limite, o evento `pasteRejected` é emitido e a colagem é cancelada.
     * Após sair do campo (blur) ou ao submeter o formulário, se o valor ultrapassar `precision`,
     * o campo ficará inválido com o erro `exceedsPrecision: { precision, actual }`.
     *
     * @default 15
     */
    precision = input(15);
    /**
     * @deprecated Use `minDecimalPlaces` e `maxDecimalPlaces` ao invés deste.
     * @description Número de casas decimais exibidas e aceitas pelo campo.
     * Quando informado, repassa o valor para `minDecimalPlaces` e `maxDecimalPlaces`.
     *
     * @default 0
     */
    scale = input(0);
    /**
     * @description Número mínimo de casas decimais exibidas.
     *
     * @default 0
     */
    minDecimalPlaces = model(0);
    /**
     * @description Número máximo de casas decimais aceitas.
     *
     * @default 0
     */
    maxDecimalPlaces = model(0);
    /**
     * @description Separador decimal personalizado. Quando não informado,
     * utiliza o separador definido pelo locale ativo da aplicação.
     */
    decimalSeparator = model(',');
    /**
     * @deprecated Use `thousandSeparator` ao invés deste.
     * @description Separador de milhar personalizado. Recomenda-se migrar para `thousandSeparator`.
     */
    thousandsSeparator = input(undefined);
    /**
     * @description Separador de milhar personalizado. Quando não informado,
     * utiliza o separador definido pelo locale ativo da aplicação.
     */
    thousandSeparator = model('.');
    /**
     * @deprecated Este input não tem mais efeito e pode ser removido.
     * O alinhamento do campo é sempre `'right'`, conforme o comportamento padrão da máscara numérica.
     */
    alignTo = input('right');
    /**
     * @description Permite a entrada de valores negativos.
     *
     * @default true
     */
    allowNegative = input(true);
    /**
     * @description Texto de placeholder exibido quando o campo está vazio.
     */
    placeholder = model(undefined);
    maxLength;
    /**
     * @description Emitido quando uma colagem (paste) é rejeitada pela validação do campo.
     * Emite a string colada que foi recusada.
     */
    pasteRejected = output();
    _decimalSeparatorExplicit = false;
    _thousandSeparatorExplicit = false;
    constructor() {
        super();
    }
    ngOnInit() {
        super.ngOnInit();
        this.updatePlaceholder();
    }
    // ngOnChanges handles all signal writes reactively, avoiding the need for
    // effect() with allowSignalWrites. The decimalSeparator/thousandSeparator inputs
    // have truthy defaults, so ngOnChanges is necessary to distinguish "parent bound this"
    // from "it's just the default value".
    ngOnChanges(changes) {
        if (changes['decimalSeparator'] && this.decimalSeparator()) {
            this._decimalSeparatorExplicit = true;
        }
        if (changes['thousandSeparator'] && this.thousandSeparator()) {
            this._thousandSeparatorExplicit = true;
        }
        if (changes['thousandsSeparator']) {
            const val = this.thousandsSeparator();
            if (val !== undefined) {
                this._thousandSeparatorExplicit = true;
                this.thousandSeparator.set(val);
            }
        }
        if (changes['scale']) {
            this.minDecimalPlaces.set(this.scale());
            this.maxDecimalPlaces.set(this.scale());
        }
        if (changes['scale'] ||
            changes['decimalSeparator'] ||
            changes['thousandSeparator'] ||
            changes['thousandsSeparator'] ||
            changes['precision']) {
            this.calculateMaxLength();
        }
        if (changes['scale'] || changes['decimalSeparator']) {
            this.updatePlaceholder();
        }
    }
    /**
     * Overrides base paste handler to add precision validation.
     * If the pasted value exceeds `precision` digits, the paste is rejected.
     */
    onPaste(event) {
        const pastedText = event.clipboardData?.getData('text') ?? '';
        const effectiveThousandSep = this.thousandsSeparator() ?? this.thousandSeparator();
        const numericText = pastedText
            .replace(new RegExp(`\\${effectiveThousandSep}`, 'g'), '')
            .replace(this.decimalSeparator(), '.');
        const [intPart, decimalPart = ''] = numericText.split('.');
        const totalDigits = intPart.replace(/\D/g, '').length + decimalPart.slice(0, this.scale()).length;
        if (totalDigits > this.precision()) {
            event.preventDefault();
            this.pasteRejected.emit(pastedText);
            return;
        }
        super.onPaste(event);
    }
    /**
     * Overrides locale-derived separators with explicitly set inputs, if provided.
     * If no explicit separator is set, the locale-derived value is used.
     */
    updateSeparators() {
        const explicitDecimal = this._decimalSeparatorExplicit ? this.decimalSeparator() : undefined;
        const explicitThousand = this._thousandSeparatorExplicit
            ? (this.thousandsSeparator() ?? this.thousandSeparator())
            : undefined;
        super.updateSeparators();
        if (explicitDecimal !== undefined) {
            this.decimalSeparator.set(explicitDecimal);
        }
        if (explicitThousand !== undefined) {
            this.thousandSeparator.set(explicitThousand);
        }
        this.calculateMaxLength();
        this.updatePlaceholder();
    }
    /**
     * Overrides base validator to add precision validation.
     * If the total number of significant digits exceeds `precision`, returns an `exceedsPrecision` error.
     */
    validate(control) {
        const baseErrors = super.validate(control);
        if (!control.value || !this.precision()) {
            return baseErrors ?? null;
        }
        const numericStr = String(control.value).replace('-', '');
        const [intPart, decimalPart = ''] = numericStr.split('.');
        const totalDigits = intPart.length + decimalPart.length;
        if (totalDigits > this.precision()) {
            return {
                ...baseErrors,
                exceedsPrecision: {
                    precision: this.precision(),
                    actual: totalDigits,
                },
            };
        }
        return baseErrors ?? null;
    }
    /**
     * Responsible to calculate the field maximum length considering the separators.
     */
    calculateMaxLength() {
        const decSepLength = this.decimalSeparator()?.length ?? 0;
        const effectiveThousandSep = this.thousandsSeparator() ?? this.thousandSeparator();
        const thoSepLength = effectiveThousandSep?.length ?? 0;
        const DIGITS_GROUP_SIZE = 3;
        let maxLength = this.precision() + (this.scale() ? decSepLength : 0);
        maxLength +=
            Math.ceil((this.precision() - (this.scale() ? this.scale() : 0)) / DIGITS_GROUP_SIZE - 1) * thoSepLength;
        this.maxLength = maxLength;
    }
    updatePlaceholder() {
        const scale = this.scale();
        if (!this.placeholder() && scale) {
            this.placeholder.set(`0${this.decimalSeparator()}${''.padEnd(scale, '0')}`);
        }
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: BignumberInputDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
    static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "18.2.14", type: BignumberInputDirective, selector: "input[sBignumberInput]", inputs: { precision: { classPropertyName: "precision", publicName: "precision", isSignal: true, isRequired: false, transformFunction: null }, scale: { classPropertyName: "scale", publicName: "scale", isSignal: true, isRequired: false, transformFunction: null }, minDecimalPlaces: { classPropertyName: "minDecimalPlaces", publicName: "minDecimalPlaces", isSignal: true, isRequired: false, transformFunction: null }, maxDecimalPlaces: { classPropertyName: "maxDecimalPlaces", publicName: "maxDecimalPlaces", isSignal: true, isRequired: false, transformFunction: null }, decimalSeparator: { classPropertyName: "decimalSeparator", publicName: "decimalSeparator", isSignal: true, isRequired: false, transformFunction: null }, thousandsSeparator: { classPropertyName: "thousandsSeparator", publicName: "thousandsSeparator", isSignal: true, isRequired: false, transformFunction: null }, thousandSeparator: { classPropertyName: "thousandSeparator", publicName: "thousandSeparator", isSignal: true, isRequired: false, transformFunction: null }, alignTo: { classPropertyName: "alignTo", publicName: "alignTo", isSignal: true, isRequired: false, transformFunction: null }, allowNegative: { classPropertyName: "allowNegative", publicName: "allowNegative", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { minDecimalPlaces: "minDecimalPlacesChange", maxDecimalPlaces: "maxDecimalPlacesChange", decimalSeparator: "decimalSeparatorChange", thousandSeparator: "thousandSeparatorChange", placeholder: "placeholderChange", pasteRejected: "pasteRejected" }, host: { properties: { "attr.placeholder": "placeholder()", "attr.maxLength": "maxLength" } }, providers: [
            {
                provide: NG_VALUE_ACCESSOR,
                // NOSONAR - 'BignumberInputDirective' is deprecated.
                useExisting: forwardRef(() => BignumberInputDirective),
                multi: true,
            },
        ], usesInheritance: true, usesOnChanges: true, ngImport: i0 });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: BignumberInputDirective, decorators: [{
            type: Directive,
            args: [{
                    selector: 'input[sBignumberInput]',
                    host: {
                        '[attr.placeholder]': 'placeholder()',
                        '[attr.maxLength]': 'maxLength',
                    },
                    providers: [
                        {
                            provide: NG_VALUE_ACCESSOR,
                            // NOSONAR - 'BignumberInputDirective' is deprecated.
                            useExisting: forwardRef(() => BignumberInputDirective),
                            multi: true,
                        },
                    ],
                }]
        }], ctorParameters: () => [] });

class BignumberInputModule {
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: BignumberInputModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
    static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "18.2.14", ngImport: i0, type: BignumberInputModule, declarations: [BignumberInputDirective], imports: [CommonModule], exports: [BignumberInputDirective] });
    static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: BignumberInputModule, imports: [CommonModule] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: BignumberInputModule, decorators: [{
            type: NgModule,
            args: [{
                    imports: [CommonModule],
                    // NOSONAR - 'BignumberInputDirective' is deprecated.
                    declarations: [BignumberInputDirective],
                    // NOSONAR - 'BignumberInputDirective' is deprecated.
                    exports: [BignumberInputDirective],
                }]
        }] });

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

export { BignumberAlignmentOption, BignumberInputDirective, BignumberInputModule };
//# sourceMappingURL=seniorsistemas-angular-components-bignumber-input.mjs.map
