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('score') 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'];
      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)
      this.crackTimeDiv.innerHTML = marker("Estimated time to be cracked")+": "+res?.crack_times_display?.offline_fast_hashing_1e10_per_second;
      this.score.emit(score);
    }
    else{
      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);
  }
}
