import {Component, OnInit, ElementRef} from '@angular/core';
import {HelpContentService} from '../../services/help-content.service';
import {ActivatedRoute, Router} from '@angular/router';
import {EnvProperties} from '../../openaireLibrary/utils/properties/env-properties';
import { Community } from '../../domain/community';
import {DomSanitizer, Title} from '@angular/platform-browser';
import {TitleCasePipe} from '@angular/common';
import {availableEntitiesMap, StatisticsDisplay, StatisticsSummary} from '../../openaireLibrary/connect/statistics/statisticsEntities';
import {ConfigurationService} from '../../openaireLibrary/utils/configuration/configuration.service';

import {Session} from '../../openaireLibrary/login/utils/helper.class';
import {LoginErrorCodes} from '../../openaireLibrary/login/utils/guardHelper.class';
import {HelperFunctions} from "../../openaireLibrary/utils/HelperFunctions.class";
import {CommunityCharts} from '../../openaireLibrary/connect/statistics/communityCharts';

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

export class StatsComponent implements OnInit {
    // errorMessage: string;
    // loadingMessage: string;
    public showLoading: boolean = true;
    public errorMessage: string = '';
    public updateErrorMessage: string = '';

    communities: Community[] = [];
    communityId: string;
    communityInfo = null;
    deactivatedEntity: boolean;

    displayedTimeline: string;
    displayedGraph: string;
    displayedProjectChart: string;
    displayedEntity: string;

    entitiesList: string[] = [];
    entitiesMap: Map<string, string> = availableEntitiesMap;

    statisticsSum: StatisticsSummary;
    statisticsDisplay: StatisticsDisplay;
    chartsInfoMap: {};

    showAllInMonitor: boolean = false;
    showAllInDashboard: boolean = false;

    public properties: EnvProperties = null;
  private communityName = null;

    constructor(private element: ElementRef,
                private contentService: HelpContentService,
                private configService: ConfigurationService,
                private route: ActivatedRoute,
                private _router: Router,
                private title: Title,
                private sanitizer: DomSanitizer,
                private titleCase: TitleCasePipe) {}

    ngOnInit() {
        this.route.data
            .subscribe((data: { envSpecific: EnvProperties }) => {
                this.properties = data.envSpecific;
                    this.route.queryParams.subscribe(
                        params => {
                            HelperFunctions.scroll();
                            this.title.setTitle('Administration Dashboard | Statistics');
                            this.communityId = params['communityId'];
                            this.getStatistics();
                        });
                },
                error => console.log(`E R R O R!!`)
            );
    }

    getStatistics() {
      if(!Session.isLoggedIn()){
        this._router.navigate(['/user-info'], { queryParams: { "errorCode": LoginErrorCodes.NOT_VALID, "redirectUrl":  this._router.url} });
      } else {
        // this.loadingMessage = 'Retrieving statistics';
        // this.errorMessage = '';
        this.showLoading = true;
        this.updateErrorMessage = "";
        this.errorMessage = "";

        this.statisticsSum = null;
        this.statisticsDisplay = null;
        this.contentService.getCommunityStatistics(this.properties.statisticsAPIURL, this.communityId).subscribe(
            stats => {
              if(stats) {
                this.statisticsSum = stats;
                if(stats["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"]=stats["other"];
                }
              }
            },
            error => {
                //this.loadingMessage = '';
                //this.errorMessage = 'Failed to retrieve statistics for the chosen community!';
                //console.log(error);
                this.handleError('Failed to retrieve statistics for the chosen community!', error);
            },
            () => {
                //this.loadingMessage = '';
                this.getDisplayOptions();
            }
        );
      }
    }

    getDisplayOptions() {
      if(!Session.isLoggedIn()){
        this._router.navigate(['/user-info'], { queryParams: { "errorCode": LoginErrorCodes.NOT_VALID, "redirectUrl":  this._router.url} });
      } else {
        this.contentService.getCommunityAdminStatisticsChoices(this.properties.adminToolsAPIURL, this.communityId)
            .subscribe(
                res => {
                    this.statisticsDisplay = res;
                },
                error => {
                    //console.log(error);
                    this.handleError('Failed to retrieve statistics\' choices for the chosen community!', error);
                },
                () => {
                    this.getCommunityInfo();
                }
            );
        }
    }

