/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

import { Component, OnInit, Input, Output, EventEmitter, ViewChild, ChangeDetectorRef } from '@angular/core';
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
import { ToastrService } from 'ngx-toastr';
import { Subscription } from 'rxjs';

import { ProjectService, RolesGroupsService, EndpointService, UserAccessKeyService } from '../../../core/services';
import { ProjectDataService } from '../project-data.service';
import { CheckUtils, FileUtils, PATTERNS } from '../../../core/util';
import { Project } from '../project.component';
import { DICTIONARY } from '../../../../dictionary/global.dictionary';

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

  readonly DICTIONARY = DICTIONARY;

  public projectForm: FormGroup;
  public groupsList: any = [];
  public endpointsList: any = [];
  public projectList: Project[] = [];
  public accessKeyValid: boolean;
  public keyLabel: string = '';

  @Input() item: any;
  @Output() update: EventEmitter<{}> = new EventEmitter();
  @ViewChild('stepper') stepper;

  private subscriptions: Subscription = new Subscription();

  constructor(
    public toastr: ToastrService,
    private _fb: FormBuilder,
    private projectService: ProjectService,
    private projectDataService: ProjectDataService,
    private rolesService: RolesGroupsService,
    private endpointService: EndpointService,
    private userAccessKeyService: UserAccessKeyService,
    private cd: ChangeDetectorRef
  ) { }

  ngOnInit() {
    this.initFormModel();
    this.getGroupsData();
    this.getEndpointsData();

    this.subscriptions.add(this.projectDataService._projects.subscribe((value: Project[]) => {
      if (value) this.projectList = value;
    }));
    if (this.item) {
      this.editSpecificProject(this.item);
      this.stepper.selectedIndex = 1;
    }
  }

  public confirm(data) {
    if (this.item) {
      this.projectService.updateProject(data).subscribe(() => {
        this.toastr.success('Project updated successfully!', 'Success!');
        this.update.emit();
      }, error => this.toastr.error(error.message || 'Project update failed!', 'Oops!'));
    } else {
      this.projectService.createProject(data).subscribe(() => {
        this.toastr.success('Project creation is processing!', 'Success!');
        this.projectDataService.updateProjects();
        this.update.emit();
        this.reset();
      }, error => this.toastr.error(error.message || 'Project creation failed!', 'Oops!'));
    }
  }

  public reset() {
    this.keyLabel = '';
    this.initFormModel();
  }

  public generateProjectTag($event) {
    this.projectForm.controls.tag.setValue($event.target.value.toLowerCase());
  }

  public onFileChange($event) {
    const reader = new FileReader();
    const files = $event.target.files;

    if (files && files.length) {
      const [file] = $event.target.files;
      reader.readAsBinaryString(file);

      reader.onload = () => {
        this.projectForm.patchValue({
          key: reader.result
        });

        this.accessKeyValid = this.isValidKey(file.name);
        this.keyLabel = this.getLabel(file);
        $event.target.value = '';
        this.cd.markForCheck();
      };
    }
  }

  public generateUserAccessKey() {
    this.userAccessKeyService.generateAccessKey().subscribe(data => {
      FileUtils.downloadFile(data);
      this.keyLabel = 'Key is generated';
      this.accessKeyValid = true;
    });
  }

  public selectOptions(list, key, select?) {
    let filter = key === 'endpoints' ? list.map(el => el.name) : list;
    this.projectForm.controls[key].setValue(select ? filter : []);
  }

  private initFormModel(): void {
    this.projectForm = this._fb.group({
      'key': ['', Validators.required],
      'name': ['', Validators.compose([Validators.required, Validators.pattern(PATTERNS.projectName), this.checkDuplication.bind(this), this.providerMaxLength.bind(this)])],
      'endpoints': [[], Validators.required],
      'tag': ['', Validators.compose([Validators.required, Validators.pattern(PATTERNS.projectName)])],
      'groups': [[], Validators.required]
    });
  }

  public editSpecificProject(item: Project) {

    this.projectForm = this._fb.group({
      'key': [''],
      'name': [item.name, Validators.required],
      'endpoints': [item.endpoints],
      'tag': [item.tag, Validators.required],
      'groups': [item.groups, Validators.required]
    });
  }

  isDisabled(endpoint: any): boolean {
    return this.item && this.item.endpoints.includes(endpoint);
  }

  private getLabel(file: File): string {
    return file ? !this.accessKeyValid ? 'Public key is required.' : file.name : '';
  }

  private isValidKey(value): boolean {
    return value.toLowerCase().endsWith('.pub');
  }

  private getGroupsData() {
    this.rolesService.getGroupsData().subscribe(
      (list: any) => this.groupsList = list.map(el => el.group),
      error => this.toastr.error(error.message, 'Oops!'));
  }

  private getEndpointsData() {
    this.endpointService.getEndpointsData().subscribe(
      list => this.endpointsList = list,
      error => this.toastr.error(error.message, 'Oops!'));
  }

  private checkDuplication(control) {
    if (control.value) {
      for (let index = 0; index < this.projectList.length; index++) {
        if (CheckUtils.delimitersFiltering(control.value) === CheckUtils.delimitersFiltering(this.projectList[index].name))
          return { duplication: true };
      }
    }
  }

  private providerMaxLength(control) {
    return control.value.length <= DICTIONARY.max_project_name_length ? null : { limit: true };
  }
}
