import {Component, EventEmitter, Input, Output, ViewChild} from '@angular/core';
import {ActivatedRoute, Router} from '@angular/router';
import {EnvProperties} from '../../openaireLibrary/utils/properties/env-properties';
import {AlertModal} from '../../openaireLibrary/utils/modal/alert';

import {CommunityService} from '../../openaireLibrary/connect/community/community.service';
import {EmailService} from "../../openaireLibrary/utils/email/email.service";
import {Session, User} from '../../openaireLibrary/login/utils/helper.class';

import {Email} from "../../openaireLibrary/utils/email/email";
import {Composer} from "../../openaireLibrary/utils/email/composer";
import {LoginErrorCodes} from '../../openaireLibrary/login/utils/guardHelper.class';
import {UserManagementService} from "../../openaireLibrary/services/user-management.service";
import {Subscriber, Subscription} from "rxjs";
import {properties} from "../../../environments/environment";
import {UserRegistryService} from "../../openaireLibrary/services/user-registry.service";
import {SubscribeService} from "../../openaireLibrary/utils/subscribe/subscribe.service";
import {NotificationHandler} from "../../openaireLibrary/utils/notification-handler";

@Component({
  selector: 'subscribe',
  template: `
    <span *ngIf="subscribed != null && !showNumbers && showTemplate">
      <div *ngIf="!subscribed && showLoginAlert" class="uk-alert-warning uk-animation-slide-bottom" uk-alert="">
        <a class="uk-alert-close" uk-close></a>
        <p>Please login first to join</p>
      </div>
      <button *ngIf="loading" id="join" class="uk-button uk-flex uk-flex-column uk-flex-center uk-flex-middle">
        <span class="uk-icon"><loading [top_margin]="false" [size]="'small'" [color]="null"></loading></span>
      </button>
<!--      uk-box-shadow-large-->
      <button *ngIf="!subscribed && !loading" id="join" class="uk-button uk-flex uk-flex-middle uk-flex-center"
              (click)="subscribe()">
        <icon name="group" [flex]="true"></icon>
        <span class="uk-margin-small-left">Join</span>
      </button>
      <button *ngIf="subscribed && !loading" id="member" class="uk-button uk-flex uk-flex-middle uk-flex-center"
              (click)="confirmOpen()" [disabled]="isManager" [attr.uk-tooltip]="isManager?'You are automatically a member because you are a manager':null">
        <icon name="group" [flex]="true"></icon>
        <span class="uk-margin-small-left">Member</span>
      </button>
    </span>
    <span *ngIf="showNumbers && members > 0  && showTemplate" class="uk-display-inline-block">
      <span class="uk-text-meta">Members: </span> {{members}}
    </span>
    <modal-alert (alertOutput)="confirmClose($event)" [overflowBody]="false">
    </modal-alert>
  `
})
export class SubscribeComponent {
  // @Input() showSubscribe:boolean = true;
  @Input() showNumbers: boolean;
  @Input() communityId: string;
  @Input() showTemplate: boolean = true;
  @Output() subscribeEvent = new EventEmitter();
  
  public community = null;
  public emailToInformManagers: Email;
  
  loading: boolean = false;
  subscribed: boolean = null;
  properties: EnvProperties = properties;
  members: number = 0;
  @Output() countSubscribersEvent = new EventEmitter();
  showLoginAlert: Boolean = false;
  @ViewChild(AlertModal, { static: true }) alert;
  private user: User;
  
  subs: Subscription[] = [];
  
  constructor(private route: ActivatedRoute,
              private _emailService: EmailService,
              private _communityService: CommunityService,
              private router: Router,
              private subscribeService: SubscribeService,
              private userManagementService: UserManagementService,
              private userRegistryService: UserRegistryService) {
  }
  
  public ngOnInit() {
    this.subs.push(this.subscribeService.getLoading().subscribe(loading => {
      this.loading = loading;
    }));
    this.subs.push(this.subscribeService.getMembers().subscribe(members => {
      this.members = members;
      this.countSubscribersEvent.emit({
        value: this.members
      });
    }));
    if (!this.showNumbers) {
      this.subs.push(this.userManagementService.getUserInfo().subscribe(
        user => {
          this.user = user;
          this.init();
        }
      ));
    } else {
      this.init();
    }
  }
  
