import {ChangeDetectorRef, Directive, OnInit} from "@angular/core";
import {StakeholderBaseComponent} from "../openaireLibrary/monitor-admin/utils/stakeholder-base.component";
import {StakeholderType} from "../openaireLibrary/monitor/entities/stakeholder";
import {Option} from "../openaireLibrary/sharedComponents/input/input.component";
import {FormBuilder, FormControl} from "@angular/forms";
import {debounceTime, distinctUntilChanged} from "rxjs/operators";
import {HelperFunctions} from "../openaireLibrary/utils/HelperFunctions.class";
import {LayoutService} from "../openaireLibrary/dashboard/sharedComponents/sidebar/layout.service";
import {IrishMonitorService} from "./irish-monitor.service";
import {StakeholderPublication} from "./irish";
import {OpenaireEntities} from "../openaireLibrary/utils/properties/searchFields";

@Directive()
export class BrowseStakeholderBaseComponent extends StakeholderBaseComponent implements OnInit {
  openaireEntities = OpenaireEntities;
  stakeholderType: StakeholderType;
  stakeholders: StakeholderPublication[] = [];
  filteredStakeholders: StakeholderPublication[] = [];
  showLoading: boolean = true;
  isMobile: boolean = false;

  gridView: boolean = true;
  sortOptions: Option[] = [
    {value: null, label: 'Number of Publications'},
    {value: 'alphAsc', label: 'Alphabetically Asc. (A-Z)'},
    {value: 'alphDsc', label: 'Alphabetically Dsc. (Z-A)'},
    /*{value: 'oaDsc', label: '"Open Access %" Dsc.'}*/
  ];
  pageOptions: number[] = [10, 20, 30, 40];
  sortBy: string = null;
  currentPage: number = 1;
  pageSize: number = 10;
  parameters = {};
  keywordControl: FormControl;
  hasPublications: boolean = true;

  /* Services */
  protected irishMonitorService: IrishMonitorService;
  protected layoutService: LayoutService;
  protected cdr: ChangeDetectorRef;
  protected fb: FormBuilder;

  constructor() {
    super();
  }

  ngOnInit() {
    this.keywordControl = this.fb.control(this._route.snapshot.queryParams.keyword);
    this.subscriptions.push(this.layoutService.isMobile.subscribe(isMobile => {
      this.isMobile = isMobile;
      this.cdr.detectChanges();
    }));
    this.stakeholderType = this._route.snapshot.data.type;
    if(!this.stakeholderType) {
      this.navigateToError();
    }
    this.subscriptions.push(this.irishMonitorService.getStakeholdersWithPublications(this.stakeholderType).subscribe(stakeholders => {
      this.stakeholders = stakeholders;
      this.filteredStakeholders = stakeholders;
      this.hasPublications = this.stakeholders.length > 0 && this.stakeholders.filter(stakeholder => stakeholder.publications > 0).length > 0;
      if(!this.hasPublications) {
        this.sortBy = 'alphAsc';
        this.sortOptions = this.sortOptions.filter(option => !!option.value);
      }
      this.sortByChanged();
      this.filtering(this.keywordControl.value);
    }));
    this.subscriptions.push(this.keywordControl.valueChanges.pipe(debounceTime(200), distinctUntilChanged()).subscribe(value => {
      this.filtering(value);
      if(value?.length > 0) {
        this.parameters['keyword'] = value;
      } else {
        delete this.parameters['keyword']
      }
      this._router.navigate([], {queryParams: this.parameters});
    }));
  }

  private filtering(value) {
    if(!value){
      this.filteredStakeholders = this.stakeholders;
    } else {
      this.filteredStakeholders = this.stakeholders.filter(item => (item['name'] && item['name'].toLowerCase().includes(value.toLowerCase())) || (item['alias'] && item['alias'].toLowerCase().includes(value.toLowerCase())));
    }
    this.afterStakeholdersInitialized();
    this.currentPage = 1;
  }

  sortByChanged() {
    switch(this.sortBy) {
      case 'alphAsc':
        this.stakeholders = this.stakeholders.sort((a, b) => a['name'].localeCompare(b['name']));
        break;
      case 'alphDsc':
        this.stakeholders = this.stakeholders.sort((a, b) => b['name'].localeCompare(a['name']));
        break;
      default:
        this.stakeholders = this.stakeholders.sort((a, b) => b.publications - a.publications);
        break;
    }
  }

  sizeChanged($event) {
    this.pageSize = $event;
    this.currentPage = 1;
    this.afterStakeholdersInitialized();
  }

  updateCurrentPage($event) {
    this.currentPage = $event.value;
    HelperFunctions.scrollToId('target');
    this.afterStakeholdersInitialized();
  }

  get typeAsLabel() {
    return this.stakeholderUtils.types.find(type => type.value === this.stakeholderType).label;
  }
  
  afterStakeholdersInitialized() {
    // this is a method that will be overriden from the components extending this base component, if needed
    this.showLoading = false;
  }
}
