import * as i0 from '@angular/core';
import { inject, ElementRef, Renderer2, input, output, Directive, viewChildren, numberAttribute, booleanAttribute, computed, forwardRef, Component } from '@angular/core';
import * as i1 from '@angular/forms';
import { FormBuilder, Validators, ReactiveFormsModule, NG_VALUE_ACCESSOR } from '@angular/forms';
import { coerceBooleanProperty } from '@angular/cdk/coercion';
import { FormField } from '@ngstarter-ui/components/form-field';
import { Input } from '@ngstarter-ui/components/input';

class PinInputDirective {
    _elementRef = inject(ElementRef);
    _renderer = inject(Renderer2);
    _placeholder;
    index = input(...(ngDevMode ? [undefined, { debugName: "index" }] : /* istanbul ignore next */ []));
    acceptOnly = input(...(ngDevMode ? [undefined, { debugName: "acceptOnly" }] : /* istanbul ignore next */ []));
    valuePaste = output();
    get api() {
        return {
            focus: () => {
                this._elementRef.nativeElement.focus();
            },
            nativeElement: this._elementRef.nativeElement
        };
    }
    ngOnInit() {
        this._placeholder = this._elementRef.nativeElement.getAttribute('placeholder') || '';
    }
    _handleFocus() {
        this._renderer.removeAttribute(this._elementRef.nativeElement, 'placeholder');
    }
    _handleBlur() {
        this._renderer.setAttribute(this._elementRef.nativeElement, 'placeholder', this._placeholder);
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: PinInputDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
    static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.4", type: PinInputDirective, isStandalone: true, selector: "[ngsPinInput]", inputs: { index: { classPropertyName: "index", publicName: "index", isSignal: true, isRequired: false, transformFunction: null }, acceptOnly: { classPropertyName: "acceptOnly", publicName: "acceptOnly", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { valuePaste: "valuePaste" }, host: { listeners: { "focus": "_handleFocus()", "blur": "_handleBlur()" }, classAttribute: "ngs-pin-input" }, exportAs: ["ngsPinInput"], ngImport: i0 });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: PinInputDirective, decorators: [{
            type: Directive,
            args: [{
                    selector: '[ngsPinInput]',
                    exportAs: 'ngsPinInput',
                    host: {
                        'class': 'ngs-pin-input',
                        '(focus)': '_handleFocus()',
                        '(blur)': '_handleBlur()'
                    }
                }]
        }], propDecorators: { index: [{ type: i0.Input, args: [{ isSignal: true, alias: "index", required: false }] }], acceptOnly: [{ type: i0.Input, args: [{ isSignal: true, alias: "acceptOnly", required: false }] }], valuePaste: [{ type: i0.Output, args: ["valuePaste"] }] } });

