import {Component, Input, ViewChild} from '@angular/core';
import {Router} from '@angular/router';
import {ContextsService} from './service/contexts.service';
import {ClaimEntity, ShowOptions} from './claimHelper.class';
import {EnvProperties} from '../../utils/properties/env-properties';
import {Subscriber} from "rxjs";
import {OpenaireEntities} from "../../utils/properties/searchFields";
import {CommunitiesService} from "../../connect/communities/communities.service";
import {UserManagementService} from "../../services/user-management.service";
import {Session} from "../../login/utils/helper.class";

declare var UIkit: any;

@Component({
  selector: 'claim-contexts-search-form',
  templateUrl: 'claimContextSearchForm.component.html'

})
export class ClaimContextSearchFormComponent {
  @Input() public centerAlign: boolean = false;
  @Input() public results:ClaimEntity[];
  @Input() public sources;
  @Input() public properties: EnvProperties;
  @Input() communityId: string = null;
  @Input() public inlineClaim: boolean = false;
  @Input() basketLimit;
  @Input() showOptions:ShowOptions;
  @ViewChild('modal') modal;
  modalClicked = false;
  public selectedCommunityId: string = "0";
  public selectedCategoryId: string = "0";
  public query = '';
  public communities: any;
  public selectedCommunityLabel: string = "Community:";

  public categories: any = [];
  public concepts = [];
  public conceptsClass = [];
  public conceptsClassDisplay = [];
  public conceptsCategoryLoading = [];
  public warningMessage = "";
  public infoMessage = "";
  public loading: boolean = false;
  public error: boolean = false;
  @Input() localStoragePrefix: string = "";
  openaireEntities = OpenaireEntities;
  entitiesSelectOptions;
  keyword = "";
  subscriptions = [];
  communityLogos = {};
  communityIds = [];
  user = null;
  ngOnInit() {
    this.entitiesSelectOptions = this.showOptions.selectOptions;
    //get community logos
    this.subscriptions.push(this.userManagementService.getUserInfo().subscribe(user => {
      this.user = user;

    this.subscriptions.push(this._communitiesService.getCommunities(this.properties, this.properties.communityAPI+"/communities/").subscribe(
      communitiesResults => {
        if(communitiesResults!=null) {
          this.communityLogos = {};
          for (let community of communitiesResults) {
            if(community.logoUrl && community.logoUrl.length > 0) {
              this.communityLogos[community.communityId] = community;
            }
          }
          this.communityIds = communitiesResults.filter(community => {
            return community.claim == "all" ||
              Session.isCommunityCurator(this.user) ||
              Session.isClaimsCurator(this.user) ||
              (community.claim == "membersOnly"  && Session.isSubscribedTo("community", community.communityId,this.user)) ||
              (community.claim == "managersOnly"  && Session.isManager("community", community.communityId,this.user))
          }).map(community => community.communityId);
          this.getCommunities();
        }
      },
      error => {
        this.getCommunities();
      }
    ));

    }, error => {

    }));
  
  }
  ngOnDestroy() {
    this.subscriptions.forEach(subscription => {
      if (subscription instanceof Subscriber) {
        subscription.unsubscribe();
      }
    });
  }
  constructor(private _contextService: ContextsService, private router: Router, private _communitiesService: CommunitiesService,  private userManagementService: UserManagementService,) {

  }

  filter() {
    return this.communities?this.communities.filter(community => this.keyword.length ==0 || community.label.toLowerCase().indexOf(this.keyword.toLowerCase()) != -1):[];
  }
  remove(community: any) {
    this.selectedCommunityId = community.id;
    this.selectedCommunityLabel = community.label;
    this.getCategories();
    this.removeById(community.id);
    this.openModal();
  }
  removeById(id) {
    let index: number = -1;
    for (let _i = 0; _i < this.results.length; _i++) {
      let item = this.results[_i];
      if (item.id == id) {
        index = _i;
      }
    }

    if (index > -1) {
      this.results.splice(index, 1);
      if (this.results != null) {
        localStorage.setItem(this.localStoragePrefix, JSON.stringify(this.results));
      }
      UIkit.notification(OpenaireEntities.COMMUNITY + ' removed from your basket!', {
        status: 'warning',
        timeout: 4000,
        pos: 'bottom-right'
      });
    }

  }
  select(communityId, communityLabel) {
    console.log("SELECT", communityId)
    this.selectedCommunityId = communityId;
    this.selectedCommunityLabel = communityLabel;
    this.getCategories();
    if (this.isSelected(communityId)) {
      this.removeById(communityId);
    } else {
      this.addNewContext(communityLabel, null, {'id': communityId, 'label': communityLabel});
    }
  }

  public openModal() {
    this.modalClicked = true;
    this.modal.cancelButton = false;
    this.modal.okButton = false;
    this.modal.alertTitle =  this.selectedCommunityLabel;
    this.modal.open();
  }