    getCommunityInfo() {
      if(!Session.isLoggedIn()){
        this._router.navigate(['/user-info'], { queryParams: { "errorCode": LoginErrorCodes.NOT_VALID, "redirectUrl":  this._router.url} });
      } else {
        //console.log(`calling ${this.properties.adminToolsAPIURL}/communityFull/${this.communityId}`);
        this.configService.getCommunityInformation(this.properties, this.communityId).subscribe(
            res => {
                this.communityInfo = res;
                this.communityName = this.communityInfo.shortTitle;
            },
            error => this.handleError('Failed to retrieve information for the chosen community!', error),//console.log(error),
            () => {
                this.createChartUrlMap();
                this.entitiesList = Array.from( this.entitiesMap.keys() );
                this.onChangeEntity(this.entitiesList[0]);
            }
        );
      }
    }

    onChangeEntity (entity: string) {
      if(!Session.isLoggedIn()){
        this._router.navigate(['/user-info'], { queryParams: { "errorCode": LoginErrorCodes.NOT_VALID, "redirectUrl":  this._router.url} });
      } else {
        this.showLoading = true;

        this.deactivatedEntity = false;
        this.displayedEntity = entity;

        this.displayedTimeline = `${entity}Timeline`;
        this.displayedGraph = `${entity}Graph`;
        this.changeDisplayedProjectChart(`${entity}Projectcolumn`);
        if (this.statisticsDisplay.entities[entity].charts.map['projectColumn'].showInMonitor &&
            this.statisticsDisplay.entities[entity].charts.map['projectPie'].showInMonitor &&
            this.statisticsDisplay.entities[entity].charts.map['projectTable'].showInMonitor) {
            this.showAllInMonitor = true;
        }
        if (this.statisticsDisplay.entities[entity].charts.map['projectColumn'].showInDashboard &&
            this.statisticsDisplay.entities[entity].charts.map['projectPie'].showInDashboard &&
            this.statisticsDisplay.entities[entity].charts.map['projectTable'].showInDashboard) {
            this.showAllInDashboard = true;
        }

        const activatedEntities = this.communityInfo['entities'];
        if ( !activatedEntities.some(item => item.pid === entity) ) {
            this.deactivatedEntity = true;
        }

        this.showLoading = false;
      }
    }

    changeDisplayedProjectChart(chartName: string) {
        this.displayedProjectChart = chartName;
    }

    createChartUrlMap() {
      let communityCharts: CommunityCharts = new CommunityCharts(this.sanitizer);
      this.chartsInfoMap = communityCharts.getChartsForCommunity(this.communityId, this.communityName, this.properties);
    }

