import { Component, Inject, OnInit, ViewChild } from '@angular/core';
import { IBaseDialog } from '@shared/common-dialogs/base-dialog';
import { IAction } from '@objects-view/interfaces/actions/action';
import { DialogCallbackAction } from '@objects-view/actions/dialog-callback-action';
import { UntypedFormBuilder, Validators } from '@angular/forms';
import { IPublicKeyModel } from '@fleio-api/public-key/model/public-key.model';
import { PublicKeysApiService } from '@fleio-api/public-key/public-key-api.service';
import { ClipboardService } from '@shared/ui-api/clipboard.service';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { FleioId } from '@fleio-api/base-model/base-fleio-object.model';
import { AuthService } from '@shared/auth/auth.service';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { ClientsApiService } from '@fleio-api/client-user/client/clients-api.service';

@Component({
  selector: 'app-ssh-key-add-dialog',
  templateUrl: './ssh-key-add-dialog.component.html',
  styleUrls: ['./ssh-key-add-dialog.component.scss']
})
export class SshKeyAddDialogComponent implements IBaseDialog, OnInit {
  @ViewChild('formErrors') formErrors;
  backendErrors: Record<string, unknown> = {};
  sshKeyForm = this.formBuilder.group({
    name: ['', Validators.required],
    public_key: ['', Validators.required],
    private_key: [''],
  });
  generatedKey: Record<string, unknown>;
  dialogTitle = $localize`Add SSH key`;
  dialogActions: Array<IAction> = [
    new DialogCallbackAction({
      name: $localize`Generate new key`,
      ignoreFormInvalidity: true,
      callback: () => this.generateKey(),
    }),
    new DialogCallbackAction({
      name: $localize`Save key`,
      primary: true,
      callback: () => this.addSSHkey(),
    }),
  ];
  dialogForm = this.sshKeyForm;
  loading = false;
  userOptionsSwitchMap: (search: string) => Observable<any>;

  constructor(
    public dialogRef: MatDialogRef<SshKeyAddDialogComponent>,
    @Inject(MAT_DIALOG_DATA) public data: {
      client_id: FleioId
    },
    private formBuilder: UntypedFormBuilder,
    private publicKeysApiService: PublicKeysApiService,
    public clipboard: ClipboardService,
    private authService: AuthService,
    private clientsApi: ClientsApiService,
  ) {
  }

  ngOnInit() {
    if (this.authService.feature('ui.staff') && this.data.client_id) {
      this.sshKeyForm.addControl('user', this.formBuilder.control([''], Validators.required));
    }

    this.userOptionsSwitchMap = (search) => {
      let lowerCaseSearch = '';
      if (search && typeof search === 'string') {
        lowerCaseSearch = search.toLocaleLowerCase();
      }
      return this.clientsApi.getUsers(this.data.client_id).pipe(
        map(data => {
            if (lowerCaseSearch) {
              return data.users.filter(user => {
                return user.email.toLowerCase().includes(lowerCaseSearch) ||
                  user.full_name.toLowerCase().includes(lowerCaseSearch) ||
                  user.id.toString().includes(lowerCaseSearch);
              });
            } else {
              return data.users;
            }
          }
        ));
    };
  }

  generateKey() {
    this.loading = true;
    this.publicKeysApiService.getGeneratedKeyPair().subscribe(key => {
      this.generatedKey = key;
      this.sshKeyForm.patchValue(key);
    }).add(() => {
      this.loading = false;
    });
  }

  addSSHkey() {
    const value = JSON.parse(JSON.stringify(this.sshKeyForm.value));

    if (value.user?.id) {
      value.user_id = value.user.id;
      delete value.user;
    }

    this.loading = true;
    this.publicKeysApiService.create(
      value,
    ).subscribe({
      next: (result: IPublicKeyModel) => {
        this.dialogRef.close(result);
      }, error: error => {
        if (error.error) {
          this.backendErrors = error.error;
          this.formErrors.setBackendErrors(error.error);
        }
      }
    }).add(() => {
      this.loading = false;
    });
  }

}