  isSelected(id): boolean {
    for (let _i = 0; _i < this.results.length; _i++) {
      let item = this.results[_i];
      if (item.id == id) {
        return true;
        // this.warningMessage = "Concept already in selected list";
      }
    }
    return false;
  }
  getClaimEntity(community, category, concept){
    const entity: ClaimEntity = new ClaimEntity() ;
    entity.type = "community";
    entity.context = {community: community, category: category, concept: concept};
    entity.id = entity.context.concept.id;
    return entity;
  }
  addNewContext(community, category, concept, notify = true) {
    const entity: ClaimEntity = this.getClaimEntity(community, category, concept) ;
    this.warningMessage = "";
    if (!this.isSelected(entity.id)) {
      this.results.push(entity);
      localStorage.setItem(this.localStoragePrefix, JSON.stringify(this.results));
      UIkit.notification(OpenaireEntities.COMMUNITY + ' added in your basket!', {
        status: 'success',
        timeout: 4000,
        pos: 'bottom-right'
      });
    }

  }

  getCommunities() {
      this.loading = true;
      this.subscriptions.push(this._contextService.getCommunitiesByState().subscribe(
        data => {
          this.communities = data.filter(community => {
            return this.communityIds.indexOf(community.id) != -1
          });
          if (this.communities.length > 0) {
            this.communities.sort((n1, n2) => n1.title > n2.title);
          }
          this.loading = false;
          if (this.communityId != null && this.communityIds.indexOf(this.communityId) != -1) {
            //preselect community
            this.selectedCommunityId = this.communityId;
            for (let i = 0; i < this.communities.length; i++) {
              if (this.communities[i].id == this.selectedCommunityId) {
                this.selectedCommunityLabel = this.communities[i].label;
                break;
              }
            }
            this.addNewContext(this.selectedCommunityLabel, null, {
              'id': this.selectedCommunityId,
              'label': this.selectedCommunityLabel
            }, false)

          }
        },
        err => {
          //console.log(err);
          ClaimContextSearchFormComponent.handleError("Error getting communities", err);
          this.loading = false;
          this.error = true;
        }
      ));

  }

  getCategories() {
    this.loading = true;
    // this.categories=[];
    if (this.selectedCommunityId != '0') {

        if (this.categories[this.selectedCommunityId]) {
          this.loading = false;
          if(this.categories[this.selectedCommunityId].length > 0){
            this.openModal()
          }
          return;
        }
        this.subscriptions.push(this._contextService.getCategories(this.selectedCommunityId, this.properties.contextsAPI).subscribe(
          data => {
            if(data.length > 0){
              this.openModal()
            }
            this.categories[this.selectedCommunityId] = data;
            this.concepts = [];
            if (this.query !== "") {
              const event = {value: ""};
              event.value = this.query;
            }
            this.loading = false;
          },
          err => {
            //console.log(err);
            ClaimContextSearchFormComponent.handleError("Error getting categories for community with id: " + this.selectedCommunityId, err);
            this.loading = false;
          }
        ));
      }

  }
  
  displaySubcategory(id) {
    if (this.conceptsClassDisplay[id] != null) {
      this.conceptsClassDisplay[id] = !this.conceptsClassDisplay[id];

    } else {
      this.conceptsClassDisplay[id] = true;
    }
  }

  browseConcepts(categoryId) {
      if (this.conceptsClass[categoryId] != null) {
        this.conceptsClassDisplay[categoryId] = !this.conceptsClassDisplay[categoryId];
        return;
      } else {
        this.conceptsClassDisplay[categoryId] = true;
      }
      this.conceptsClass[categoryId] = [];
      this.conceptsCategoryLoading[categoryId] = true;
      this.subscriptions.push(this._contextService.getConcepts(categoryId, "", false, this.properties.contextsAPI).subscribe(
        data => {
          // var concepts = data;
          this.conceptsClass[categoryId] = [];
          for (let i = 0; i < data.length; i++) {
            if (data[i].hasSubConcept == true) {
              this.browseSubConcepts(categoryId, data[i].id);
            } else {
              this.conceptsClass[categoryId].push(data[i]);
            }
          }
          this.conceptsCategoryLoading[categoryId] = false;
        },
        err => {
          //console.log(err);
          ClaimContextSearchFormComponent.handleError("Error getting concepts for category with id: " + this.selectedCategoryId, err);
          this.conceptsCategoryLoading[categoryId] = false;
        }
      ));
  }

  browseSubConcepts(categoryId, conceptId) {

    this.conceptsCategoryLoading[categoryId] = true;
    this.subscriptions.push(this._contextService.getSubConcepts(conceptId, "", false, this.properties.contextsAPI).subscribe(
      data => {
        const concepts = data[0];
        this.conceptsClass[categoryId].push(concepts);
        this.conceptsCategoryLoading[categoryId] = false;
      },
      err => {
        //console.log(err);
        ClaimContextSearchFormComponent.handleError("Error getting subconcepts for concept with id: " + conceptId, err);
        this.conceptsCategoryLoading[categoryId] = false;
      }
    ));


  }

  private static handleError(message: string, error) {
    console.error("Claim context search form (component): " + message, error);
  }
}
