import {Component, OnInit, Input, ElementRef} from '@angular/core';
import {FormGroup, FormBuilder, Validators} from '@angular/forms';
import {ActivatedRoute, Router} from '@angular/router';
import {HelpContentService} from '../../../services/help-content.service';
import {CommunityService} from '../../../openaireLibrary/connect/community/community.service';
import {SubjectsService} from '../subjects.service';
import {EnvProperties} from '../../../openaireLibrary/utils/properties/env-properties';
import {Session} from '../../../openaireLibrary/login/utils/helper.class';
import {LoginErrorCodes} from '../../../openaireLibrary/login/utils/guardHelper.class';

import { concat } from 'rxjs/observable/concat';
import {HelperFunctions} from "../../../openaireLibrary/utils/HelperFunctions.class";
import {Title} from '@angular/platform-browser';
@Component({
    selector: 'subjects-edit-form',
    templateUrl: './subjects-edit-form.component.html',
})

export class SubjectsEditFormComponent implements OnInit {

    @Input('group')
    myForm: FormGroup;

    public showLoading = true;
    public errorMessage = '';
    public updateErrorMessage = '';

    public successfulSaveMessage = '';
    public successfulResetMessage = '';

    public hasChanged = false;

    public res = [];

    params: any;

    public communityId = null;
    public community = null;
    public properties: EnvProperties = null;
    public newsubject = '';
    public edit = null;
    public editSubjectOriginalValue = null;
    public originalSubjects = [];

    constructor (private element: ElementRef,
                 private route: ActivatedRoute,
                 private _router: Router,
                 public _fb: FormBuilder,
                 private title: Title,
                 private _helpContentService: HelpContentService,
                 private _communityService: CommunityService,
                 private _subjectsService: SubjectsService) { }


    ngOnInit() {
        this.route.data.subscribe((data: { envSpecific: EnvProperties }) => {
        this.properties = data.envSpecific;
        this.route.queryParams.subscribe(
            communityId => {
                HelperFunctions.scroll();
                this.title.setTitle('Administration Dashboard | Subjects');
                this.communityId = communityId['communityId'];

                if (!Session.isLoggedIn()) {
                    this._router.navigate(['/user-info'], {
                        queryParams: { 'errorCode': LoginErrorCodes.NOT_VALID, 'redirectUrl':  this._router.url} });
                } else {
                  if (this.communityId != null && this.communityId !== '') {
                      this.showLoading = true;
                      this.updateErrorMessage = '';
                      this.errorMessage = '';

                      this._communityService.getCommunity(this.properties,
                          this.properties.communityAPI + this.communityId).subscribe (
                        community => {
                              this.community = community;
                              this.params = {community: encodeURIComponent(
                                  '"' + community.queryId + '"')};
                              this.originalSubjects = [];
                              for (let i = 0; i < this.community.subjects.length; i++) {
                                  this.originalSubjects.push(this.community.subjects[i]);
                              }
                              if (this.community.subjects.length === 0) {
                                this.community.subjects.push('');
                              }
                              this.showLoading = false;
                        },
                        error => this.handleError('System error retrieving community profile', error)
                      );
                  }
                }
            });
        });
    }



  public addSubject() {
    if (!Session.isLoggedIn()) {
      this._router.navigate(
          ['/user-info'], {
              queryParams: { 'errorCode': LoginErrorCodes.NOT_VALID, 'redirectUrl':  this._router.url} });
    } else {
          this.community.subjects.push('');
    }
  }

  public removeSubject(i: any) {
    if (!Session.isLoggedIn()) {
      this._router.navigate(['/user-info'], {
          queryParams: { 'errorCode': LoginErrorCodes.NOT_VALID, 'redirectUrl':  this._router.url} });
    } else {
          this.community.subjects.splice(i, 1);
    }
  }

  public resetForm(communityId: string) {
    if (!Session.isLoggedIn()) {
      this._router.navigate(['/user-info'],
          { queryParams: { 'errorCode': LoginErrorCodes.NOT_VALID, 'redirectUrl':  this._router.url} });
    } else {
      if (communityId != null && communityId !== '') {
          this.showLoading = true;
          this.updateErrorMessage = '';
          this.errorMessage = '';

          this._communityService.getCommunity(this.properties,
              this.properties.communityAPI + communityId).subscribe (
            community => {
                  this.community = community;
                  this.params = {community: encodeURIComponent('"' + community.queryId + '"')};
                  this.showLoading = false;
                  this.handleSuccessfulReset('Form reset!');
            },
            error => this.handleError('System error retrieving community profile', error)
          );
      }
      this.resetChange();
    }
  }

 public getSubjectsExistOnlyInFirst(firstArray: string[], secondArray: string[]): string[] {

   const difference = [];
   for (let i = 0; i < firstArray.length; i++) {
       if (secondArray.indexOf(firstArray[i]) === -1) {
           difference.push(firstArray[i]);
       }

   }
   return difference;

 }

