import { Component, OnInit, OnDestroy, ViewChild, ElementRef } from '@angular/core';
import { Group } from '../group';
import { ActivatedRoute, Router, Data } from '@angular/router';
import { GroupsService } from '../groups.service';
import { Subscription } from 'rxjs/Subscription';
import { RankingType } from './ranking';
import { GridOptions } from 'ag-grid-community/main';
import localeText from './../../../assets/localeText';
import { ngxCsv } from 'ngx-csv/ngx-csv';
import * as picasso from 'picasso.js';
picasso.default('canvas');

@Component({
  selector: 'app-ranking',
  templateUrl: './ranking.component.html',
  styleUrls: ['./ranking.component.css']
})
export class RankingComponent implements OnInit, OnDestroy {

  @ViewChild('chartContainer')
  public elemRef: ElementRef;
  public group: Group;
  public id: number;
  public currentUser: any;
  public typeOfRankingToDisplay: RankingType = RankingType.all;
  private gridApi;
  public gridOptions: GridOptions;
  public groupDetailsSubscription: Subscription;
  public rankingSubscription: Subscription;
  public chart;
  public localeText = localeText;
  public columnDefs = [
    { headerName: 'Nazwa użytkownika', field: 'username', headerTooltip: 'Nazwa użytkownika' },
    { headerName: 'Imię', field: 'name', headerTooltip: 'Imię' },
    { headerName: 'Nazwisko', field: 'surname', headerTooltip: 'Nazwisko' },
    { headerName: 'Punkty', field: 'points', headerTooltip: 'Punkty' },
  ];
  public data = [];


  constructor(private route: ActivatedRoute, private groupService: GroupsService, private router: Router) { }

  ngOnInit(): void {
    this.id = this.route.snapshot.params.id;
    this.currentUser = JSON.parse(localStorage.getItem('currentUser'));
    this.groupDetailsSubscription = this.groupService.getGroupDetails(this.id)
      .subscribe(data2 => {
        this.group = data2;
        this.rankingSubscription = this.groupService.getGlobalRanking(this.group.id).subscribe(data3 => {
          this.data = data3.sort((a, b) => {
            if (a.points > b.points) {
              return -1;
            } else if (a.points < b.points) {
              return 1;
            } else {
              return 0;
            }
          });
          this.showChart();
        });
      });
  }

  downloadCSVResults() {
    const options = {
      fieldSeparator: ';',
      quoteStrings: '',
      decimalseparator: ',',
      showLabels: true,
      headers: ['Punkty', 'Imię', 'Nazwisko']
    };
    const arr = this.data;
    arr.map(x => delete x['username']);
    // tslint:disable-next-line:no-unused-expression
    new ngxCsv(arr, this.group.name + '_ranking_' + this.typeOfRankingToDisplay, options);
  }

  ngOnDestroy(): void {
    if (this.groupDetailsSubscription) {
      this.groupDetailsSubscription.unsubscribe();
    }
    if (this.rankingSubscription) {
      this.rankingSubscription.unsubscribe();
    }
  }

  showChart(): void {
    const data: Data = {
      type: 'matrix',
      data: [['username', 'points']]
    };
    this.data.forEach(item => data.data.push([item.username, item.points]));
    this.chart = picasso.default.chart({
      element: this.elemRef.nativeElement,
      data,
      settings: {
        scales: {
          y: {
            data: { field: 'points' },
            invert: true,
            include: [0]
          },
          c: {
            data: { field: 'points' },
            type: 'color'
          },
          t: { data: { extract: { field: 'username' } }, padding: 0.3 },
        },
        components: [{
          type: 'axis',
          dock: 'left',
          scale: 'y'
        }, {
          type: 'axis',
          dock: 'bottom',
          scale: 't'
        }, {
          key: 'bars',
          type: 'box',
          data: {
            extract: {
              field: 'username',
              props: {
                start: 0,
                end: { field: 'points' }
              }
            }
          },
          settings: {
            major: { scale: 't' },
            minor: { scale: 'y' },
            box: {
              fill: function (d) {
                return d.datum.value === JSON.parse(localStorage.getItem('currentUser')).username ? '#cea856' : '#ffffff';
              },
              stroke: 'transparent'
            }
          }
        }
        ]
      }
    });
  }

  showGlobalRanking(): void {
    this.typeOfRankingToDisplay = RankingType.all;
    this.rankingSubscription = this.groupService.getGlobalRanking(this.id).subscribe(data => {
      this.data = data.sort((a, b) => {
        if (a.points > b.points) {
          return -1;
        } else if (a.points < b.points) {
          return 1;
        } else {
          return 0;
        }
      });
      this.showChart();
    });
  }

  showOnlyTestsRanking(): void {
    this.typeOfRankingToDisplay = RankingType.test;
    this.rankingSubscription = this.groupService.getTestsRanking(this.id).subscribe(data => {
      this.data = data.sort((a, b) => {
        if (a.points > b.points) {
          return -1;
        } else if (a.points < b.points) {
          return 1;
        } else {
          return 0;
        }
      });
      this.showChart();
    });
  }

  onGridReady(params) {
    this.gridApi = params.api;
    this.gridApi.sizeColumnsToFit();
  }

  onGridColumnsChanged(params) {
    params.api.sizeColumnsToFit();
  }

  onGridSizeChanged(params) {
    params.api.sizeColumnsToFit();
    if (this.data) {
      this.showChart();
    }
  }

  setRankingTypeTitle(): string {
    return this.typeOfRankingToDisplay === RankingType.test ? 'testów' : 'ogólny';
  }

}