  public ngOnDestroy() {
    for (let sub of this.subs) {
      if (sub instanceof Subscriber) {
        sub.unsubscribe();
      }
    }
    this.subscribeService.setLoading(false);
  }
  
  public isSubscribed() {
    this.subscribed = Session.isSubscribedTo('community', this.communityId, this.user);
  }
  
  public get isManager() {
    return Session.isManager('community', this.communityId, this.user);
  }
  
  private init() {
    if (!this.showNumbers) {
      let email = (this.user) ? this.user.email : null;
      if (email == null) {
        this.subscribed = false;
      } else {
        if (this.communityId) {
          this.isSubscribed();
        }
      }
    } else {
      if (this.communityId) {
        this.subscribeService.setLoading(true);
        this.subs.push(this.userRegistryService.getMembersCount('community', this.communityId).subscribe(res => {
            this.subscribeService.setMembers((res && res.response) ? res.response : 0);
            this.subscribeService.setLoading(false);
          },
          error => {
            this.handleError("Error getting community subscribers for community with id: " + this.communityId, error);
          }));
      }
    }
    if (this.communityId) {
      this.emailToInformManagers = {body: "", subject: "", recipients: []};
      this.subs.push(this._communityService.getCommunityAsObservable().subscribe(
        community => {
          this.community = community;
        },
        error => {
          //console.log('System error retrieving community profile', error)
          this.handleError("Error getting community with id: " + this.communityId, error);
        }
      ));
    }
  }
  
  private successfulSubscribe() {
    if (!this.subscribed) {
      this.subscribed = true;
      this.subscribeEvent.emit({
        value: "ok"
      });
      this.subs.push(this._emailService.notifyManagers(this.communityId, 'subscriber',
        Composer.composeEmailToInformManagers(this.community.title, this.communityId, this.user.fullname)).subscribe(
        res => {
          //console.log("The email has been sent successfully!")
        },
        error => {
          //console.log(error)
          this.handleError("Error notifying managers about new subscribers for community with id: " + this.communityId, error);
        }
      ));
    }
  }
  
  subscribe() {
    if (!this.user) {
      this.subscribed = false;
      // this.showLoginAlert = true;
      this.router.navigate(['/user-info'], {
        queryParams: {
          "errorCode": LoginErrorCodes.ACTION_REQUIRES_LOGIN,
          "redirectUrl": this.router.url
        }
      });
    } else {
      this.subscribeService.setLoading(true);
      this.showLoginAlert = false;
      this.subs.push(this.userRegistryService.subscribeTo('community', this.communityId).subscribe(res => {
        this.userManagementService.updateUserInfo();
        this.subscribeService.setMembers(this.members + 1);
        this.subscribeService.setLoading(false);
        this.successfulSubscribe();
      }, error => {
        this.subscribeService.setLoading(false);
        NotificationHandler.rise('>An error occurred. Please try again!', 'danger');
        //console.log(error)
        this.handleError("Error subscribing email: " + this.user.email + " from community with id: " + this.communityId, error);
      }));
    }
  }
  
  unsubscribe() {
    var email = (this.user) ? this.user.email : null;
    if (email == null) {
      this.subscribed = false;
    } else {
      this.subscribeService.setLoading(true);
      this.subs.push(this.userRegistryService.unsubscribeFrom('community', this.communityId).subscribe(res => {
        this.userManagementService.updateUserInfo();
        this.subscribeService.setMembers(this.members - 1);
        this.subscribeService.setLoading(false);
        this.subscribed = false;
      }, error => {
        this.subscribeService.setLoading(false);
        NotificationHandler.rise('>An error occurred. Please try again!', 'danger');
        //console.log(error)
        this.handleError("Error unsubscribing email: " + email + " from community with id: " + this.communityId, error);
      }));
    }
  }
  
  confirmOpen() {
    
    this.alert.cancelButton = true;
    this.alert.okButton = true;
    this.alert.alertTitle = "Leave community ";
    //this.alert.message = "Do you want to proceed? ";
    this.alert.message = "You are a member of the Community Gateway. Do you want to leave?";
    this.alert.okButtonText = "LEAVE";
    this.alert.cancelButtonText = "CANCEL";
    this.alert.open();
  }
  
  confirmClose(data) {
    this.unsubscribe();
  }
  
  private handleError(message: string, error) {
    console.error("Subscribe (component): " + message, error);
  }
}
