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 {SubscribeService} from '../../../openaireLibrary/utils/subscribe/subscribe.service';
import {EmailService} from '../../../openaireLibrary/utils/email/email.service';

import {EnvProperties} from '../../../openaireLibrary/utils/properties/env-properties';
import {Email} from '../../../openaireLibrary/utils/email/email';
import {Composer} from '../../../openaireLibrary/utils/email/composer';
import {Validator} from '../../../openaireLibrary/utils/email/validator';

import {Session} from '../../../openaireLibrary/login/utils/helper.class';
import {LoginErrorCodes} from '../../../openaireLibrary/login/utils/guardHelper.class';
import {HelperFunctions} from "../../../openaireLibrary/utils/HelperFunctions.class";
import {Title} from '@angular/platform-browser';

@Component({
    selector: 'community-edit-form',
    templateUrl: './community-edit-form.component.html',
})

export class CommunityEditFormComponent 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 firstVersionOfManagers: string[];
    public newManagersToSubscribe: string[];

    public email: Email;

    public emailToInform: Email;

    public note = '';

    public properties: EnvProperties = null;

    constructor (private element: ElementRef,
                 private title: Title,
                 private route: ActivatedRoute,
                 private _router: Router,
                 public _fb: FormBuilder,
                 private _helpContentService: HelpContentService,
                 private _communityService: CommunityService,
                 private _subscribeService: SubscribeService,
                 private _emailService: EmailService) { }


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

                    this.email = {body: '', subject: '', recipients: []};
                    this.emailToInform = {body: '', subject: '', recipients: []};

                    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.firstVersionOfManagers = community.managers.slice();
                                  this.showLoading = false;
                            },
                            error => this.handleError('System error retrieving community profile', error)
                          );
                      }
                    }
             });
        });
    }

    public addManager() {
            this.community.managers.push('');
    }

    public removeManager(i: any) {
            this.community.managers.splice(i, 1);
    }

    // public addSubject() {
    //         this.community.subjects.push("");
    // }
    //
    // public removeSubject(i : any) {
    //         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 updateCommunity() {
      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 community = this.parseUpdatedCommunity();

            if (!Validator.hasValidEmails(community['managers']) || !this.hasFilled(community['name'])) {
                this._router.navigate(['/community-edit-form'], {
                    queryParams: { 'communityId': this.communityId}});
            } else {
                const newManagers = this.getNewManagers();
                this._communityService.updateCommunity(
                    this.properties.communityAPI + this.communityId, community).subscribe(

                    community => {
                        if (newManagers !== null) {
                            this.sendMailToNewManagers(newManagers);
                            this.informOldManagersForTheNewOnes();
                            for (let i = 0; i < newManagers.length; i++) {
                                this._subscribeService.subscribeToCommunityByEmail(this.properties, this.communityId, newManagers[i]).subscribe(
                                    res => {
                                        // console.log(res);
                                    }
                                );
                                this._subscribeService.getCommunitySubscribers
                                (this.properties, this.communityId).subscribe(
                                    res => {
                                        // console.log(res);
                                    }
                                );
                            }
                        }
                        this.handleSuccessfulSave('Community saved!');
                    },
                    error => {
                        this.handleUpdateError('System error updating community profile', error);
                    },
                    () => { this.firstVersionOfManagers = this.community['managers'].slice(); }
                );
                this._router.navigate(['/community-edit-form'], {
                    queryParams: { 'communityId': this.communityId}});
            }
        }
        this.resetChange();
      }
    }


    private parseUpdatedCommunity(): {} {
        const community = {};

        community['name'] = this.community.title;
        community['shortName'] = this.community.shortTitle;
        community['status'] = this.community.status;
        community['description'] = this.community.description;
        community['logoUrl'] = this.community.logoUrl;

        community['managers'] = new Array<string>();
        this.community.managers = this.getNonEmptyItems(this.community.managers);
        community['managers'] = this.community.managers;

        return community;
    }

    private getNewManagers(): Array<string> {

        let newManagers = null;
        for (let i = 0; i < this.community['managers'].length; i++) {
            if (!this.firstVersionOfManagers.includes(this.community['managers'][i])) {
                if(newManagers ===  null) {
                    newManagers = new Array<string>();
                }
                newManagers.push(this.community['managers'][i]);
            }
        }
        return newManagers;
    }

    private sendMailToNewManagers(managers: any) {
        this._emailService.sendEmail(this.properties,
                                     Composer.composeEmailForNewManager(this.communityId,
                                         this.community.title, managers)).subscribe(
              res => {
                // console.log("The email has been sent successfully!")
              },
              error => console.log(error)
        );
    }

    private informOldManagersForTheNewOnes() {
        this._emailService.notifyForNewManagers(
            this.properties, this.communityId,
                                     Composer.composeEmailToInformOldManagersForTheNewOnes(this.community.title, this.communityId,
                                                                                           this.firstVersionOfManagers,
                                                                                           this.community.managers)).subscribe(
              res => {
                // console.log("The email has been sent successfully!")
              },
              error => console.log(error)
        );
    }

    private subscribeNewManagers(newManagers: string[]): boolean {
        return true;
    }

    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])) {
                 // console.log(data[i]);
            } else if (this.isNonEmpty(data[i])) {
                 arrayNonEmpty[j] = data[i];
                 j++;
                 // console.log(data[i]);
            }
        }
        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 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;
    }
}