    toggleShowAllInMonitor(entity: string) {
      if(!Session.isLoggedIn()){
        this._router.navigate(['/user-info'], { queryParams: { "errorCode": LoginErrorCodes.NOT_VALID, "redirectUrl":  this._router.url} });
      } else {
        this.showLoading = true;
        this.updateErrorMessage = "";
        //this.loadingMessage = 'Saving changes';
        this.showAllInMonitor = !this.showAllInMonitor;

        this.contentService.postCommunityAdminStatisticsChoices(
            this.properties.adminToolsAPIURL,
            this.communityId,
            entity,
            'charts',
            'projectColumn',
            this.showAllInMonitor,
            true).subscribe(
            response => {},//console.log(JSON.stringify(response)),
            error => {
                //console.log(error);
                //this.loadingMessage = '';
                //this.errorMessage = 'The changes could not be saved';

                this.handleUpdateError('The changes could not be saved', error);
            },
            () => {

                this.contentService.postCommunityAdminStatisticsChoices(
                    this.properties.adminToolsAPIURL,
                    this.communityId,
                    entity,
                    'charts',
                    'projectPie',
                    this.showAllInMonitor,
                    true).subscribe(
                    response => {},//console.log(JSON.stringify(response)),
                    error => {
                        //console.log(error);
                        //this.loadingMessage = '';
                        //this.errorMessage = 'The changes could not be saved';

                        this.handleUpdateError('The changes could not be saved', error);
                    },
                    () => {

                        this.contentService.postCommunityAdminStatisticsChoices(
                            this.properties.adminToolsAPIURL,
                            this.communityId,
                            entity,
                            'charts',
                            'projectTable',
                            this.showAllInMonitor,
                            true).subscribe(
                            response => {},//console.log(JSON.stringify(response)),
                            error => {
                                //console.log(error);
                                //this.loadingMessage = '';
                                //this.errorMessage = 'The changes could not be saved';

                                this.handleUpdateError('The changes could not be saved' ,error);
                            },
                            () => {

                                this.statisticsDisplay.entities[entity]['charts'].map['projectColumn'].showInMonitor = this.showAllInMonitor;
                                this.statisticsDisplay.entities[entity]['charts'].map['projectPie'].showInMonitor = this.showAllInMonitor;
                                this.statisticsDisplay.entities[entity]['charts'].map['projectTable'].showInMonitor = this.showAllInMonitor;
                                //this.loadingMessage = '';

                                this.showLoading = false;
                            }
                        );
                    }
                );
            }
        );

        /*forkJoin didn't work properly - maybe try another way*/
        /*Observable.forkJoin(
            this.contentService.postCommunityAdminStatisticsChoices(
                this.properties.adminToolsAPIURL,
                this.communityId,
                entity,
                'charts',
                'projectColumn',
                this.showAllInMonitor,
            true),
            this.contentService.postCommunityAdminStatisticsChoices(
                this.properties.adminToolsAPIURL,
                this.communityId,
                entity,
                'charts',
                'projectPie',
                this.showAllInMonitor,
                true),
            this.contentService.postCommunityAdminStatisticsChoices(
                this.properties.adminToolsAPIURL,
                this.communityId,
                entity,
                'charts',
                'projectTable',
                this.showAllInMonitor,
                true)

        ).subscribe(
            response => console.log('All went well in forkJoin!'),
            error => {
                console.log(error);
                this.loadingMessage = '';
                this.errorMessage = 'The changes could not be saved';
            },
            () => {
                this.statisticsDisplay.entities[entity]['charts'].map['projectColumn'].showInMonitor = this.showAllInMonitor;
                this.statisticsDisplay.entities[entity]['charts'].map['projectPie'].showInMonitor = this.showAllInMonitor;
                this.statisticsDisplay.entities[entity]['charts'].map['projectTable'].showInMonitor = this.showAllInMonitor;
                this.loadingMessage = '';
            }
        );*/
      }
    }

