import {Component, OnInit, Inject, ViewChild, ElementRef} from '@angular/core';
import {FormBuilder, FormGroup, Validators} from '@angular/forms';
import {MatDialog, MatDialogRef, MAT_DIALOG_DATA} from '@angular/material/dialog';
import {Router} from '@angular/router';


import {UserService} from './../../services/user.service';
import {ItemService} from './../../services/item.service';
import {I18nService} from './../../services/i18n.service';
import {MatchingValidator} from './../../utils/matching.validator';

import {uniqueNamesGenerator, Config, adjectives, colors, animals} from 'unique-names-generator';

var openpgp = require('openpgp');

@Component({
  selector: 'app-register',
  templateUrl: './register.component.html',
  styleUrls: ['./register.component.scss']
})
export class RegisterComponent implements OnInit {

  form: FormGroup;
  public missingToken: boolean;
  public success: boolean;
  public working: boolean;
  items = [];
  currentLocale: String;
  model: any = {
    username: '',
    password: '',
    password2: '',
  };

  constructor(
    private formBuilder: FormBuilder,
    private userService: UserService,
    private itemService: ItemService,
    private i18n: I18nService,
    public dialog: MatDialog) {
    this.currentLocale = this.i18n.getLocale();
  }

  async ngOnInit() {
    this.form = this.formBuilder.group({
      username: ['', Validators.required],
      email: ['', Validators.email],
      primaryEmail: [false, Validators.nullValidator],
      password: ['', Validators.required],
      password2: ['', Validators.required]
    }, {
      validator: MatchingValidator('password', 'password2')
    });

    this.itemService.items().subscribe((data: any) => {
      this.items = data;
    });
  }


  genUsername() {
    const config: Config = {
      dictionaries: [adjectives, colors, animals],
      separator: "",
      style: "capital",
      length: 3
    };

    this.model.username = uniqueNamesGenerator(config);
  }

  register() {
    this.missingToken = false;
    if(this.form.valid && !this.working) {
      this.working = true;
      let pgpOption = {
        userIds: [{name: this.model.username, email: this.model.username + "@we.bstly.de"}],
        curve: "ed25519",
      }

      var pubKey, privKey
      openpgp.generateKey(pgpOption).then((key) => {
        privKey = key.privateKeyArmored;
        pubKey = key.publicKeyArmored;

        this.model.profileFields = [
          {"name": "publicKey", "type": "BLOB", "visibility": "PROTECTED", "blob": pubKey}
        ]

        if(this.model.email) {
          this.model.profileFields.push({"name": "email", "type": "EMAIL", "visibility": "PRITAVE", "value": this.model.email})
        }
        if(this.model.primaryEmail) {
          this.model.profileFields.push({"name": "primaryEmail", "type": "BOOL", "visibility": "PRITAVE", "value": this.model.primaryEmail})
        }

        this.userService.register(this.model).subscribe((result: any) => {
          result.privateKey = privKey;

          const dialogRef = this.dialog.open(RegisterDialog, {
            closeOnNavigation: false,
            disableClose: true,
            data: result
          });

          dialogRef.afterClosed().subscribe(result => {
            if(result) {
              this.success = true;
            }
          });

          this.working = false;
        }, (error) => {
          this.working = false;
          if(error.status == 401) {
            this.missingToken = true;
          } else if(error.status == 409) {
            let errors = {};
            for(let code of error.error) {
              errors[code.field] = errors[code.field] || {};
              errors[code.field][code.code] = true;
            }

            for(let code in errors) {
              this.form.get(code).setErrors(errors[code]);
            }
          }
        })

      })
    }
  }
}


@Component({
  selector: 'app-register-dialog',
  templateUrl: 'register.dialog.html',
  styleUrls: ['./register.dialog.scss']
})
export class RegisterDialog {

  public downloaded: boolean = false;

  @ViewChild("downloadKey", {read: ElementRef}) downloadKey: ElementRef;

  constructor(private router: Router,
    public dialogRef: MatDialogRef<RegisterDialog>,
    @Inject(MAT_DIALOG_DATA) public data: any) {
  }

  ngAfterViewInit() {
    this.downloadKey.nativeElement.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(this.data.privateKey));
    this.downloadKey.nativeElement.setAttribute('download', this.data.username + ".private.key");
  }

  setDownloaded() {
    this.downloaded = true;
  }

}
