import * as i0 from '@angular/core';
import { Component, Input, Directive, HostListener, NgModule } from '@angular/core';
import * as i2 from '@angular/common';
import { CommonModule } from '@angular/common';
import { isNullOrUndefined } from '@seniorsistemas/angular-components/utils';
import * as i1 from '@ngx-translate/core';

class PasswordStrengthComponent {
    translate;
    weakTitle;
    mediumTitle;
    strongTitle;
    description;
    title;
    position = 'right';
    left = 0;
    top = 0;
    visible = false;
    constructor(translate) {
        this.translate = translate;
    }
    ngOnInit() {
        this.title = this.weakTitle;
    }
    setPasswordStrengthPosition() {
        const passwordStrength = document.querySelector('.password-strength');
        if (!passwordStrength) {
            return;
        }
        switch (this.position) {
            case 'top':
                passwordStrength.classList.add('password-strength--top');
                break;
            case 'right':
                passwordStrength.classList.add('password-strength--right');
                break;
            case 'left':
                passwordStrength.classList.add('password-strength--left');
                break;
        }
    }
    updateIndicators(passwordStrength) {
        const strengthIndicator1 = document.querySelector('#strength-indicator-1');
        const strengthIndicator2 = document.querySelector('#strength-indicator-2');
        const strengthIndicator3 = document.querySelector('#strength-indicator-3');
        const onIndicators = [];
        const indicators = [strengthIndicator1, strengthIndicator2, strengthIndicator3];
        let strengthClass;
        switch (passwordStrength) {
            case 'veryWeak':
                this.title = this.weakTitle ?? this.translate.instant('platform.angular_components.weak');
                break;
            case 'weak':
                this.title = this.weakTitle ?? this.translate.instant('platform.angular_components.weak');
                strengthClass = 'strength-indicator--weak';
                onIndicators.push(strengthIndicator1);
                break;
            case 'medium':
                this.title = this.mediumTitle ?? this.translate.instant('platform.angular_components.medium');
                strengthClass = 'strength-indicator--medium';
                onIndicators.push(strengthIndicator1);
                onIndicators.push(strengthIndicator2);
                break;
            case 'strong':
                this.title = this.strongTitle ?? this.translate.instant('platform.angular_components.strong');
                strengthClass = 'strength-indicator--strong';
                onIndicators.push(strengthIndicator1);
                onIndicators.push(strengthIndicator2);
                onIndicators.push(strengthIndicator3);
                break;
        }
        indicators.forEach((indicator) => {
            indicator?.classList.remove('strength-indicator--weak', 'strength-indicator--medium', 'strength-indicator--strong');
        });
        onIndicators.forEach((indicator) => {
            indicator?.classList.add(strengthClass);
        });
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: PasswordStrengthComponent, deps: [{ token: i1.TranslateService }], target: i0.ɵɵFactoryTarget.Component });
    static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: PasswordStrengthComponent, selector: "ng-component", inputs: { weakTitle: "weakTitle", mediumTitle: "mediumTitle", strongTitle: "strongTitle", description: "description" }, ngImport: i0, template: "<div\n    class=\"password-strength\"\n    [ngStyle]=\"{\n        left: left + 'px',\n        top: top + 'px',\n    }\"\n    [ngClass]=\"['password-strength--' + position]\"\n>\n    <span class=\"password-strength-title\">{{ title }}</span>\n    <div class=\"strength-indicators\">\n        <span\n            class=\"strength-indicator\"\n            id=\"strength-indicator-1\"\n        ></span>\n        <span\n            class=\"strength-indicator\"\n            id=\"strength-indicator-2\"\n        ></span>\n        <span\n            class=\"strength-indicator\"\n            id=\"strength-indicator-3\"\n        ></span>\n    </div>\n    <span class=\"content\">{{ description }}</span>\n</div>\n", styles: [".password-strength{position:fixed;transform:translate(-50%);background-color:#fff;border-radius:2px;box-shadow:0 0 5px 1px #ccc;padding:10px;width:232px;z-index:99999}.password-strength:after{content:\"\";position:absolute}.password-strength-title{font-family:Open Sans,sans-serif;font-size:14px;font-weight:700;line-height:150%}.password-strength .strength-indicators{display:flex;justify-content:space-between;padding:10px 0}.password-strength .strength-indicators .strength-indicator{background-color:#ccc;border-radius:2px;display:inline-block;height:3px;width:64px}.password-strength .strength-indicators .strength-indicator--weak{background-color:#c13018}.password-strength .strength-indicators .strength-indicator--medium{background-color:#fcbf10}.password-strength .strength-indicators .strength-indicator--strong{background-color:#0c9348}.password-strength .content{font-family:Open Sans,sans-serif;font-size:12px;font-weight:400;line-height:150%}.password-strength--top{transform:translate(-50%,-100%)}.password-strength--top:after{top:100%;right:calc(50% - 4px);border-left:8px solid transparent;border-right:8px solid transparent;border-top:8px solid #fff}.password-strength--right{transform:translateY(-50%)}.password-strength--right:after{bottom:calc(50% - 8px);left:-8px;border-top:8px solid transparent;border-right:8px solid #fff;border-bottom:8px solid transparent}.password-strength--left{transform:translate(-100%,-50%)}.password-strength--left:after{bottom:calc(50% - 8px);right:-8px;border-top:8px solid transparent;border-left:8px solid #fff;border-bottom:8px solid transparent}\n"], dependencies: [{ kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: PasswordStrengthComponent, decorators: [{
            type: Component,
            args: [{ template: "<div\n    class=\"password-strength\"\n    [ngStyle]=\"{\n        left: left + 'px',\n        top: top + 'px',\n    }\"\n    [ngClass]=\"['password-strength--' + position]\"\n>\n    <span class=\"password-strength-title\">{{ title }}</span>\n    <div class=\"strength-indicators\">\n        <span\n            class=\"strength-indicator\"\n            id=\"strength-indicator-1\"\n        ></span>\n        <span\n            class=\"strength-indicator\"\n            id=\"strength-indicator-2\"\n        ></span>\n        <span\n            class=\"strength-indicator\"\n            id=\"strength-indicator-3\"\n        ></span>\n    </div>\n    <span class=\"content\">{{ description }}</span>\n</div>\n", styles: [".password-strength{position:fixed;transform:translate(-50%);background-color:#fff;border-radius:2px;box-shadow:0 0 5px 1px #ccc;padding:10px;width:232px;z-index:99999}.password-strength:after{content:\"\";position:absolute}.password-strength-title{font-family:Open Sans,sans-serif;font-size:14px;font-weight:700;line-height:150%}.password-strength .strength-indicators{display:flex;justify-content:space-between;padding:10px 0}.password-strength .strength-indicators .strength-indicator{background-color:#ccc;border-radius:2px;display:inline-block;height:3px;width:64px}.password-strength .strength-indicators .strength-indicator--weak{background-color:#c13018}.password-strength .strength-indicators .strength-indicator--medium{background-color:#fcbf10}.password-strength .strength-indicators .strength-indicator--strong{background-color:#0c9348}.password-strength .content{font-family:Open Sans,sans-serif;font-size:12px;font-weight:400;line-height:150%}.password-strength--top{transform:translate(-50%,-100%)}.password-strength--top:after{top:100%;right:calc(50% - 4px);border-left:8px solid transparent;border-right:8px solid transparent;border-top:8px solid #fff}.password-strength--right{transform:translateY(-50%)}.password-strength--right:after{bottom:calc(50% - 8px);left:-8px;border-top:8px solid transparent;border-right:8px solid #fff;border-bottom:8px solid transparent}.password-strength--left{transform:translate(-100%,-50%)}.password-strength--left:after{bottom:calc(50% - 8px);right:-8px;border-top:8px solid transparent;border-left:8px solid #fff;border-bottom:8px solid transparent}\n"] }]
        }], ctorParameters: () => [{ type: i1.TranslateService }], propDecorators: { weakTitle: [{
                type: Input
            }], mediumTitle: [{
                type: Input
            }], strongTitle: [{
                type: Input
            }], description: [{
                type: Input,
                args: [{ required: true }]
            }] } });

