import { Component, OnInit, Input, ViewChild, Output, EventEmitter, NgZone,ViewEncapsulation } from '@angular/core';
import { DashboardService } from '../dashboard/dashboard.service';
import { DashboardDatamodelService } from '../dashboard/dashboard-datamodel.service';
import { FlexmonsterPivot } from "../datagrid/flexmonster/flexmonster.angular4";
import {  RESIZE_EVENT } from '../datagrid/window-resize';
import { DEEP_CLONE } from '../dashboard/dashboard-composite/composite.utils';

@Component( {
    selector: 'fm-chart',
    templateUrl: './fm-chart.component.html',
    styleUrls: ['./fm-chart.component.css'],
    encapsulation: ViewEncapsulation.None

} )
export class FmChartComponent implements OnInit {

    @Input( 'data' ) dashboardData: any;
    @Input('elWidth') elWidth:any;
    @ViewChild( 'fmChart' ) fmChart!: FlexmonsterPivot;
    @Output() onDrillDown: EventEmitter<any> = new EventEmitter<any>();
    @Output() onGetData: EventEmitter<any> = new EventEmitter<any>();
    
    licenseKey:any;
    xAxisCol:any;
    yAxisCol:any
    linkedColumns:any = [];
    contWidth:any;
    hostUrl:any;
    elemId:any;
    chartType:any;
    reportData:any;
    showTotal:any;
    showDataLabels:any;
    reportDataFormats:any;
    
    constructor(private dashboardService: DashboardService, public zone: NgZone) { }

