import { Component, OnInit, Input, ViewChild,OnDestroy,ElementRef, ViewEncapsulation, NgZone, Output, EventEmitter } from '@angular/core';
import { FlexmonsterPivot } from "../flexmonster/flexmonster.angular4";
import {  RESIZE_EVENT } from '../window-resize';

import { DashboardService } from '../../dashboard/dashboard.service';
import * as moment from 'moment';
import { APPLY_AGGREGATION } from '../../dashboard/dashboard-composite/composite.utils';

declare var exportToFile :any;
declare var removeClass :any;

declare var groupArrayMain: any;

@Component({
  selector: 'simple-grid',
  templateUrl: './simple-grid.component.html',
  styleUrls: ['./simple-grid.component.css'],
//   encapsulation: ViewEncapsulation.Native
  encapsulation: ViewEncapsulation.None
})
export class SimpleGridComponent implements OnInit ,OnDestroy {

    @Input('data') dashboardData : any;
    @Input('elWidth') elWidth: any;
    
    @ViewChild('simpleGrid') simpleGrid: FlexmonsterPivot | any;
    @Output() onDrillDown: EventEmitter<any> = new EventEmitter<any>();
    @Output() onRowSelect: EventEmitter<any> = new EventEmitter<any>();
    
    isOpened: boolean = false;
    isExpanded: boolean = false;
    isTreeStyleRows: boolean = false;
    pivotDataSource: any;
    clientWidth: any;
    
    isRefreshed: any;
    
    hostUrl: any;
    contWidth: any;
    licenseKey: any;
    linkedColumns: any = [];
    customizeCellFunc = this.customizeCellFunction.bind(this);
    selectedRowIndex: any;
    selectedRowData: any={};
    columnDataTypes: any={};
    reportData: any;
    data: any;
    columnsConfig: any;
    showExport: any;
    
    constructor(private dashboardService: DashboardService, public zone: NgZone){}
  
   onPivotReady(): void {
          console.log("SimpleGridComponent [ready]", this.simpleGrid, this.reportData, this.contWidth, this.elWidth );
          //removeClass('fm-pivot-view','fm-ui-element');
   }
    