class PinInput {
    _fb = inject(FormBuilder);
    inputs = viewChildren(PinInputDirective, ...(ngDevMode ? [{ debugName: "inputs" }] : /* istanbul ignore next */ []));
    length = input(4, { ...(ngDevMode ? { debugName: "length" } : /* istanbul ignore next */ {}), transform: numberAttribute });
    placeholder = input('', ...(ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []));
    acceptOnly = input(/^[0-9]+$/, ...(ngDevMode ? [{ debugName: "acceptOnly" }] : /* istanbul ignore next */ []));
    disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
    form;
    _disabled = false;
    isDisabled = computed(() => {
        return this._disabled || this.disabled();
    }, ...(ngDevMode ? [{ debugName: "isDisabled" }] : /* istanbul ignore next */ []));
    onChange = () => { };
    onTouched = () => { };
    get controls() {
        return this.form.get('value').controls;
    }
    ngOnInit() {
        const inputs = [];
        for (let i = 0; i < this.length(); i++) {
            inputs.push(this._fb.control({ value: '', disabled: this.disabled() }, [Validators.required]));
        }
        this.form = this._fb.group({
            value: this._fb.array(inputs)
        });
    }
    registerOnChange(fn) {
        this.onChange = fn;
    }
    registerOnTouched(fn) {
        this.onTouched = fn;
    }
    setDisabledState(isDisabled) {
        this._disabled = coerceBooleanProperty(isDisabled);
    }
    writeValue(value) {
        if (!value) {
            this.controls.forEach(control => {
                control.setValue('');
            });
            return;
        }
        value = String(value);
        for (let i = 0; i < value.length; i++) {
            const control = this.controls[i];
            if (control && value[i].match(this.acceptOnly)) {
                control.setValue(value[i]);
            }
        }
    }
    _valuePaste(event) {
        event.preventDefault();
        event.stopPropagation();
        // const value = event.clipboardData?.getData('text/plain');
    }
    _handleKeyDown(event) {
        if (event.key === 'ArrowRight' || event.key === 'ArrowLeft') {
            return;
        }
        if (event.key === 'Delete' || event.key === 'Backspace' || event.key === 'Tab') {
            const element = event.target;
            if (event.key === 'Backspace' && !element.value) {
                this.inputs().forEach((inputDirective, index) => {
                    const element = event.target;
                    if (inputDirective.api.nativeElement === element) {
                        const prevControl = this.inputs().at(index - 1);
                        if (prevControl) {
                            prevControl.api.focus();
                        }
                    }
                });
            }
            return;
        }
        event.preventDefault();
        event.stopPropagation();
    }
    _handleKeyUp(event) {
        if (event.key === 'ArrowRight' || event.key === 'ArrowLeft') {
            return;
        }
        if (event.key === 'Shift' || (event.keyCode >= 112 && event.keyCode <= 123)) {
            event.preventDefault();
            event.stopPropagation();
            return;
        }
        if (event.key === 'Delete' || event.key === 'Backspace' || event.key === 'Tab') {
            this.onChange(+this.form.value.value.join(''));
            return;
        }
        if (!event.key.match(this.acceptOnly())) {
            event.preventDefault();
            event.stopPropagation();
            return;
        }
        this.inputs().forEach((inputDirective, index) => {
            const element = event.target;
            if (inputDirective.api.nativeElement === element) {
                const control = this.controls[index];
                control.setValue(event.key);
                const nextControl = this.inputs().at(index + 1);
                if (nextControl) {
                    nextControl.api.focus();
                }
            }
        });
        this.onChange(+this.form.value.value.join(''));
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: PinInput, deps: [], target: i0.ɵɵFactoryTarget.Component });
    static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.4", type: PinInput, isStandalone: true, selector: "ngs-pin-input", inputs: { length: { classPropertyName: "length", publicName: "length", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, acceptOnly: { classPropertyName: "acceptOnly", publicName: "acceptOnly", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "paste": "_valuePaste($event)", "keydown": "_handleKeyDown($event)", "keyup": "_handleKeyUp($event)" }, properties: { "class.is-disabled": "isDisabled()" }, classAttribute: "ngs-pin-input" }, providers: [
            {
                provide: NG_VALUE_ACCESSOR,
                useExisting: forwardRef(() => PinInput),
                multi: true
            }
        ], viewQueries: [{ propertyName: "inputs", predicate: PinInputDirective, descendants: true, isSignal: true }], exportAs: ["ngsPinInput"], ngImport: i0, template: "<div [formGroup]=\"form\">\n  <div formArrayName=\"value\" class=\"inputs\">\n    @for (control of controls; track control) {\n      <ngs-form-field subscriptHiddenIfEmpty>\n        <input type=\"text\"\n               ngsInput\n               ngsPinInput\n               [formControl]=\"control\"\n               [acceptOnly]=\"acceptOnly()\"\n               [placeholder]=\"placeholder()\"\n               [attr.disabled]=\"isDisabled() || null\"\n               maxlength=\"1\" >\n      </ngs-form-field>\n    }\n  </div>\n</div>\n", styles: [":host{--ngs-pin-input-width: calc(var(--spacing, .25rem) * 14);--ngs-pin-gap: calc(var(--spacing, .25rem) * 4);--ngs-form-field-input-text-align: center;--ngs-form-field-width: var(--ngs-pin-input-width);display:block;width:max-content}:host .inputs{display:flex;align-items:center;gap:var(--ngs-pin-gap)}:host .input{flex:none}\n/*! tailwindcss v4.2.2 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormArrayName, selector: "[formArrayName]", inputs: ["formArrayName"] }, { kind: "component", type: FormField, selector: "ngs-form-field", inputs: ["subscriptHiddenIfEmpty"], exportAs: ["ngsFormField"] }, { kind: "directive", type: Input, selector: "input[ngsInput], textarea[ngsInput]", inputs: ["id", "placeholder", "required", "disabled", "readonly", "errorStateMatcher"], exportAs: ["ngsInput"] }, { kind: "directive", type: PinInputDirective, selector: "[ngsPinInput]", inputs: ["index", "acceptOnly"], outputs: ["valuePaste"], exportAs: ["ngsPinInput"] }] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: PinInput, decorators: [{
            type: Component,
            args: [{ selector: 'ngs-pin-input', exportAs: 'ngsPinInput', imports: [
                        ReactiveFormsModule,
                        FormField,
                        Input,
                        PinInputDirective
                    ], providers: [
                        {
                            provide: NG_VALUE_ACCESSOR,
                            useExisting: forwardRef(() => PinInput),
                            multi: true
                        }
                    ], host: {
                        'class': 'ngs-pin-input',
                        '[class.is-disabled]': 'isDisabled()',
                        '(paste)': '_valuePaste($event)',
                        '(keydown)': '_handleKeyDown($event)',
                        '(keyup)': '_handleKeyUp($event)',
                    }, template: "<div [formGroup]=\"form\">\n  <div formArrayName=\"value\" class=\"inputs\">\n    @for (control of controls; track control) {\n      <ngs-form-field subscriptHiddenIfEmpty>\n        <input type=\"text\"\n               ngsInput\n               ngsPinInput\n               [formControl]=\"control\"\n               [acceptOnly]=\"acceptOnly()\"\n               [placeholder]=\"placeholder()\"\n               [attr.disabled]=\"isDisabled() || null\"\n               maxlength=\"1\" >\n      </ngs-form-field>\n    }\n  </div>\n</div>\n", styles: [":host{--ngs-pin-input-width: calc(var(--spacing, .25rem) * 14);--ngs-pin-gap: calc(var(--spacing, .25rem) * 4);--ngs-form-field-input-text-align: center;--ngs-form-field-width: var(--ngs-pin-input-width);display:block;width:max-content}:host .inputs{display:flex;align-items:center;gap:var(--ngs-pin-gap)}:host .input{flex:none}\n/*! tailwindcss v4.2.2 | MIT License | https://tailwindcss.com */\n"] }]
        }], propDecorators: { inputs: [{ type: i0.ViewChildren, args: [i0.forwardRef(() => PinInputDirective), { isSignal: true }] }], length: [{ type: i0.Input, args: [{ isSignal: true, alias: "length", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], acceptOnly: [{ type: i0.Input, args: [{ isSignal: true, alias: "acceptOnly", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }] } });

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

export { PinInput };
//# sourceMappingURL=ngstarter-ui-components-pin-input.mjs.map