 public updateSubjects() {
    if (!Session.isLoggedIn()) {
      this._router.navigate(['/user-info'],
          { queryParams: { 'errorCode': LoginErrorCodes.NOT_VALID, 'redirectUrl':  this._router.url} });
    } else {
      if (this.communityId != null && this.communityId !== '') {
          this.showLoading = true;
          const subjectsToDeleteAr = this.getSubjectsExistOnlyInFirst(this.originalSubjects, this.community.subjects);
          const subjectsToAddAr = this.getSubjectsExistOnlyInFirst(this.community.subjects, this.originalSubjects);
          const subjectsToDelete = this.parseUpdatedSubjects(subjectsToDeleteAr);
          const subjectsToAdd = this.parseUpdatedSubjects(subjectsToAddAr);
          if (subjectsToAddAr.length > 0 && subjectsToDeleteAr.length > 0) {
            const obs = concat(this._subjectsService.addSubjects(
                this.properties.communityAPI + this.communityId + '/subjects', subjectsToAdd),
            this._subjectsService.removeSubjects(
                this.properties.communityAPI + this.communityId + '/subjects', subjectsToDelete));
             obs.subscribe(res => {
               if (res['method'] === 'delete') {
                this.afterUpdateActions(res);
               }
             },
              error => this.handleUpdateError('System error updating subjects', error)
            );
          } else if (subjectsToAddAr.length > 0) {
            this._subjectsService.addSubjects(
                this.properties.communityAPI + this.communityId + '/subjects', subjectsToAdd).
            subscribe(res => {
                 this.afterUpdateActions(res);
             },
              error => this.handleUpdateError('System error updating subjects', error)
            );
          } else if (subjectsToDeleteAr.length > 0) {
            this._subjectsService.removeSubjects(
                this.properties.communityAPI + this.communityId + '/subjects', subjectsToDelete).
            subscribe(res => {
                 this.afterUpdateActions(res);
             },
              error => this.handleUpdateError('System error updating subjects', error)
            );
          }
          // this._router.navigate(['/manage-subjects'], {queryParams: { "communityId": this.communityId}});
      }
      this.resetChange();
    }
  }

  afterUpdateActions(res) {
    this.community.subjects = res['subjects'];
    this.originalSubjects = [];
    for (let i = 0; i < this.community.subjects.length; i++) {
        this.originalSubjects.push(this.community.subjects[i]);
    }
    if (this.community.subjects.length === 0) {
      this.community.subjects.push('');
    }
    this.handleSuccessfulSave('Subjects updated!');
    this.showLoading = false;
  }

  private parseUpdatedSubjects(subjects): {} {
      const parsedSubjects = this.getNonEmptyItems(subjects);
      return parsedSubjects;
  }



  private getNonEmptyItems(data: string[]): string[] {
      const length = data.length;
      const arrayNonEmpty = new Array<string>();
      let j = 0;
      for (let i = 0; i < length; i++) {
          if (this.isEmpty(data[i])) {
          } else if (this.isNonEmpty(data[i])) {
               arrayNonEmpty[j] = data[i];
               j++;
          }
      }
      return arrayNonEmpty;
  }

  private hasFilled(data: any): boolean {
      if (this.isNonEmpty(data) && !this.isEmpty(data)) {
          return true;
      }
      return false;
  }

  private isEmpty(data: string): boolean {
      if (data !== undefined && !data.replace(/\s/g, '').length) {
          return true;
      } else {
          return false;
      }
  }

  private isNonEmpty(data: string): boolean {
      if (data !== undefined && data != null) {
          return true;
      } else {
          return false;
      }
  }

  private hasValidEmail(data: any): boolean {
      const length = data['managers'].length;

      for (let i = 0; i < length; i++) {
          if (!this.emailValidator(data['managers'][i])) {
              // TODO remove console message after final testing
              // console.log("INVALID EMAIL");
              return false;
          }
      }
      // TODO remove console message after final testing
      // console.log("ALL EMAILS ARE VALID");
      return true;
  }

  private emailValidator(email: any): boolean {
      if (email.match('^[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,4}$')) {
          return true;
      } else {
          return false;
      }
  }

  private change() {
      this.hasChanged = true;
      this.successfulSaveMessage = '';
      this.successfulResetMessage = '';
  }

  private resetChange() {
      this.hasChanged = false;
  }

  public get form() {
      return this._fb.group({
          _id : '',
          name : ['', Validators.required]
      });
  }

  public reset() {
      this.myForm.patchValue({
          name : '',
          _id : ''
      });
  }

  handleUpdateError(message: string, error) {
      this.updateErrorMessage = message;
      console.log('Server responded: ' + error);
      this.showLoading = false;
  }

  handleError(message: string, error) {
      this.errorMessage = message;
      console.log('Server responded: ' + error);

      this.showLoading = false;
  }

  handleSuccessfulSave(message) {
      this.showLoading = false;
      this.successfulSaveMessage = message;
  }

  handleSuccessfulReset(message) {
      this.showLoading = false;
      this.successfulResetMessage = message;
  }

  trackByFn(index: any, item: any) {
      return index;
  }
}
