import * as i0 from '@angular/core';
import { computed, input, output, Directive, contentChildren, contentChild, ElementRef, signal, ChangeDetectionStrategy, Component, NgModule } from '@angular/core';
import { SiPasswordToggleComponent } from '@siemens/element-ng/password-toggle';
import { NG_VALIDATORS } from '@angular/forms';

/**
 * Copyright (c) Siemens 2016 - 2026
 * SPDX-License-Identifier: MIT
 */
const RE_UPPER_CASE = /[A-Z]/;
const RE_LOWER_CASE = /[a-z]/;
const RE_DIGITS = /[0-9]/;
const RE_SPECIAL_CHARS = /[\x21-\x2F|\x3A-\x40|\x5B-\x60]/;
const RE_WHITESPACES = /\s/;
class SiPasswordStrengthDirective {
    maxStrength = computed(() => {
        const strength = this.siPasswordStrength();
        return (1 +
            (strength.uppercase ? 1 : 0) +
            (strength.lowercase ? 1 : 0) +
            (strength.digits ? 1 : 0) +
            (strength.special ? 1 : 0));
    }, ...(ngDevMode ? [{ debugName: "maxStrength" }] : []));
    noValidation = false;
    /**
     * Define Siemens password strength.
     *
     * @defaultValue
     * ```
     * {
     *     minLength: 8,
     *     uppercase: true,
     *     lowercase: true,
     *     digits: true,
     *     special: true
     *   }
     * ```
     */
    siPasswordStrength = input({
        minLength: 8,
        uppercase: true,
        lowercase: true,
        digits: true,
        special: true
    }, ...(ngDevMode ? [{ debugName: "siPasswordStrength" }] : []));
    /**
     * Output callback event called when the password changes. The number
     * indicated the number of rules which still can be met. (`-2` --\> 2 rules are
     * still unmet, `0` --\> all met)
     */
    passwordStrengthChanged = output();
    /** @internal */
    validate(control) {
        const strength = this.getStrength(control.value);
        // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
        const requiredStrength = this.siPasswordStrength().minRequiredPolicies || this.maxStrength();
        if (strength.length && strength.strength >= requiredStrength) {
            return {};
        }
        return { siPasswordStrength: true };
    }
    getStrength(password) {
        const policy = this.siPasswordStrength();
        if (!password) {
            this.noValidation = false;
            this.passwordStrengthChanged.emit();
            return { length: false, strength: 0 };
        }
        let strength = 0;
        // Strength check
        const length = password.length >= policy.minLength;
        strength += length ? 1 : 0;
        strength += policy.uppercase && password.match(RE_UPPER_CASE) ? 1 : 0;
        strength += policy.lowercase && password.match(RE_LOWER_CASE) ? 1 : 0;
        strength += policy.digits && password.match(RE_DIGITS) ? 1 : 0;
        strength += policy.special && password.match(RE_SPECIAL_CHARS) ? 1 : 0;
        if (policy.allowWhitespace !== true) {
            strength = password.match(RE_WHITESPACES) ? 0 : strength;
        }
        this.noValidation = true;
        // Notify listeners
        this.passwordStrengthChanged.emit(strength - this.maxStrength());
        return { length, strength };
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: SiPasswordStrengthDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
    static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.0.8", type: SiPasswordStrengthDirective, isStandalone: true, selector: "[siPasswordStrength]", inputs: { siPasswordStrength: { classPropertyName: "siPasswordStrength", publicName: "siPasswordStrength", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { passwordStrengthChanged: "passwordStrengthChanged" }, host: { properties: { "class.no-validation": "noValidation" } }, providers: [{ provide: NG_VALIDATORS, useExisting: SiPasswordStrengthDirective, multi: true }], ngImport: i0 });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: SiPasswordStrengthDirective, decorators: [{
            type: Directive,
            args: [{
                    selector: '[siPasswordStrength]',
                    providers: [{ provide: NG_VALIDATORS, useExisting: SiPasswordStrengthDirective, multi: true }],
                    host: {
                        '[class.no-validation]': 'noValidation'
                    }
                }]
        }], propDecorators: { siPasswordStrength: [{ type: i0.Input, args: [{ isSignal: true, alias: "siPasswordStrength", required: false }] }], passwordStrengthChanged: [{ type: i0.Output, args: ["passwordStrengthChanged"] }] } });

/**
 * Copyright (c) Siemens 2016 - 2026
 * SPDX-License-Identifier: MIT
 */
