import {
  ChangeDetectorRef,
  Component, EventEmitter,
  Input,
  OnChanges,
  OnDestroy,
  OnInit, Output,
  SimpleChanges,
  ViewChild
} from '@angular/core';
import {AbstractControl, FormBuilder, FormGroup, Validators} from '@angular/forms';
import {AlertModal} from "../../../utils/modal/alert";
import {UserRegistryService} from "../../../services/user-registry.service";
import {EnvProperties} from "../../../utils/properties/env-properties";
import {properties} from "../../../../../environments/environment";
import {Role, Session, User} from "../../../login/utils/helper.class";
import {UserManagementService} from "../../../services/user-management.service";
import {Router} from "@angular/router";
import {SubscriberInviteComponent} from "../../../sharedComponents/subscriber-invite/subscriber-invite.component";
import {Subscription, zip} from "rxjs";

declare var UIkit;

@Component({
  selector: 'subscribers',
  templateUrl: 'subscribers.component.html'
})
export class SubscribersComponent implements OnInit, OnDestroy, OnChanges {
  
  @Input()
  public id: string;
  @Input()
  public type: string;
  @Input()
  public name: string;
  @Input()
  public link: string;
  @Input()
  public message: string = null;
  @Input()
  public inviteDisableMessage: string;
  public user: User = null;
  public subscribers: any[];
  public showSubscribers: any[];
  public subs: any[] = [];
  public loading: boolean = true;
  public selectedUser: string = null;
  public properties: EnvProperties = properties;
  public exists: boolean = true;
  public roleFb: FormGroup;
  /** Paging */
  page: number = 1;
  pageSize: number = 10;
  /** Search */
  filterForm: FormGroup;
  @ViewChild('inviteModal') inviteModal: AlertModal;
  @ViewChild('deleteModal') deleteModal: AlertModal;
  @ViewChild('createRoleModal') createRoleModal: AlertModal;
  @ViewChild('subscriberInvite') subscriberInvite: SubscriberInviteComponent;
  
  constructor(private userRegistryService: UserRegistryService,
              private userManagementService: UserManagementService,
              private router: Router,
              private cdr: ChangeDetectorRef,
              private fb: FormBuilder) {
  }
  
  ngOnInit() {
    this.filterForm = this.fb.group({
      keyword: this.fb.control('')
    });
    this.subs.push(this.filterForm.get('keyword').valueChanges.subscribe(value => {
      if(this.subscribers) {
        this.filterBySearch(value);
      }
    }));
    this.updateList();
    this.userManagementService.getUserInfo().subscribe(user => {
      this.user = user;
      this.cdr.detectChanges();
    });
  }
  
  ngOnChanges(changes: SimpleChanges) {
    if (changes.role) {
      this.updateList();
    }
  }
  
  ngOnDestroy() {
    this.subs.forEach(sub => {
      if (sub instanceof Subscription) {
        sub.unsubscribe();
      }
    });
  }
  
  get currentPage(): any[] {
    if (this.showSubscribers) {
      return this.showSubscribers.slice((this.page - 1) * this.pageSize, this.page * this.pageSize);
    } else {
      return [];
    }
  }
  
  updateList() {
    this.loading = true;
    this.subs.push( this.userRegistryService.getActive(this.type, this.id, 'member', true).subscribe(users => {
      this.subscribers = users;
      this.filterBySearch(this.filterForm.value.keyword);
      this.loading = false;
      this.exists = true;
    }, error => {
      this.subscribers = [];
      this.showSubscribers = [];
      if (error.status === 404) {
        this.exists = false;
      }
      this.loading = false;
    }));
  }
  
  openDeleteModal(item: any) {
    this.selectedUser = item.email;
    this.deleteModal.alertTitle = 'Delete member';
    this.deleteModal.open();
  }
  
  openInviteModal() {
    if(this.subscriberInvite && !this.subscriberInvite.loading) {
      this.inviteModal.alertTitle = 'Invite users to join ' + this.name;
      this.inviteModal.okButtonLeft = false;
      this.inviteModal.okButtonText = 'Send';
      this.subscriberInvite.reset();
      this.inviteModal.open();
    }
  }
  
  openCreateRoleModal() {
    this.createRoleModal.alertTitle = 'Create group';
    this.createRoleModal.okButtonLeft = false;
    this.createRoleModal.okButtonText = 'create';
    this.roleFb = this.fb.group({
      name: this.fb.control(Role.roleName(this.type, this.id), Validators.required),
      description: this.fb.control(Role.roleName(this.type, this.id), Validators.required)
    });
    setTimeout(() => {
      this.roleFb.get('name').disable();
      this.roleFb.get('description').disable();
    }, 0);
    this.createRoleModal.open();
  }
  
  deleteSubscriber() {
    this.loading = true;
    this.userRegistryService.remove(this.type, this.id, this.selectedUser, 'member').subscribe(() => {
      this.subscribers = this.subscribers.filter(user => user.email != this.selectedUser);
      this.filterBySearch(this.filterForm.value.keyword);
      if(this.currentPage.length === 0) {
        this.page = 1;
      }
      this.userManagementService.updateUserInfo();
      UIkit.notification(this.selectedUser + ' <b>is no longer</b> a member of ' + this.name + ' Dashboard', {
        status: 'success',
        timeout: 6000,
        pos: 'bottom-right'
      });
      this.loading = false;
    }, error => {
      UIkit.notification('An error has occurred. Please try again later', {
        status: 'danger',
        timeout: 6000,
        pos: 'bottom-right'
      });
      this.loading = false;
    });
  }
  
  createGroup() {
    this.loading = true;
    this.userRegistryService.createRole(this.type, this.id).subscribe(() => {
      UIkit.notification('Group has been <b> successfully created</b>', {
        status: 'success',
        timeout: 6000,
        pos: 'bottom-right'
      });
      this.updateList();
    }, error => {
      UIkit.notification('An error has occurred. Please try again later', {
        status: 'danger',
        timeout: 6000,
        pos: 'bottom-right'
      });
      this.loading = false;
    });
  }
  
  public get isPortalAdmin() {
    return Session.isPortalAdministrator(this.user) || Session.isCurator(this.type, this.user);
  }
  
  public updatePage(event) {
    this.page = event.value;
  }
  
  private filterBySearch(value: any) {
    this.showSubscribers = this.subscribers.filter(subscriber => !value || subscriber.email.includes(value));
    this.page = 1;
  }
}