    ngOnInit() {
        
        this.reportData = Object.assign({}, this.dashboardData, {});
        
        this.hostUrl = this.dashboardService.getHostURL();
        this.licenseKey = this.reportData.licenseKey;
        this.data = Object.assign([], this.reportData.data, []);
        this.columnsConfig = this.reportData.columnsConfig;
        this.showExport = this.columnsConfig ? this.columnsConfig.showExport : false;
        console.log("SimpleGridComponent of reportData [ngOnInit] ===>",this.reportData, this.columnsConfig);
        
      //TO DISPLAY DATE IN FORMATED FORM AS dd/MM/yy START
        var column;
        //var colTypeId;
        var colTypeIds: any = [];
        var columnGroup=this.reportData.column_group;
        var colFormatProps:any = [];
        var colSortProps:any = [];
        if(columnGroup[2] !=null){
            for(var colGroup of columnGroup){
                var columns=colGroup.columns;
                console.log('columns>>>>',columns)
                if( columns != null ){
                    if( columns instanceof Array ){
                        for(var colms of columns){
                           // console.log('columns::::',colms)
                           // column=colms.column;
                            var colId=colms.id;
                            var colFormatName = colms.formatName;
                            var colSortOption = colms.sort;
                            console.log("colId for coloumn==>",colId);
                            var typeOfColumn=colms.type;
                            if(typeOfColumn === 'date string'){
                                //colTypeId = colId
                                colTypeIds.push(colId);
                                console.log("colId for type date=>",colTypeIds);
                            }
                            console.log("typeOfColumn for coloumn==>",typeOfColumn);
                            if( colFormatName && ( typeOfColumn === 'number' || typeOfColumn === 'string' ) )
                            {
                                colFormatProps.push({
                            		'columnName' : colId,
                            		'formatName' : colFormatName
                            	});
                            } 
                            else if( typeOfColumn === 'string')
                            {
                            	colFormatProps.push({
                            		'columnName' : colId,
                            		'formatName' : 'STRING_DEFAULT'
                            	});
                            }

                            if( colSortOption ) 
                            {
                            	colSortProps.push({
                            		'columnName' : colId,
                            		'sortOption' : colSortOption
                            	});
                            }
                        }
                    }
                }//if( columns != null )
            }
        }//if(columnGroup[2] !=null)
        if(this.columnsConfig)
        {
        	this.columnsConfig['__formatColumns'] = colFormatProps;
            this.columnsConfig['__sortColumns'] = colSortProps;
            if(this.columnsConfig.formats && this.columnsConfig.formats.push)
            {
                var STRING_DEFAULT_FMT = {
                    name: 'STRING_DEFAULT',
                    nullValue: "",
                    textAlign: "left"
                };
                this.columnsConfig.formats.push(STRING_DEFAULT_FMT);
            }
        }
        //TODO [Need To Optimise]
        if(this.reportData.data){
            if(colTypeIds && colTypeIds.length > 0)
            {
                this.reportData.data.forEach(
                    (optVal: any) => {
                        for( var colTypeId of colTypeIds ) {
                           if(colTypeId && optVal[colTypeId]){
                               console.log("date format for optVal.LAST_RCP_DATE ==",optVal[colTypeId]);
                               var dateFormat = (window as any)['e12navigator'].applDateFormat.toUpperCase();
                               console.log("Check dateFormat for appl == >",dateFormat,optVal[colTypeId],dateFormat);
                               try
                               {
                                   var isoDateString = moment(optVal[colTypeId],dateFormat).toISOString(true);
                                   isoDateString = isoDateString.split(".000")[0];
                                   optVal[colTypeId] = isoDateString;
                               }
                               catch(e)
                               {
                                    // Formatting not possible 
                               }
                               console.log("date format>>>>>>>>",optVal);
                           }
                        }
                    }
                );
                var dataType = this.reportData.data[0];
                if( dataType || Object.keys(dataType).length > 0)
                {
                    Object.keys(dataType).map( key=> {
                        this.columnDataTypes[key] = {
                            'type' : 'string'
                        };
                    });
                }
            }
            console.log(" this.reportData.data>>>>>>>", this.reportData.data);
        }
      // TO DISPLAY DATE IN FORMATED FORM AS dd/MM/yy END
        
        console.log("SimpleGridComponent [ngOnInit]",this.licenseKey, this.reportData, this.hostUrl );
        

        if(this.hostUrl){            
            RESIZE_EVENT.subscribe(
                    (clientWidth: any) => {
                        console.log('on device width resize',clientWidth);
                        this.elWidth = clientWidth;
                        if( this.simpleGrid )
                        {
                            this.simpleGrid.flexmonster.refresh();
                            this.zone.run(() => {
                                console.log( 'view refreshed' );
                            } );
                        }
                    }
            );
        } 
        
        var groupByColumns = '';
        var aggregateObj: any = {
            'SUM' : '',
            'AVG' : '',
            'MIN' : '',
            'MAX' : '',
            'COUNT' : '',
        };
        if(columnGroup)
        {
            columnGroup.forEach(
                (column_group: any) => {
                    if(column_group.link_metadata && Object.keys(column_group.link_metadata).length > 0 && column_group.link_metadata != ""){
                        this.linkedColumns.push(column_group.id);
                    }
                    if(column_group.columns && column_group.columns.length > 0){
                        var column = column_group.columns[0];
                        this.columnDataTypes[column.id] = {
                            'type' : column.type ? column.type.toLowerCase() : column.type 
                        };

                        if(column.showUnique == 'Y')
                        {
                            var tempArray: any = [];
                            this.reportData.data.forEach(
                                (record: any) => {
                                    var existingRecord = tempArray.find((rec: any) => rec[column.id] == record[column.id]);
                                    if(!existingRecord){
                                        tempArray.push(record);
                                    }
                                }
                            );
                            this.reportData.data = tempArray;
                        }
                        if(column.groupBy == 'Y')
                        {
                            groupByColumns += column.id + ',';
                        }
                        if(column.aggFunction)
                        {
                            const aggFunction = column.aggFunction.toUpperCase();
                            aggregateObj[aggFunction] += column.id + ',';
                        }
                    }
                }
            );
            
            console.log('groupByColumns ::', groupByColumns , 'columnDataTypes:: ',this.columnDataTypes,this.reportData.data);
            if( groupByColumns )
            {
                this.data = APPLY_AGGREGATION(this.reportData.data, groupByColumns, aggregateObj);
            }
            else
            {
                this.data = this.reportData.data;
            }
            //Aded datatype object in data array @ 0th index 
            this.data.unshift(this.columnDataTypes);
            console.log('groupByColumns ::',this.data);
        }
        
        console.log('linkedColumns:: ',this.linkedColumns);
    }
    
