import {Component, Input} from '@angular/core';
import {ActivatedRoute, Router} from '@angular/router';
import {Location, TitleCasePipe} from '@angular/common';
import {DomSanitizer, Meta, Title} from '@angular/platform-browser';
import {EnvProperties} from '../openaireLibrary/utils/properties/env-properties';
import {ErrorCodes} from '../openaireLibrary/utils/properties/errorCodes';
import {StatisticsService} from '../utils/services/statistics.service';
import {ConfigurationService} from '../openaireLibrary/utils/configuration/configuration.service';
import {PiwikService} from '../openaireLibrary/utils/piwik/piwik.service';
import {
  availableCharts,
  availableEntitiesMap,
  StatisticsDisplay,
  StatisticsSummary
} from "../openaireLibrary/connect/statistics/statisticsEntities";
import {CommunityCharts} from "../openaireLibrary/connect/statistics/communityCharts";
import {CommunityService} from "../openaireLibrary/connect/community/community.service";
import {Subscriber, Subscription} from "rxjs";
import {properties} from "../../environments/environment";


@Component({
  selector: 'statistics',
  templateUrl: 'statistics.component.html',
})

export class StatisticsComponent {
  public pageTitle = "OpenAIRE";
  properties: EnvProperties = properties;
  @Input() communityId = null;
  @Input() currentMode = 'showInMonitor';
  communityInfo: any = null;
  entitiesList: string[] = [];
  entitiesMap: Map<string, string> = availableEntitiesMap;
  chartCatsList: string[] = availableCharts;
  //allowedCharts = {};
  allowedCharts: Map<string, string[]> = new Map<string, string[]>();
  allowedEntities: string[] = [];
  //allowedChartsMode = {showInMonitor: {}/, showInDashboard: {}};
  allowedChartsMode = {showInMonitor: new Map<string, string[]>(), showInDashboard: new Map<string, string[]>()};
  allowedEntitiesMode = {showInMonitor: [], showInDashboard: []};
  
  statisticsSum: StatisticsSummary = null;
  statisticsDisplay: StatisticsDisplay = null;
  chartTitlesMode = {showInMonitor: {}, showInDashboard: {}};
  chartsInfoMap: {};
  
  displayedTimeline: string;
  displayedTimelineUrl: string;
  displayedGraph: string;
  displayedGraphUrl: string;
  displayedProjectChart: string;
  displayedProjectChartUrl: string;
  displayedEntity: string;
  public errorCodes: ErrorCodes = new ErrorCodes();
  status = null;
  communityName = null;
  
  subs: Subscription[] = [];
  
  constructor(
    private route: ActivatedRoute,
    private _router: Router,
    private location: Location,
    private _meta: Meta,
    private _title: Title,
    private _piwikService: PiwikService,
    private _statisticsService: StatisticsService,
    private _configService: ConfigurationService,
    private titleCase: TitleCasePipe,
    private _communityService: CommunityService,
    private sanitizer: DomSanitizer) {
    
  }
  
  public ngOnInit() {
    if (this.currentMode == "showInMonitor") {
      var description = "open access, research, scientific publication, European Commission, EC, FP7, ERC, Horizon 2020, H2020, search, projects ";
      var title = "Monitor";
      
      this._title.setTitle(title);
      this._meta.updateTag({content: description}, "name='description'");
      this._meta.updateTag({content: description}, "property='og:description'");
      this._meta.updateTag({content: title}, "property='og:title'");
    }
    var url = properties.domain + properties.baseLink + this._router.url;
    this._meta.updateTag({content: url}, "property='og:url'");
    this.subs.push(this._communityService.getCommunityAsObservable().subscribe(
      community => {
        if(community) {
          this.communityId = community.communityId;
          if (this.currentMode == "showInMonitor") {
            this.subs.push(this._piwikService.trackView(this.properties, "Monitor " + this.communityId).subscribe());
          }
          this.communityName = community.shortTitle;
          this.createChartUrlMap();
          this.createStatisticsObjects();
        }
      }));
    
  }
  
  public ngOnDestroy() {
    for (let sub of this.subs) {
      if (sub instanceof Subscriber) {
        sub.unsubscribe();
      }
    }
  }
  