    toggleShowAllInDashboard(entity: string) {
      if(!Session.isLoggedIn()){
        this._router.navigate(['/user-info'], { queryParams: { "errorCode": LoginErrorCodes.NOT_VALID, "redirectUrl":  this._router.url} });
      } else {
        this.showLoading = true;
        this.updateErrorMessage = "";

        //this.loadingMessage = 'Saving changes';
        this.contentService.postCommunityAdminStatisticsChoices(
            this.properties.adminToolsAPIURL,
            this.communityId,
            entity,
            'charts',
            'projectColumn',
            !this.showAllInDashboard,
            false).subscribe(
            response => {},//console.log(JSON.stringify(response)),
            error => {
                //console.log(error);
                //this.loadingMessage = '';
                //this.errorMessage = 'The changes could not be saved';
                this.handleUpdateError('The changed could not be saved', error);
            },
            () => {

                this.contentService.postCommunityAdminStatisticsChoices(
                    this.properties.adminToolsAPIURL,
                    this.communityId,
                    entity,
                    'charts',
                    'projectPie',
                    !this.showAllInDashboard,
                    false).subscribe(
                    response => {},//console.log(JSON.stringify(response)),
                    error => {
                        //console.log(error);
                        //this.loadingMessage = '';
                        //this.errorMessage = 'The changes could not be saved';
                        this.handleUpdateError('The changes could not be saved', error);
                    },
                    () => {

                        this.contentService.postCommunityAdminStatisticsChoices(
                            this.properties.adminToolsAPIURL,
                            this.communityId,
                            entity,
                            'charts',
                            'projectTable',
                            !this.showAllInDashboard,
                            false).subscribe(
                            response => {},//console.log(JSON.stringify(response)),
                            error => {
                                //console.log(error);
                                //this.loadingMessage = '';
                                //this.errorMessage = 'The changes could not be saved';
                                this.handleUpdateError('The changes could not be saved', error);
                            },
                            () => {

                                this.showAllInDashboard = !this.showAllInDashboard;
                                this.statisticsDisplay.entities[entity]['charts'].map['projectColumn'].showInDashboard = this.showAllInDashboard;
                                this.statisticsDisplay.entities[entity]['charts'].map['projectPie'].showInDashboard = this.showAllInDashboard;
                                this.statisticsDisplay.entities[entity]['charts'].map['projectTable'].showInDashboard = this.showAllInDashboard;
                                //this.loadingMessage = '';

                                this.showLoading = false;
                            }
                        );
                    }
                );
            }
        );
      }
    }

    toggleShowGraphAnalysisView() {
      this.contentService.statisticsIsActiveToggle(this.properties.adminToolsAPIURL, this.statisticsDisplay._id).subscribe(status => {
        this.statisticsDisplay.isActive = status;
      });
    }

    toggleShowInMonitor(entity: string, chartsOrNumbers: string, title: string) {
      if(!Session.isLoggedIn()){
        this._router.navigate(['/user-info'], { queryParams: { "errorCode": LoginErrorCodes.NOT_VALID, "redirectUrl":  this._router.url} });
      } else {
        this.updateErrorMessage = "";

        this.contentService.postCommunityAdminStatisticsChoices(
            this.properties.adminToolsAPIURL,
            this.communityId,
            entity,
            chartsOrNumbers,
            title,
            !this.statisticsDisplay.entities[entity][chartsOrNumbers].map[title].showInMonitor,
            true).subscribe(
                    response => {},//console.log(JSON.stringify(response)),
                    error => this.handleUpdateError('The changes could not be saved', error),//console.log(error),
                    () => {
                      this.statisticsDisplay.entities[entity][chartsOrNumbers].map[title].showInMonitor = !this.statisticsDisplay.entities[entity][chartsOrNumbers].map[title].showInMonitor;
                    }
                );
      }
    }

    toggleShowInDashboard(entity: string, chartsOrNumbers: string, title: string) {
      if(!Session.isLoggedIn()){
        this._router.navigate(['/user-info'], { queryParams: { "errorCode": LoginErrorCodes.NOT_VALID, "redirectUrl":  this._router.url} });
      } else {
        this.updateErrorMessage = "";

        this.contentService.postCommunityAdminStatisticsChoices(
            this.properties.adminToolsAPIURL,
            this.communityId,
            entity,
            chartsOrNumbers,
            title,
            !this.statisticsDisplay.entities[entity][chartsOrNumbers].map[title].showInDashboard,
            false).subscribe(
                response => {},//console.log(JSON.stringify(response)),
                error => this.handleUpdateError('The changes could not be saved', error),//console.log(error),
                () => {
                  this.statisticsDisplay.entities[entity][chartsOrNumbers].map[title].showInDashboard = !this.statisticsDisplay.entities[entity][chartsOrNumbers].map[title].showInDashboard;
                }
            );
      }
    }

    getCamelCaseString (inputString: string) {
        return this.titleCase.transform(inputString);
    }


    handleUpdateError(message: string, error) {
        this.updateErrorMessage = message;
        console.log('Server responded: ' +error);

        this.showLoading = false;
    }

    handleError(message: string, error) {
        this.errorMessage = message;
        console.log('Server responded: ' + error);

        this.showLoading = false;
    }
}