    ngOnChanges() {
        console.log('ngOnChanges in Simple Grid',this.contWidth, this.elWidth );
        if(!this.hostUrl && this.elWidth != 0 && this.contWidth != this.elWidth && this.simpleGrid && this.simpleGrid.flexmonster){
            console.log('on element width resize');
            this.contWidth = this.elWidth;
            this.simpleGrid.flexmonster.refresh();
        }
    }
    
    exportToExcel()
    {
      var options = {
         filename : 'report'
      }
      try
      {
          var fileName = this.reportData.title.replace(/[&\/\\|#,+()$~%.'":*?<>{}]/g, '');
          var params = {
              filename: '' + fileName,
              destinationType:'file',
              excelSheetName: 'Report',
              showFilters: true
          };
          console.log('exportToExcel', exportToFile);
          setTimeout( () =>{
              if( this.simpleGrid )
              {
                  this.simpleGrid.flexmonster.exportTo('excel', params, exportToFile);
              }
          }, 2000); 
      }
      catch(e)
      {
          console.log('exportToExcel', e);
      }
      
    }
    
    onReportComplete(): void {
        console.log('onReportComplete', this.data );
        var reportConfig = {
           dataSource: {
                dataSourceType: "json",
                data: this.data 
           },
           options : {
                grid: {
                    type:  'flat',
                    showHeaders: false,
                    showFilter: false,
	                showGrandTotals : this.columnsConfig ? this.columnsConfig.showGrandTotals : 'off',
	                grandTotalsPosition : this.columnsConfig ? this.columnsConfig.grandTotalsPosition : 'top'
                },
                datePattern: this.columnsConfig ? this.columnsConfig.datePattern : "dd/MM/yy",
                configuratorButton : false, // As per KB sir, no need to parameterized.
                drillThrough: false,
                showCalculatedValuesButton: false,
                showDrillThroughConfigurator: false
           },
           /*
           formats: [
             {
               name: "",
               thousandsSeparator: ""
             }
           ],*/
           formats: this.columnsConfig ? this.columnsConfig.formats : [],
           columns: this.reportData.columns,
           tableSizes: {
               columns: this.reportData.columns,
           }
        };
      
        if( this.simpleGrid ) 
        {
            this.simpleGrid.flexmonster.off("reportcomplete");
            console.log('simple reportConfig:::',reportConfig);
            this.simpleGrid.flexmonster.setReport(reportConfig);
            if(this.reportData.filterInfo){                
                var column = this.reportData.filterInfo.column;
                var value = this.reportData.filterInfo.value;
				// Changes by Prajyot [ To setfilter using link columns] - Starts      
                //this.simpleGrid.flexmonster.setFilter(
                //        column, this.getColumnVals(column,value)
                //);
                this.onSetFilter(column,value);
                var columns = this.reportData.filterInfo.link_columns;
                var values = this.reportData.filterInfo.rowData;
                console.log('link_columns and rowData:::',columns, values);
                if(columns && values)
                {
                    columns = columns.toLowerCase();
                    columns.split(',').map((_column: any) => {
                        var _value = values[_column];
                        this.onSetFilter(_column,_value);
                    });
                }
				// Changes by Prajyot [ To setfilter using link columns] - Ends      
            }    
            console.log('simple pivotGrid:::',this.simpleGrid);    
            if(this.columnsConfig)
            {
            	this.applyColumnsConfig();
            }
        }
    }
    
    openFieldsList() {
         console.log('simple openFieldsList:::');
         if( this.simpleGrid )
         {
             this.simpleGrid.flexmonster.openFieldsList();
         }
    }
    ngOnDestroy() {
        console.log('simple grid ngOnDestroy..');
    }

    customizeCellFunction(cell: any, data: any) {        
        if (data.hierarchy && this.linkedColumns.indexOf(data.hierarchy.uniqueName) > -1 && data.type == "value") {
            var el = document.createElement( 'div' );
            el.innerHTML = cell.text;
            cell.text = "<span class='drill-down-link'>"+ el.innerText +"</span>";
        }
        if (data.type == "value") {
            if (data.rowIndex % 2 == 0) {
              cell.addClass("alter1");
            } else {
              cell.addClass("alter2");
            }
        }
        if(data.rowIndex == this.selectedRowIndex){
            var idx1 = cell.classes.indexOf('alter1');
            var idx2 = cell.classes.indexOf('alter2');
            if(idx1 > -1){
                cell.classes.splice(idx1, 1);
            }
            if(idx2 > -1){
                cell.classes.splice(idx2, 1);
            }

            cell.classes.push('highlight-cell');
            this.selectedRowData[data.hierarchy.uniqueName.trim().toLowerCase()] = data.label;
        }
    }
    
    onCellClick(cell: any){
        console.log('selectedRowData ::',this.selectedRowData);
        if (cell.hierarchy && this.linkedColumns.indexOf(cell.hierarchy.uniqueName) > -1 && cell.type == "value") {            
            this.selectedRowIndex = cell.rowIndex;
            this.simpleGrid.flexmonster.refresh();
            var columnGroup = this.reportData.column_group.find( (columnGroup: any) => columnGroup.id === cell.hierarchy.uniqueName);
            console.log('On Cell Click: [Cell & linkMetadata]',cell,columnGroup.link_metadata);           
        
            var selectedFieldInfo = {
              "column" :  cell.hierarchy.uniqueName,
              "value" : cell.label,
              "linkMetadata" : columnGroup.link_metadata,
              "link_columns" : columnGroup.link_columns,  // Added by Prajyot [ To setfilter using link columns]
              "rowData" : this.selectedRowData
            };
            
            setTimeout(() => {
                this.onDrillDown.emit(selectedFieldInfo);
             }, 200);
            
        }
        
        this.selectedRowIndex = cell.rowIndex;
        this.simpleGrid.flexmonster.refresh();
        
      /*  if(this.reportData.obj_name){
            this.selectedRowIndex = cell.rowIndex;
            this.simpleGrid.flexmonster.refresh();
            
            console.log('selectedRowData ::',this.selectedRowData);
        } */  
    }
    
    getColumnVals(column: any, value: any) {
        var filterData: any = {};
        var filterValues:any = [];
        var formattedVal = column+'.['+value+']'
        filterValues.push(formattedVal);    
        filterData['members'] = filterValues;
        console.log('filterValues',filterValues,filterValues);
        return filterData;
    }
    
    onAfterGridDraw(){
        console.log('After Grid Draw ::');
        
        if(Object.keys(this.selectedRowData).length > 0){
            this.onRowSelect.emit(this.selectedRowData);
        }
    }
	//Added by Prajyot [ To setfilter using link columns] - Starts      
    onSetFilter(column: any,value: any)
    {
        this.simpleGrid.flexmonster.setFilter(
            column, this.getColumnVals(column,value)
        );
	    column = column.toUpperCase();
        console.log('onSetFilter simpleGrid:::',column, value);
        this.simpleGrid.flexmonster.setFilter(
            column, this.getColumnVals(column,value)
        );
    }
	//Added by Prajyot [ To setfilter using link columns] - Ends      
	
	applyColumnsConfig()
	{
		if( this.columnsConfig.formats && this.columnsConfig['__formatColumns'] )
		{
			this.columnsConfig['__formatColumns'].map( (formatObj: any) => {
				this.setFormat(formatObj.columnName, formatObj.formatName);
			});
		}
		if( this.columnsConfig['__sortColumns'] )
		{
        	this.columnsConfig['__sortColumns'].map( (sortObj: any) => {
				this.setSort(sortObj.columnName, sortObj.sortOption);
			});
		}
	}
	
	setFormat(columnName: any, formatName: any) 
	{
	  var formatsArr = this.columnsConfig.formats;
	  console.log('formatArr' + JSON.stringify(formatsArr));
	  if(!formatsArr || !formatsArr.filter) return;
	  var _format = formatsArr.filter( (fmt: any) => {
	    console.log('format', fmt);
	  	if( fmt.name === formatName )
	    	return fmt;
      });
	  console.log('2__format' + JSON.stringify(_format));
	  this.simpleGrid.flexmonster.setFormat(_format[0], columnName);
	  this.simpleGrid.flexmonster.refresh();
	}	
	
	//Sorting types can be applied as sortType : "asc", "desc", or "unsorted".
	setSort(columnName: any, sortType: any) {
		this.simpleGrid.flexmonster.setSort(columnName, sortType);
		this.simpleGrid.flexmonster.refresh();
	}  
}