  getCamelCaseString(inputString: string) {
    return this.titleCase.transform(inputString);
  }
  
  createStatisticsObjects() {
    // console.log(" Stats! "+ this.properties.statisticsAPIURL);
    this.status = this.errorCodes.LOADING;
    this.subs.push(this._statisticsService.getCommunityStatistics(this.properties, this.communityId).subscribe(
      res => {
        if (res) {
          this.statisticsSum = res;
          if (res["other"]) { //hack because in stats API the entity name is "other" while in admin API is "orp". This component uses also "orp" name
            this.statisticsSum["orp"] = res["other"];
          }
          this.getDisplayOptions();
        } else {
          console.error("Error getting community statistics for community with id: " + this.communityId);
          this.status = this.errorCodes.ERROR;
        }
      },
      error => {
        //console.log(error);
        this.handleError("Error getting community statistics for community with id: " + this.communityId, error);
        this.status = this.errorCodes.ERROR;
      }));
  }
  
  getDisplayOptions() {
    this.subs.push(this._statisticsService.getCommunityAdminStatisticsChoices(this.properties, this.communityId)
      .subscribe(
        res => {
          this.statisticsDisplay = res;
          
          this.getCommunityInfo();
          this.status = this.errorCodes.DONE;
          
        },
        error => {
          //console.log(error);
          this.handleError("Error getting community statistics choices by administrators for community with id: " + this.communityId, error);
          this.status = this.errorCodes.ERROR;
        }
      ));
  }
  
  
  getCommunityInfo() {
    // console.log(`calling ${this.properties.adminToolsAPIURL}/communityFull/${this.communityId}`);
    this.subs.push(this._configService.portalAsObservable.subscribe(
      res => {
        this.communityInfo = res;
        /*for(let i=0; i<this.communityInfo.entities.length; i++){

            if (this.communityInfo.entities[i]["isEnabled"] ) {
                this.entitiesList.push(this.communityInfo.entities[i]['pid']);
            }
        }
        console.log(this.entitiesList);*/
        this.initializeDisplayedCharts()
      },
      error => {
        //console.log(error)
        this.handleError("Error getting community with id: " + this.communityId, error);
        this.initializeDisplayedCharts();
      }
    ));
  }
  
  initializeDisplayedCharts() {
    let firstEntity: string;
    this.entitiesList = Array.from(this.entitiesMap.keys());
    
    this.allowedChartsMode[this.currentMode] = this.allowedCharts;
    this.allowedEntitiesMode[this.currentMode] = this.allowedEntities;
    let titles = [];
    // console.log('this.entitiesList is',this.entitiesList);
    // console.log(`my current mode is: ${this.currentMode}`);
    for (let entity of this.entitiesList) {
      if (this.statisticsDisplay.entities[entity] && this.statisticsSum[entity].total && this.communityInfo.entities.filter(x => x['pid'] == entity && x['isEnabled'] === true).length) {
        this.allowedChartsMode.showInDashboard[entity] = [];
        this.allowedChartsMode.showInMonitor[entity] = [];
        for (let chart of this.chartCatsList) {
          if (this.statisticsSum[entity].total &&
            this.statisticsDisplay.entities[entity].charts.map[chart] &&
            this.statisticsDisplay.entities[entity].charts.map[chart]["showInDashboard"] &&
            this.chartsInfoMap[entity + this.getCamelCaseString(chart)].url) {
            this.allowedChartsMode.showInDashboard[entity].push(entity + this.getCamelCaseString(chart));
            if (titles.indexOf("dashboard" + this.chartsInfoMap[entity + this.getCamelCaseString(chart)].title) == -1) {
              titles.push("dashboard" + this.chartsInfoMap[entity + this.getCamelCaseString(chart)].title);
              this.chartTitlesMode.showInDashboard[entity + this.getCamelCaseString(chart)] = true;
            } else {
              this.chartTitlesMode.showInDashboard[entity + this.getCamelCaseString(chart)] = false;
            }
            
            // console.log(`added ${entity} - ${chart} to allowedCharts`);
          }
          if (this.statisticsSum[entity].total &&
            this.statisticsDisplay.entities[entity].charts.map[chart] &&
            this.statisticsDisplay.entities[entity].charts.map[chart]["showInMonitor"] &&
            this.chartsInfoMap[entity + this.getCamelCaseString(chart)].url) {
            this.allowedChartsMode.showInMonitor[entity].push(entity + this.getCamelCaseString(chart));
            if (titles.indexOf("monitor" + this.chartsInfoMap[entity + this.getCamelCaseString(chart)].title) == -1) {
              titles.push("monitor" + this.chartsInfoMap[entity + this.getCamelCaseString(chart)].title);
              this.chartTitlesMode.showInMonitor[entity + this.getCamelCaseString(chart)] = true;
            } else {
              this.chartTitlesMode.showInMonitor[entity + this.getCamelCaseString(chart)] = false;
            }
            // console.log(`added ${entity} - ${chart} to allowedCharts`);
            
          }
        }
        if (this.allowedChartsMode.showInMonitor[entity].length) {
          // console.log(`added ${entity} to allowedEntities`);
          this.allowedEntitiesMode.showInMonitor.push(entity);
          if (!firstEntity) {
            firstEntity = entity;
            this.onChangeEntity(entity);
          }
        }
        if (this.allowedChartsMode.showInDashboard[entity].length) {
          // console.log(`added ${entity} to allowedEntities`);
          this.allowedEntitiesMode.showInDashboard.push(entity);
          if (!firstEntity) {
            firstEntity = entity;
            this.onChangeEntity(entity);
          }
        }
      }
    }
    
  }
  