class PasswordStrengthDirective {
    elementRef;
    appRef;
    componentFactoryResolver;
    injector;
    enabled = true;
    passwordStrengthValidation;
    passwordStrengthPosition = 'right';
    passwordStrengthWeakTitle;
    passwordStrengthMediumTitle;
    passwordStrengthStrongTitle;
    passwordStrengthDescription;
    componentRef;
    constructor(elementRef, appRef, 
    // NOSONAR - 'ComponentFactoryResolver' is deprecated.
    componentFactoryResolver, injector) {
        this.elementRef = elementRef;
        this.appRef = appRef;
        this.componentFactoryResolver = componentFactoryResolver;
        this.injector = injector;
    }
    ngOnInit() {
        this.validateProperties();
    }
    onFocus() {
        const content = this.elementRef.nativeElement.value ?? '';
        this.createPasswordStrength();
        const component = this.componentRef?.instance;
        if (!component) {
            return;
        }
        if (content) {
            if (this.passwordStrengthValidation) {
                component.updateIndicators(this.passwordStrengthValidation(content));
            }
        }
        else {
            component.updateIndicators('veryWeak');
        }
    }
    onBlur() {
        this.destroyPasswordStrength();
    }
    createPasswordStrength() {
        if (this.enabled && isNullOrUndefined(this.componentRef)) {
            const componentFactory = this.componentFactoryResolver.resolveComponentFactory(PasswordStrengthComponent);
            this.componentRef = componentFactory.create(this.injector);
            this.appRef.attachView(this.componentRef.hostView);
            const domElem = this.componentRef.hostView.rootNodes[0];
            document.body.appendChild(domElem);
            this.setPasswordStrengthComponentProperties();
            this.showPasswordStrength();
        }
    }
    showPasswordStrength() {
        if (this.componentRef) {
            this.componentRef.instance.visible = true;
        }
    }
    // NOSONAR - Refactor this function to reduce its Cognitive Complexity from 16 to the 15 allowed.
    setPasswordStrengthComponentProperties() {
        if (isNullOrUndefined(this.componentRef)) {
            return;
        }
        this.componentRef.instance.position = this.passwordStrengthPosition;
        this.componentRef.instance.weakTitle = this.passwordStrengthWeakTitle;
        this.componentRef.instance.mediumTitle = this.passwordStrengthMediumTitle;
        this.componentRef.instance.strongTitle = this.passwordStrengthStrongTitle;
        this.componentRef.instance.description = this.passwordStrengthDescription;
        const { top, right, bottom, left } = this.elementRef.nativeElement.getBoundingClientRect();
        const margin = 20;
        const elementRefHeight = bottom - top;
        const elementRefWidth = right - left;
        const safeSpace = 150;
        let positioned = false;
        const invalidOptions = [];
        while (!positioned) {
            if (invalidOptions.includes('top') && invalidOptions.includes('right') && invalidOptions.includes('left')) {
                this.destroyPasswordStrength();
                throw new Error('No space to show password strength');
            }
            switch (this.passwordStrengthPosition) {
                case 'top': {
                    const topShift = top;
                    const rightShift = document.body.clientWidth - right;
                    const leftShift = left;
                    const MIN_HORIZONTAL_SAFE_SPACE = 50;
                    if (topShift <= elementRefHeight + safeSpace ||
                        rightShift < MIN_HORIZONTAL_SAFE_SPACE ||
                        leftShift < MIN_HORIZONTAL_SAFE_SPACE) {
                        this.passwordStrengthPosition = 'right';
                        invalidOptions.push('top');
                        break;
                    }
                    this.componentRef.instance.top = Math.round(top - margin);
                    this.componentRef.instance.left = Math.round(elementRefWidth / 2 + left);
                    positioned = true;
                    break;
                }
                case 'right': {
                    const rightShift = document.body.clientWidth - right;
                    if (rightShift <= elementRefWidth + safeSpace) {
                        this.passwordStrengthPosition = 'left';
                        invalidOptions.push('right');
                        break;
                    }
                    this.componentRef.instance.top = Math.round(top + elementRefHeight / 2);
                    this.componentRef.instance.left = Math.round(right + margin);
                    positioned = true;
                    break;
                }
                case 'left': {
                    const leftShift = left;
                    if (leftShift <= elementRefWidth + safeSpace) {
                        this.passwordStrengthPosition = 'top';
                        invalidOptions.push('left');
                        break;
                    }
                    this.componentRef.instance.top = Math.round(top + elementRefHeight / 2);
                    this.componentRef.instance.left = Math.round(left - margin);
                    positioned = true;
                    break;
                }
                default: {
                    break;
                }
            }
            this.componentRef.instance.position = this.passwordStrengthPosition;
        }
    }
    validateProperties() {
        this.passwordStrengthValidation = this.passwordStrengthValidation || this.defaultValidator;
    }
    destroyPasswordStrength() {
        if (this.componentRef) {
            this.appRef.detachView(this.componentRef.hostView);
            this.componentRef.destroy();
            this.componentRef = null;
        }
    }
    defaultValidator(content) {
        let points = 0;
        const PASSWORD_MIN_LENGTH = 6;
        const WEEK_CRITERIA = 1;
        const MEDIUM_CRITERIA = 4;
        const STRONG_CRITERIA = 5;
        const regExpValidations = [
            /(?=.*\d)/, // number
            /(?=.*[a-z])/, // lowercase
            /(?=.*[A-Z])/, // uppercase
            /(?=.*[!@#$%&*.\\=+^~-])/, // special character
        ];
        if (content.length >= PASSWORD_MIN_LENGTH) {
            points++;
        }
        regExpValidations.forEach((validation) => {
            if (validation.test(content)) {
                points++;
            }
        });
        if (points < WEEK_CRITERIA) {
            return 'veryWeak';
        }
        if (points < MEDIUM_CRITERIA) {
            return 'weak';
        }
        if (points < STRONG_CRITERIA) {
            return 'medium';
        }
        return 'strong';
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: PasswordStrengthDirective, deps: [{ token: i0.ElementRef }, { token: i0.ApplicationRef }, { token: i0.ComponentFactoryResolver }, { token: i0.Injector }], target: i0.ɵɵFactoryTarget.Directive });
    static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.14", type: PasswordStrengthDirective, selector: "[sPasswordStrength]", inputs: { enabled: ["sPasswordStrength", "enabled"], passwordStrengthValidation: "passwordStrengthValidation", passwordStrengthPosition: "passwordStrengthPosition", passwordStrengthWeakTitle: "passwordStrengthWeakTitle", passwordStrengthMediumTitle: "passwordStrengthMediumTitle", passwordStrengthStrongTitle: "passwordStrengthStrongTitle", passwordStrengthDescription: "passwordStrengthDescription" }, host: { listeners: { "keyup": "onFocus()", "focus": "onFocus()", "blur": "onBlur()" } }, ngImport: i0 });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: PasswordStrengthDirective, decorators: [{
            type: Directive,
            args: [{
                    selector: '[sPasswordStrength]',
                }]
        }], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.ApplicationRef }, { type: i0.ComponentFactoryResolver }, { type: i0.Injector }], propDecorators: { enabled: [{
                type: Input,
                args: ['sPasswordStrength']
            }], passwordStrengthValidation: [{
                type: Input
            }], passwordStrengthPosition: [{
                type: Input
            }], passwordStrengthWeakTitle: [{
                type: Input
            }], passwordStrengthMediumTitle: [{
                type: Input
            }], passwordStrengthStrongTitle: [{
                type: Input
            }], passwordStrengthDescription: [{
                type: Input,
                args: [{ required: true }]
            }], onFocus: [{
                type: HostListener,
                args: ['keyup']
            }, {
                type: HostListener,
                args: ['focus']
            }], onBlur: [{
                type: HostListener,
                args: ['blur']
            }] } });

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

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

export { PasswordStrengthComponent, PasswordStrengthDirective, PasswordStrengthModule };
//# sourceMappingURL=seniorsistemas-angular-components-password-strength.mjs.map
