import { DOCUMENT } from '@angular/common';
import {
  Directive,
  ElementRef,
  EventEmitter,
  Inject,
  Input,
  OnInit,
  Output,
  Renderer2
} from '@angular/core';
import { marker } from '@biesbjerg/ngx-translate-extract-marker';

declare const zxcvbn;

@Directive({
  selector: '[appZxcvbn]',
})
export class ZxcvbnDirective implements OnInit {
  private textDiv;
  private crackTimeDiv;
  private strengthDiv;
  private response = [
    marker('Very Weak'),
    marker('Weak'),
    marker('Normal'),
    marker('Safe'),
    marker('Very Safe'),
  ];

  @Output() readonly score = new EventEmitter();
  @Input() scoreContentMarker: any;

  constructor(
    private renderer: Renderer2,
    private el: ElementRef,
    @Inject(DOCUMENT) private document: Document
  ) {}

  ngOnInit(): void {
    if (
      this.el.nativeElement.nodeName.toUpperCase() == 'INPUT' &&
      ['text', 'password'].includes(this.el.nativeElement.getAttribute('type'))
    ) {
      if (this.scoreContentMarker) this.buildDOMForMatFormField();
      else this.buildDOM();

      this.el.nativeElement.addEventListener('input', () => {
        this.checkStrength(this.el.nativeElement.value);
      });
    } else {
      console.error('wrong DOM element passed to the zxcvbn checker', this.el.nativeElement);
    }
  }

  checkStrength(password) {
    if (password.length > 0) {
      let res = zxcvbn(password);
      let score = res['score'];

      if (this.textDiv) this.textDiv.innerHTML = this.response[score];
      this.strengthDiv.className = 'level-' + score; // override all

      if (this.scoreContentMarker) this.strengthDiv.classList.add('zxcvbn-level-mat-input');
      else this.strengthDiv.classList.add('zxcvbn-level');

      //console.log(res)
      if (this.crackTimeDiv)
        this.crackTimeDiv.innerHTML =
          marker('Estimated time to be cracked') +
          ': ' +
          res?.crack_times_display?.offline_fast_hashing_1e10_per_second;
      this.score.emit(score);
    } else {
      if (this.textDiv) this.textDiv.innerHTML = '';
      this.strengthDiv.className = 'level-non'; // override all

      if (this.scoreContentMarker) this.strengthDiv.classList.add('zxcvbn-level-mat-input');
      else this.strengthDiv.classList.add('zxcvbn-level');
    }
  }

  buildDOM() {
    let node = this.el.nativeElement;

    let div = this.renderer.createElement('div');
    div.classList.add('zxcvbn');
    let parent = node.parentElement;
    this.renderer.insertBefore(parent, div, node);
    this.renderer.appendChild(div, node);

    this.strengthDiv = this.renderer.createElement('div');

    this.strengthDiv.classList.add('zxcvbn-level');
    this.strengthDiv.classList.add('level-non');
    this.renderer.appendChild(div, this.strengthDiv);

    this.textDiv = this.renderer.createElement('div');
    this.textDiv.classList.add('zxcvbn-text');
    this.textDiv.style.display = 'none';
    this.renderer.appendChild(div, this.textDiv);

    this.crackTimeDiv = this.renderer.createElement('div');
    this.crackTimeDiv.classList.add('zxcvbn-text');
    this.renderer.appendChild(div, this.crackTimeDiv);
  }

  buildDOMForMatFormField() {
    let node = this.scoreContentMarker;

    let div = this.renderer.createElement('div');
    div.classList.add('zxcvbn');
    let parent = node.parentElement;
    this.renderer.insertBefore(parent, div, node);
    this.renderer.appendChild(div, node);

    // this.textDiv = this.renderer.createElement('div');
    // this.textDiv.classList.add('zxcvbn-text-mat-input');
    // this.textDiv.style.display = 'none';
    // this.renderer.appendChild(div, this.textDiv);

    // this.crackTimeDiv = this.renderer.createElement('div');
    // this.crackTimeDiv.classList.add('zxcvbn-text-mat-input');
    // this.renderer.appendChild(div, this.crackTimeDiv);

    this.strengthDiv = this.renderer.createElement('div');
    this.strengthDiv.classList.add('zxcvbn-level-mat-input');
    this.strengthDiv.classList.add('level-non');
    this.renderer.appendChild(div, this.strengthDiv);
  }
}
