import {Injectable} from "@angular/core";
import {HttpClient} from "@angular/common/http";
import {BehaviorSubject, Observable} from "rxjs";
import {Indicator, IndicatorPath, Stakeholder} from "../utils/entities/stakeholder";
import {HelperFunctions} from "../openaireLibrary/utils/HelperFunctions.class";
import {map} from "rxjs/operators";
import {StakeholderCreator} from "../utils/entities/stakeholderCreator";

let maps: string[] = ['parameters', 'filters'];

@Injectable({
  providedIn: "root"
})
export class StakeholderService {

  private stakeholderSubject: BehaviorSubject<Stakeholder> = null;

  constructor(private http: HttpClient) {
    this.stakeholderSubject = new BehaviorSubject<Stakeholder>(null);
  }

  getStakeholder(url: string, alias:string): Observable<Stakeholder> {
    /*return new BehaviorSubject<Stakeholder>(
      StakeholderCreator.createFunderFromDefaultProfile("ec","funder","ec__________::EC",
        "European Commission","EC",
        false,"ec",true,true)).asObservable();*/
    return this.http.get<Stakeholder>(url + '/stakeholder/' + encodeURIComponent(alias)).pipe(map(stakeholder => {
      return this.formalize(stakeholder);
    }));
  }

  getAllStakeholders(url: string, type: string = null): Observable<Stakeholder[]> {
    return this.http.get<Stakeholder[]>(url + '/stakeholder/all' + ((type)?('?type=' + type):'')).pipe(map(stakeholders => {
      return this.formalize(stakeholders);
    }));
  }

  getStakeholders(url: string, type: string = null): Observable<Stakeholder[]> {
    return this.http.get<Stakeholder[]>(url + '/stakeholder' + ((type)?('?type=' + type):'')).pipe(map(stakeholders => {
      return this.formalize(stakeholders);
    }));
  }

  getDefaultStakeholders(url: string, type: string = null): Observable<Stakeholder[]> {
    return this.http.get<Stakeholder[]>(url + '/stakeholder/default' + ((type)?('?type=' + type):'')).pipe(map(stakeholders => {
      return this.formalize(stakeholders);
    }));
  }

  buildStakeholder(url: string, stakeholder: Stakeholder): Observable<Stakeholder> {
    return this.http.post<Stakeholder>(url + '/build-stakeholder', stakeholder).pipe(map(stakeholder => {
      return this.formalize(stakeholder);
    }));
  }

  saveStakeholder(url: string, stakeholder: Stakeholder): Observable<Stakeholder> {
    return this.http.post<Stakeholder>(url + '/stakeholder/save', stakeholder).pipe(map(stakeholder => {
      return this.formalize(stakeholder);
    }));
  }

  saveElement(url: string, element: any, path: string[] = []): Observable<any> {
    path = HelperFunctions.encodeArray(path);
    return this.http.post<any>(url + ((path.length > 0)?'/':'') + path.join('/') +
      '/save', element).pipe(map(element => {
        return this.formalize(element);
    }));
  }

  deleteElement(url: string, path: string[]): Observable<any> {
    path = HelperFunctions.encodeArray(path);
    return this.http.delete<any>(url + '/' + path.join('/') + '/delete');
  }

  reorderIndicators(url: string, path: string[], indicatorIds: string[], type: string = 'chart'): Observable<Indicator[]> {
    path = HelperFunctions.encodeArray(path);
    return this.http.post<Indicator[]>(url + '/' + path.join('/') + '/' + type + '/reorder', indicatorIds).pipe(map(indicators => {
      return this.formalize(indicators);
    }));
  }

  getStakeholderAsObservable(): Observable<Stakeholder> {
    return this.stakeholderSubject.asObservable();
  }

  get stakeholder(): Stakeholder {
    return this.stakeholderSubject.getValue();
  }

  setStakeholder(stakeholder: Stakeholder) {
    this.stakeholderSubject.next(stakeholder);
  }

  private formalize(element: any) {
    return HelperFunctions.copy(element);
  }
}