  createChartUrlMap() {
    
    let communityCharts: CommunityCharts = new CommunityCharts(this.sanitizer);
    this.chartsInfoMap = communityCharts.getChartsForCommunity(this.communityId, this.communityName, this.properties);
  }
  
  
  onChangeEntity(entity: string) {
    this.displayedEntity = entity;
    // console.log(`displayed entity is ${entity}`);
    // console.log(`statisticsSum[${entity}].total is ${this.statisticsSum[entity].total}`);
    
    if (this.statisticsSum[entity].total &&
      this.allowedEntities.filter(x => x == entity).length) {
      
      // console.log(`found ${entity} in allowedEntities`);
      this.displayedTimeline = `${entity}Timeline`;
      this.displayedTimelineUrl = this.chartsInfoMap[this.displayedTimeline].url;
      // console.log(`displayed Timeline is: ${this.displayedTimeline}`);
      this.displayedGraph = `${entity}Graph`;
      this.displayedGraphUrl = this.chartsInfoMap[this.displayedGraph].url;
      // console.log(`displayed Graph is: ${this.displayedGraph}`);
      if (this.allowedCharts[entity]) {
        let firstProjectChart = this.allowedCharts[entity].filter(x => x.includes(entity + 'Project'));
        if (firstProjectChart[0]) {
          this.changeDisplayedProjectChart(firstProjectChart[0]);
        } else {
          this.displayedProjectChart = '';
          this.displayedProjectChartUrl = '';
          // console.log(`displayed ProjectChart is: ${this.displayedProjectChart}`);
        }
      }
    } else {
      this.displayedTimeline = '';
      this.displayedTimelineUrl = '';
      // console.log(`displayed Timeline is: ${this.displayedTimeline}`);
      this.displayedGraph = '';
      this.displayedGraphUrl = '';
      // console.log(`displayed Graph is: ${this.displayedGraph}`);
    }
  }
  
  changeDisplayedProjectChart(chartName: string) {
    this.displayedProjectChart = chartName;
    this.displayedProjectChartUrl = this.chartsInfoMap[this.displayedProjectChart].url;
    // console.log(`displayed ProjectChart is: ${this.displayedProjectChart}`);
  }
  
  private handleError(message: string, error) {
    console.error("Statistics (Monitor) Page: " + message, error);
  }
}


@Component({
  selector: 'statistics-for-dashboard',
  template: ''
  // templateUrl: 'statistics-for-dashboard.component.html',
})

export class StatisticsForDashboardComponent extends StatisticsComponent {
  ngOnInit() {
    super.ngOnInit();
  }
  
}