    ngOnInit() {
        this.hostUrl = this.dashboardService.getHostURL();
        
        this.reportData = Object.assign({}, this.dashboardData, {});
        this.licenseKey = this.reportData.licenseKey;
        this.elemId = this.reportData.metadataname + '-fm-grid-view' + this.reportData.compId;
        this.chartType=this.reportData.chartType || 'bar';
        this.showTotal=this.reportData.showTotal;
        this.showDataLabels = this.reportData.showDataLabels ? this.reportData.showDataLabels : false ;
        this.reportDataFormats = this.reportData.columnsConfig ? this.reportData.columnsConfig.formats : [];
        console.log( 'licenceKey for fm-chart=>', this.reportData, this.reportDataFormats);
        
        if(this.hostUrl){            
            RESIZE_EVENT.subscribe(
                    (clientWidth:any) => {
                        console.log('on device width resize',clientWidth);
                        this.elWidth = clientWidth;
                        if( this.fmChart )
                        {
                            this.fmChart.flexmonster.refresh();
                            this.zone.run(() => {
                                console.log( 'view refreshed' );
                            } );
                        }
                    }
            );
        } 
        
        if(this.reportData.column_group){
            this.reportData.column_group.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];
                            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;
                            }
                        }
                    }
            );
        }
        
        var tabChangeEvent = (window as any)["AngDashboard"].onTabChange;
        var subscribtion = tabChangeEvent.subscribe(
                (metadataname:any) => {
                    if(this.reportData.metadataname == metadataname)
                    {
                        console.log('On Tab Change Event',metadataname);
                        this.fmChart.flexmonster.refresh();
                        subscribtion.unsubscribe();
                    }
                }
        );
    }
    
    ngOnChanges() {
        console.log('ngOnChanges in Fm Chart',this.contWidth, this.elWidth );
        if(!this.hostUrl && this.elWidth != 0 && this.contWidth != this.elWidth && this.fmChart && this.fmChart.flexmonster){
            console.log('on element width resize');
            this.contWidth = this.elWidth;
            this.fmChart.flexmonster.refresh();
        }
    }

    onReportComplete(): void {
        console.log( 'Inside onReportComplete', this.chartType );

        //TODO 
        this.xAxisCol = this.findInArray( this.reportData.column_group, 'id', 'x-axis' );
        this.yAxisCol = this.findInArray( this.reportData.column_group, 'id', 'y-axis' );
        console.log( 'Inside X-AXis and Y-AXis ===> ', this.xAxisCol, this.yAxisCol );
   		//Added By Prajyot [Multiple measures] Starts
        //var column = this.reportData.filterInfo ? this.reportData.filterInfo.column : '';
        //var value = this.reportData.filterInfo ? this.reportData.filterInfo.value : '';
        //console.log( 'Inside column', column,value );
        console.log('this.xAxisCol.length >>', this.xAxisCol.length);
        console.log('this.yAxisCol.length >>', this.yAxisCol.length);        
       
        var formatsArr:any = this.reportDataFormats;
        var rowsArr:any = [];
        if( this.xAxisCol.length > 0 ) 
        {
            for( var i = 0; i < this.xAxisCol.length; i++ ) 
            {
                console.log('this.xAxisCol[i] >>', this.xAxisCol[i]);
                var rowObj:any =   {
                    'uniqueName': this.xAxisCol[i].id,
                    'caption': this.xAxisCol[i].value
                };
                if( this.xAxisCol[i].sortOrder )
                {
                	rowObj['sortOrder'] = this.xAxisCol[i].sortOrder.split(',');
                }
                else if( this.xAxisCol[i].sortOption )
                {
                	rowObj['sort'] = this.xAxisCol[i].sortOption;
                }
                rowsArr.push(rowObj);           
            }
            console.log('rowsArr >>', rowsArr);
        }
        else
        {
            alert('No rows defined to display on (X-axis)');
        }
        var measuresArr:any = [];
        if( this.yAxisCol.length > 0 ) 
        {
            for( var i = 0; i < this.yAxisCol.length; i++ ) 
            {
                console.log('this.yAxisCol[i] >>', this.yAxisCol[i]);
                var measureObj:any= {
                    'uniqueName': this.yAxisCol[i].id,
                    'caption': this.yAxisCol[i].value,
                    'aggregation': this.yAxisCol[i].aggrFunction
                };
                if( this.yAxisCol[i].formatName )
                {
                	measureObj['format'] = this.yAxisCol[i].formatName;
                }
                measuresArr.push(measureObj);           
            }
            console.log('measuresArr >>', measuresArr);
        }
        else
        {
            alert('No measures defined to display on (Y-axis)');
        }
        var multipleMeasures = this.yAxisCol.length > 1 ;
        console.log( 'Inside X-AXis and Y-AXis #2 ===> ', multipleMeasures, this.xAxisCol, this.yAxisCol );
        var _reportFilters = this.getReportFilters();
        console.log( 'Inside _reportFilters #3 ===> ', _reportFilters );
		//Added By Prajyot [Multiple measures] Ends
        var reportConfig = {
            container: "pivot-container",

            dataSource: {
                dataSourceType: "json",
                data: DEEP_CLONE(this.reportData.data)
            },
            options: {
                viewType: "charts",
                chart: {
                    type: this.chartType,
                    autoRange: false,
                    showFilter: false,
                    showMeasures: false,
                    showLegend: multipleMeasures,
                    multipleMeasures: multipleMeasures,
                    showDataLabels: this.showDataLabels
                },
                configuratorActive: false,
                configuratorButton : false,
                drillThrough: false,
                showCalculatedValuesButton: false,
                showDrillThroughConfigurator: false
            },
            formats: formatsArr,
            /*
            formats: [
                      {
                        name: "",
                        thousandsSeparator: ""
                      }
                    ],

            */
            slice: {
                reportFilters: _reportFilters,
                //reportFilters:this.reportData.filterInfo ? [{uniqueName:column , filter: {members: this.getColumnVals(column, value)}}] : [],
            
                rows: rowsArr,  
                /*
                rows: [{
                    uniqueName: this.xAxisCol.id,
                    caption: this.xAxisCol.value,
                    sortOrder: this.xAxisCol.sortOrder ? this.xAxisCol.sortOrder.split(',') : ""
                }],*/
                columns: [{
                    uniqueName: "[Measures]"
                }
                ],
                measures: measuresArr
                /*
                measures: [{
                    uniqueName: this.yAxisCol.id,
                    caption: this.yAxisCol.value,
                    aggregation: this.yAxisCol.aggrFunction
                }
                ]*/
            },
            width: "100%",
            height: 370
        };

        if ( this.fmChart ) {
            this.fmChart.flexmonster.off( "reportcomplete" );
            console.log( 'fmChart reportConfig:::', reportConfig );
            this.fmChart.flexmonster.setReport( reportConfig );
            console.log( 'fmChart:::', this.fmChart );
            
            this.fmChart.flexmonster.getData(this.getRawData.bind(this), this.getRawData.bind(this));
            
            document.getElementById(this.elemId)?.addEventListener('click', this.onBarClick.bind(this));
        }
    }

    getRawData(rawData:any){
        console.log('getRawData ::',rawData);
        if(this.showTotal && rawData && rawData.data && rawData.data[0].v0){            
            var totalVal = rawData.data[0].v0;
            totalVal = Math.round(totalVal * 100)/100;
            this.onGetData.emit(totalVal);
        }
    }

    openFieldsList() {
        console.log( 'simple openFieldsList:::' );
        this.fmChart.flexmonster.openFieldsList();
    }

    findInArray( array:any, key:any, value:any ) {
        
        var foundObj = array.find( (obj:any) => obj[key] === value );
        if(foundObj && foundObj.columns && foundObj.columns.length > 0){
            //return foundObj.columns[0]; 
            return foundObj.columns; 
        }else {
            return [{ "id": "COLNOTDEF", "value": "Column is not configured"}];
        }
    }
    
    onBarClick( event:any ) {
        console.log('Inside on bar click ',event);
        var eventData = event.target.__data__;
        if ( eventData && this.xAxisCol[0]) {
            var column = this.xAxisCol[0].id;
            var value: string;

            var columnGroup = this.reportData.column_group.find( (columnGroup:any) => columnGroup.columns[0].id === column );

            if ( columnGroup.link_metadata ) {

                var displayVal = columnGroup.columns[0].value;
                console.log( 'eventData', eventData );
                if((eventData.data && eventData.data.De) || eventData.De){
                    console.log('eventData.data.De');
                    value = eventData.De ? eventData.De : eventData.data.De;
                }
                else if((eventData.data && eventData.data.de) || eventData.de){
                    console.log('eventData.data.De');
                    value = eventData.de ? eventData.de : eventData.data.de;
                }
                else if((eventData.data && eventData.data.sf) || eventData.sf){
                    value = eventData.sf ? eventData.sf : eventData.data.sf;
                }
                else if((eventData.data && eventData.data.zf) || eventData.zf){
                    value = eventData.zf ? eventData.zf : eventData.data.zf;
                    console.log('eventData.zf',eventData.zf);
                }
                else{
                    console.log( 'eventData.data.Ve' );
                    value =eventData.Ve ? eventData.Ve : eventData.data.Ve; 
                }
                
				//Changes for get Value for selected Bar 
                /*
                var index = value.lastIndexOf( displayVal + ':' ) + 1;
                value = value.substring( index + displayVal.length, value.length );
                value=value.substring(1,value.length )
                */
                value = this.getSelectedValue(value, displayVal);
                var selectedFieldInfo = {
                    "column": column,
                    "value": value,
                    "linkMetadata": columnGroup.link_metadata,
                    "link_columns" : columnGroup.link_columns
                };
                console.log( 'detect dblclick label and value', displayVal, column, value );
                this.onDrillDown.emit( selectedFieldInfo );
            }


        }
    }

    /*
    getColumnVals(column, value) {
        console.log('getColumnVals');
        var filterValues = [];
        var formattedVal = column+'.['+value+']'
        filterValues.push(formattedVal);    
        console.log('filterValues',filterValues);
        return filterValues;
    }
    */
    
    getSelectedValue(selectedValue:any, selectedKey:any)
    {
        var returnValue = '';
        if( selectedValue )
        {
            var selValArr = selectedValue.split('\n').map( (d:any) => { 
                var keyValArr = d.split(": "); 
                var obj = { "key" : keyValArr[0] , "value" : keyValArr[1] }; 
                return obj; 
            });
            
            selValArr.map( (a:any) => {
                console.log('selectedKey : [', selectedKey, ']', a);
                if( a.key == selectedKey )
                {
                    returnValue = a.value;
                }
            });
        }
        console.log('getSelectedValue returnValue : [', returnValue, ']');
        return returnValue;
    }
    //Added by Prajyot [To create report level filter]Starts    
    getReportFilters()
    {
    	var reportFilters:any = [];
    	if(this.reportData && this.reportData.filterInfo)
    	{
			var column = this.reportData.filterInfo.column;
	        var value = this.reportData.filterInfo.value;
	    	var filterObj = this.getColumnFilter(column, value);
	        reportFilters.push(filterObj);
	        
	        var columns = this.reportData.filterInfo.link_columns;
	        var values = this.reportData.filterInfo.rowData;
	        console.log('link_columns and rowData:::',columns, values);
	        if(columns && values)
	        {
	        	//Bugfixing - Filter issue
	            //columns = columns.toLowerCase();
	            columns.split(',').map((_column:any) => {
	                var _value = values[_column] || values[_column.toLowerCase()] ;
	                var filterObj = this.getColumnFilter(_column, _value);
			        reportFilters.push(filterObj);
			        var filterObj = this.getColumnFilter(_column.toLowerCase(), _value);
			        reportFilters.push(filterObj);
	            });
	        }
    	}
		return reportFilters;        
    }
    
    getColumnFilter(column:any, value:any) {
        console.log('getColumnFilter');
        var filterMembers:any = [];
        var formattedVal = column+'.['+value+']';
        filterMembers.push(formattedVal);    
        console.log('filterMembers',filterMembers);
        var filterObj = {	
        	uniqueName: column , 
        	filter: {
        		members: filterMembers
        	}
        };
        return filterObj;
    }
    //Added by Prajyot [To create report level filter]Ends
}