class SiPasswordStrengthComponent {
    /**
     * Whether to show the visibility toggle icon.
     *
     * @defaultValue true
     */
    showVisibilityIcon = input(true, ...(ngDevMode ? [{ debugName: "showVisibilityIcon" }] : []));
    passwordStrengthDirective = contentChildren(SiPasswordStrengthDirective, ...(ngDevMode ? [{ debugName: "passwordStrengthDirective" }] : []));
    passwordInput = contentChild.required(SiPasswordStrengthDirective, { read: (ElementRef) });
    bad = signal(false, ...(ngDevMode ? [{ debugName: "bad" }] : []));
    weak = signal(false, ...(ngDevMode ? [{ debugName: "weak" }] : []));
    medium = signal(false, ...(ngDevMode ? [{ debugName: "medium" }] : []));
    good = signal(false, ...(ngDevMode ? [{ debugName: "good" }] : []));
    strong = signal(false, ...(ngDevMode ? [{ debugName: "strong" }] : []));
    toggle(type) {
        this.passwordInput().nativeElement.type = type;
    }
    ngAfterViewInit() {
        this.passwordStrengthDirective().forEach(directive => {
            directive.passwordStrengthChanged.subscribe((strength) => {
                this.strong.set(strength === 0);
                this.good.set(strength === -1);
                this.medium.set(strength === -2);
                this.weak.set(strength === -3);
                this.bad.set(strength === -4);
            });
        });
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: SiPasswordStrengthComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
    static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "21.0.8", type: SiPasswordStrengthComponent, isStandalone: true, selector: "si-password-strength", inputs: { showVisibilityIcon: { classPropertyName: "showVisibilityIcon", publicName: "showVisibilityIcon", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.bad": "bad()", "class.weak": "weak()", "class.medium": "medium()", "class.good": "good()", "class.strong": "strong()" } }, queries: [{ propertyName: "passwordStrengthDirective", predicate: SiPasswordStrengthDirective, isSignal: true }, { propertyName: "passwordInput", first: true, predicate: SiPasswordStrengthDirective, descendants: true, read: ElementRef, isSignal: true }], ngImport: i0, template: `
    <si-password-toggle [showVisibilityIcon]="showVisibilityIcon()" (typeChange)="toggle($event)">
      <ng-content />
    </si-password-toggle>
  `, isInline: true, styles: [":host{--strength-border-radius: 0 var(--element-radius-1) var(--element-radius-1) 1px;display:block;position:relative}:host:before{background:var(--strength-background);inset-block-end:1px;content:\"\";block-size:3px;inset-inline-start:1px;position:absolute;transition:inline-size calc(.15s * var(--element-animations-enabled, 1)),background calc(.15s * var(--element-animations-enabled, 1)) ease-in-out;inline-size:calc(var(--strength-width) - 2px);border-radius:var(--strength-border-radius);z-index:1}:host.bad{--strength-background: var(--element-color-bad);--strength-width: 20%}:host.weak{--strength-background: var(--element-color-poor);--strength-width: 40%}:host.medium{--strength-background: var(--element-color-average);--strength-width: 60%}:host.good{--strength-background: var(--element-color-good);--strength-width: 80%}:host.strong{--strength-background: var(--element-color-excellent);--strength-width: 100%;--strength-border-radius: 0 0 1px 1px}\n"], dependencies: [{ kind: "component", type: SiPasswordToggleComponent, selector: "si-password-toggle", inputs: ["showVisibilityIcon", "showLabel", "hideLabel"], outputs: ["typeChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: SiPasswordStrengthComponent, decorators: [{
            type: Component,
            args: [{ selector: 'si-password-strength', imports: [SiPasswordToggleComponent], template: `
    <si-password-toggle [showVisibilityIcon]="showVisibilityIcon()" (typeChange)="toggle($event)">
      <ng-content />
    </si-password-toggle>
  `, changeDetection: ChangeDetectionStrategy.OnPush, host: {
                        '[class.bad]': 'bad()',
                        '[class.weak]': 'weak()',
                        '[class.medium]': 'medium()',
                        '[class.good]': 'good()',
                        '[class.strong]': 'strong()'
                    }, styles: [":host{--strength-border-radius: 0 var(--element-radius-1) var(--element-radius-1) 1px;display:block;position:relative}:host:before{background:var(--strength-background);inset-block-end:1px;content:\"\";block-size:3px;inset-inline-start:1px;position:absolute;transition:inline-size calc(.15s * var(--element-animations-enabled, 1)),background calc(.15s * var(--element-animations-enabled, 1)) ease-in-out;inline-size:calc(var(--strength-width) - 2px);border-radius:var(--strength-border-radius);z-index:1}:host.bad{--strength-background: var(--element-color-bad);--strength-width: 20%}:host.weak{--strength-background: var(--element-color-poor);--strength-width: 40%}:host.medium{--strength-background: var(--element-color-average);--strength-width: 60%}:host.good{--strength-background: var(--element-color-good);--strength-width: 80%}:host.strong{--strength-background: var(--element-color-excellent);--strength-width: 100%;--strength-border-radius: 0 0 1px 1px}\n"] }]
        }], propDecorators: { showVisibilityIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "showVisibilityIcon", required: false }] }], passwordStrengthDirective: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => SiPasswordStrengthDirective), { isSignal: true }] }], passwordInput: [{ type: i0.ContentChild, args: [i0.forwardRef(() => SiPasswordStrengthDirective), { ...{ read: (ElementRef) }, isSignal: true }] }] } });

/**
 * Copyright (c) Siemens 2016 - 2026
 * SPDX-License-Identifier: MIT
 */
class SiPasswordStrengthModule {
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: SiPasswordStrengthModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
    static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.0.8", ngImport: i0, type: SiPasswordStrengthModule, imports: [SiPasswordStrengthComponent, SiPasswordStrengthDirective], exports: [SiPasswordStrengthComponent, SiPasswordStrengthDirective] });
    static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: SiPasswordStrengthModule, imports: [SiPasswordStrengthComponent] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: SiPasswordStrengthModule, decorators: [{
            type: NgModule,
            args: [{
                    imports: [SiPasswordStrengthComponent, SiPasswordStrengthDirective],
                    exports: [SiPasswordStrengthComponent, SiPasswordStrengthDirective]
                }]
        }] });

/**
 * Copyright (c) Siemens 2016 - 2026
 * SPDX-License-Identifier: MIT
 */

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

export { SiPasswordStrengthComponent, SiPasswordStrengthDirective, SiPasswordStrengthModule };
//# sourceMappingURL=siemens-element-ng-password-strength.mjs.map
