import { Component, Input, Output, EventEmitter, ViewEncapsulation, OnInit ,OnDestroy, OnChanges, AfterViewChecked, ChangeDetectorRef} from '@angular/core';
import { RANK, SUM, UNIQUE, AVERAGE, GROUP_BY_KEYS, SORT_BY, PREPARE_COMPOSITE_OBJECTS, OPEN_DASHBOARD, DEEP_CLONE, FILTER_DATA, UPDATE_TAB_DATA, FILTER_DATA_BY_EXPR } from './composite.utils';

import { UserTaskService } from '../../user-task/user-task.service';

@Component({
  selector: 'dashboard-composite',
  templateUrl: './dashboard-composite.component.html',
  styleUrls: ['./dashboard-composite.component.css'],
  encapsulation: ViewEncapsulation.None,
  host: { '[class]': 'compositeCss', '[style.width]': 'compositeWidth', '[style.height]': 'compositeHeight' }
})
export class DashboardCompositeComponent implements OnInit ,OnDestroy, OnChanges, AfterViewChecked {

  @Input('data') reportData : any;
  @Input('compositeConfig') compositeConfig : any;
  @Input('drillDownCompositeInfo') drillDownCompositeInfo : any;
  @Output() onDrillDown: EventEmitter<any> = new EventEmitter();
  @Output() onPerformAction: EventEmitter<any> = new EventEmitter();
  @Output() onDrillDownClose: EventEmitter<any> = new EventEmitter();

  isSelection: any;
  link_metadata: any;
  link_condition: any;
  component_config : any;
  tabConfig : any;
  tabData : any;
  compObjects: any[] = [];
  compositeId: any;
  compositeType:any;
  tableObjects: any[] =[];
  parentData = {};

  chartConfig: any;
  chartData:any;

  isDataAvailable = true;
  compositeNoDataMessage: any;

  compositeCss: any;
  compositeWidth: any;
  compositeHeight: any;
  /* Added By Vikas Lagad on 12-02-2020 [to build data for custom pie chart]Start*/
  labelsArr :any = [];
  dataArr :any = [];
  options: any ;
  heading = "";
  monthDescr =""
  totalCnt = 0;
  public chartColors : any;

  chartDetailModel: any;
  /* Added By Vikas Lagad on 12-02-2020 [to build data for custom pie chart]End*/

  /*
  default_component_config = {
    component_type: 'CUSTOM_CHART',
    chart_properties: {
      chartType: 'percentage',
      labels: [''],
      options: {
          width: 64,
          height: 64,
          responsive: true,
          maintainAspectRatio: false,
          tooltip: false,
          cutOutPercentage: 75,
          chartCenterText: "data[0] + '%'",
          condnFormat: [
            {
              id: "RED",
              expression: " data[0] <= 60 ",
              colors: [[252, 101, 101], [248, 248, 248]]
            },
            {
              id: "YELLOW",
              expression: " ( 61 < data[0] ) && ( data[0] <= 80 ) ",
              colors: [[255, 211, 90], [248, 248, 248]]
            },
            {
              id: "GREEN",
              expression: " ( 81 < data[0] ) && ( data[0] <= 100 ) ",
              colors: [[0, 199, 153], [248, 248, 248]]
            }
          ]
       }
    }
  };
  */
  //  1) Red - 60% - #fc6565 [252,101,101]
  //  2) Orange - 61 - 80 % - #ffd35a [255,211,90]
  //  3) Green - 81 - 100 % - #00c799 [0,199,153]]
  //  4) Gray - 100% - value - #f8f8f8 [248,248,248]

  constructor(private cdr: ChangeDetectorRef, public userTaskSvc : UserTaskService) { }

  ngOnInit() {
      console.log('DashboardCompositeComponent reportData', this.reportData, this.compositeConfig);

      if ( this.reportData['filterInfo'] )
      {
          console.log('DashboardCompositeComponent reportData #2', this.reportData['filterInfo']);
          console.log('DashboardCompositeComponent reportData #3', this.reportData['filterInfo']['rowData'] );
          this.parentData = this.reportData['filterInfo']['rowData'];
      }

      this.link_metadata = this.compositeConfig.link_metadata || this.compositeConfig.LINK_METADATA;
      this.link_condition = this.compositeConfig.link_condition;
      this.compositeId = this.compositeConfig.composite_id;
      this.compositeNoDataMessage = this.compositeConfig.composite_message;

      this.compositeType = this.compositeConfig.composite_type || 'CARD_PANEL';
      this.compositeCss = this.compositeConfig.composite_css ? this.compositeConfig.composite_css : 'db-col-1';
      this.compositeWidth = this.compositeConfig.width ? this.compositeConfig.width : '';
      this.compositeHeight = this.compositeConfig.height ? this.compositeConfig.height : '';

      var composite_config = this.compositeConfig.composite_config;
      if( composite_config )
      {
          console.log('composite_config from reportData', composite_config);
          this.component_config = eval( 'this.component_config = ' +  composite_config);
      }
      this.isSelection = this.isSelectionAvailable(); //this.link_metadata ? true : false;

	  if( this.component_config && this.component_config.tabs_config )
	  {
		  this.tabConfig = this.component_config.tabs_config;
		  this.chartConfig = this.component_config.chart_properties;
      }
      if(this.component_config.detailModel)
      {
        var detailConfData =  this.component_config.detailModel;
        this.heading =  detailConfData.title_column;
      }
      if(this.chartConfig && this.chartConfig.options)
      {
          this.options =  this.chartConfig.options;
      }
      if(this.chartConfig && this.chartConfig.colors)
      {
          this.chartColors =   this.chartConfig.colors;
      }
	  if( this.component_config && this.component_config.chartConfig )
     {
          this.chartConfig = this.component_config.chartConfig;
          this.chartDetailModel = this.component_config.chartDetailModel;
      }
      console.log('data from reportData', this.isSelection, this.tabConfig, this.chartConfig ,this.chartDetailModel, this.component_config, this.reportData.data);
      this.processColumnGroups();
      this.buildPieChartData();
  }

  ngOnDestroy(){

  }

  ngOnChanges(){
    if( this.drillDownCompositeInfo && this.compositeId === this.drillDownCompositeInfo.compositeId )
    {
      this.processColumnGroups();
    }
  }

  /* Added By Vikas Lagad on 12-02-2020 [build data for custom pie chart]Start*/
  buildPieChartData()
  {
        var compDataLocal = [];
        try
        {
            compDataLocal = JSON.parse(this.reportData.data);
        }
        catch(e)
        {
            compDataLocal = this.reportData.data;
        }
        var component_data: any = Object.assign([], compDataLocal);

        try
        {
            for(var i = 0; i < component_data.length; i++)
            {
                if( component_data[i]["DESCR"] && component_data[i]["DESCR"] != '')
                {
                	this.labelsArr.push( component_data[i]["DESCR"] );
                }
                if( component_data[i]["AMOUNT"] && component_data[i]["AMOUNT"] != '')
                {
                	this.dataArr.push( parseInt(component_data[i]["AMOUNT"]) );
                    this.totalCnt =  this.totalCnt + parseInt(component_data[i]["AMOUNT"]);
                }
                if(component_data[0]["EXP_DATE"] && component_data[0]["EXP_DATE"] != '')
                {
                    this.monthDescr =  component_data[0]["EXP_DATE"];
                }
            }
            console.log('Data Array  :: ',this.dataArr,this.labelsArr);
        }
        catch (error)
        {
            console.log('Exception in building pie chart data    ',error);
        }
  	}
	/* Added By Vikas Lagad on 12-02-2020 [build data for custom pie chart]Start*/

  ngAfterViewChecked(){
      //your code to update the model
      this.cdr.detectChanges();
  }

  _onDrillDown(rowData: any)
  {
      console.log('onDrillDown ...... rowData >>>>', rowData);
      //this.link_metadata = ''; //Commented by Pramod Shirke on 15-03-2022 [On click of Banner card __onDrillDown not getting called in case this.link_metadata is defined]
    if( rowData && (rowData.link_metadata || rowData.LINK_METADATA) )
    {
         //Added by Saiprasad G. START
      var link = rowData.link_metadata || rowData.LINK_METADATA;
      console.log('link....... ',link);
      this.link_metadata = link;
       //Added by Saiprasad G. END
      var drillCondition = rowData.link_condition;
      console.log('_onDrillDown 1...', link, drillCondition);
      this.__onDrillDown(link, rowData, drillCondition);
    }
	else // Because of this two time drilldown is called Start Nilesh  :: 11-04-2021
	{
	if(this.link_metadata)
	{
      var links = this.link_metadata.split(',');
      var drillCondition = this.link_condition;
      for(var link of links)
      {
        console.log('_onDrillDown 2...', link, drillCondition);
        this.__onDrillDown(link, rowData, drillCondition);
      }
	}

  }
  }

  __onDrillDown(link: any, rowData: any, drillCondition: any)
  {
    console.log('__onDrillDown 3...', link);
    if( this.component_config.component_type === 'BANNER_CARD' )
    {
      OPEN_DASHBOARD(link);
    }
    else if( link.indexOf('_composite') == 0 )
    {
      var compositeInfo = {
        "isDrillDownFromComposite": true,
        "filtercolumn" :  rowData['filter_column'],
        "compositeId" : link,
        "rowData" : rowData
      };
      this.onDrillDown.emit(compositeInfo);
    }
    else
    {
      //Added by Prajyot on 28FEB2020 - Conditional Drilldown
      console.log('drillCondition [', drillCondition, ']');
      if( drillCondition && !eval(drillCondition) )
      {
          return;
      }

      var drillColumnName = rowData.drillFrom;
      var drillColumnValue = rowData[drillColumnName];
      var selectedFieldInfo = {
          "isDrillDownFromComposite": false,
          "column" :  drillColumnName,
          "value" : drillColumnValue,
          "linkMetadata" : link,
          "rowData" : rowData
      };
      this.onDrillDown.emit(selectedFieldInfo);
    }
  }
  chart_component_data: any;
  bgColorArr: any = [];
  processColumnGroups()
  {
      var compDataLocal = [];
      try
      {
          compDataLocal = JSON.parse(this.reportData.data);
      }
      catch(e)
      {
          console.log('Catch...');
          compDataLocal = this.reportData.data;
      }

      if( this.drillDownCompositeInfo )
      {
          var filterColumn = this.drillDownCompositeInfo.filtercolumn;
          var filterValue = this.drillDownCompositeInfo.rowData[filterColumn];
          console.log('processColumnGroups filter data from reportData :', this.drillDownCompositeInfo);
          compDataLocal = FILTER_DATA(filterColumn, filterValue, compDataLocal);
          console.log('processColumnGroups filter data return :', compDataLocal);
      }

      var component_data: any = Object.assign([], compDataLocal);

      if(component_data.length == 0)
      {
          console.log('return from processColumnGroups as reportData is empty :', component_data);
          this.isDataAvailable = false;
          return;
      }

      var columnGroup= this.compositeConfig.column_group;
      console.log('processColumnGroups columnGroup :', columnGroup);
      console.log('processColumnGroups reportData :', component_data);
      console.log('this.compositeType:', this.compositeType);

      if(this.compositeType =='SERIES_CHART_PANEL') {
          console.log('SERIES_CHART_PANEL');
          this.chart_component_data = component_data;
          console.log('chart_component_data >', this.chart_component_data);

          if ( this.chart_component_data && this.chart_component_data.length > 0 ) {
              for ( var k = 0; k < this.chart_component_data.length; k++ ) {

                  if ( this.chart_component_data[k]['bgColorClass'] ) {
                      var bgColor = this.chart_component_data[k]['bgColorClass'];
                      console.log('bgColor  >>>', bgColor);
                      this.bgColorArr.push(bgColor);
                  }
              }
          }
            console.log('bgColorArr >>', this.bgColorArr);
      }
      var columnCellName: any = [];
      var columnDisplayValue: any = [];
      var columnCellDataType: any = [];
      var tableObject: any = {};
      if(columnGroup && columnGroup[0] !=null)
      {
          for(var colGroup of columnGroup)
          {
             var columns=colGroup.columns;
             console.log('columns>>>>',columns)

             if( columns != null )
             {
                 if( columns instanceof Array )
                 {
                 	 var returnAsArray = columns.length > 1;
                 	 console.log('returnAsArray::::',returnAsArray);
                     for(var colms of columns)
                     {
                         console.log('columns::::',colms)
                         var aggFunction = colms.aggFunction;
                         var columnName = colms.value;
                         var typeOfColumn = colms.type;
                         var groupBy = colms.groupBy;
                         var groupReturn = colms.groupAs;
                         var filterBy = colms.filterBy;
                         var filterByExpr = colms.filterByExpr;
                         //Added by Prasad on 01/06/2020 [added multiple condition to filter from json] START
                         console.log('filterByExpr::::',filterByExpr);
                         if( filterByExpr )
                         {
                             filterByExpr = this.replaceAll( filterByExpr, " and ", " && " );
                             filterByExpr = this.replaceAll( filterByExpr, " or ", " || " );
                         }
                         //Added by Prasad on 01/06/2020 [added multiple condition to filter from json] END
                         if(aggFunction=='SORT_BY')
                         {
                             var order = colms.order;
                             var notNullList = component_data.filter( (x: any) => {return x[columnName]});

                             var nullList = component_data.filter( (x: any) => {return !x[columnName]});

                             console.log('Null array',notNullList);
                             var sortedArray = SORT_BY(notNullList, columnName, typeOfColumn, order);
                             component_data = sortedArray.concat(nullList);

                             console.log('after sort by',component_data);
                         }
                         else if(aggFunction=='SUM')
                         {
                             component_data = GROUP_BY_KEYS(component_data, groupBy, groupReturn);
                             console.log('After GROUP_BY_KEYS :: ' , groupBy, groupReturn, component_data);
                             component_data = SUM(component_data, columnName, returnAsArray);
                             console.log('After SUM :: ' , columnName, component_data);
                         }
                         else if(aggFunction=='AVERAGE')
                         {
                             component_data = GROUP_BY_KEYS(component_data, groupBy, groupReturn);
                             console.log('After GROUP_BY_KEYS :: ' , groupBy, groupReturn, component_data);
                             component_data = AVERAGE(component_data, columnName, returnAsArray);
                             console.log('After AVERAGE :: ' , columnName, component_data);
                         }
                         else if(aggFunction=='UNIQUE')
                         {
                             component_data = GROUP_BY_KEYS(component_data, groupBy, groupReturn);
                             console.log('After GROUP_BY_KEYS :: ' , groupBy, groupReturn, component_data);
                             component_data = UNIQUE(component_data);
                             console.log('After UNIQUE :: ' , columnName, component_data);
                         }
                         else if(aggFunction=='RANK')
                         {
                             var filterkey = colms.filterkey;
                             var range = colms.range;
                             var iscontinuous = colms.continuous;
                             //component_data = RANK(component_data, columnName, filterkey, range);
                             component_data = RANK(component_data, columnName, filterkey, range, iscontinuous);
                             console.log('After RANK :: ' , iscontinuous, columnName, component_data);
                         }
                         else if(groupBy)
                         {
                             component_data = GROUP_BY_KEYS(component_data, groupBy, groupReturn);
                             console.log('Only groupBy \n After GROUP_BY_KEYS :: ' , groupBy, groupReturn, component_data);
                         }
                         else if(filterBy)
                         {
                             component_data = FILTER_DATA(filterBy, columnName, component_data);
                             console.log('Only filterBy \n After FILTER_DATA :: ' , filterBy, component_data);
                         }
                         else if(filterByExpr)
                         {
                             component_data = FILTER_DATA_BY_EXPR(filterByExpr, component_data);
                             console.log('Only filterByExpr \n After FILTER_DATA_BY_EXPR :: ' , filterByExpr, component_data);
                         }
                         else if(this.compositeType =='TABLE_PANEL'){
                             var name=colms.name;
                             var colActionStr = colms.actiontype;
                             var placeholder = colms.placeholder;
                             var errormessage = colms.errormessage;
                             var format = colms.format ? colms.format : "N";
                             columnCellName.push(name);
                             columnDisplayValue.push(columnName);
                             typeOfColumn = typeOfColumn == 'string' ? 'text' : typeOfColumn;
                             //columnCellDataType.push(typeOfColumn);
                             var colCellDataObj = {
                                "INPUT_TYPE": typeOfColumn,
                                "ACTION_STR": colActionStr,
                                "PLACEHOLDER": placeholder,
                                "ERROR_MSG": errormessage,
                                "FORMAT": format,
                                "GROUP_ID": "--"
                             }
                             columnCellDataType.push(colCellDataObj);

                             var cellType=colms.cellType;  // protected or editable or condition
                             if(cellType == 'protected')
                             {
                                tableObject[name+ '_P'] = '1';
                             }
                             if(cellType == 'editable')
                             {
                                tableObject[name+ '_P'] = '0';
                             }
                         }
                     }
                     if(returnAsArray)
                     {
				        var aggregateArr: any = [];
				        component_data.map((objArr: any)=>{
				            if ( objArr instanceof Array ) {
				                aggregateArr.push( objArr[0] );
				            }
				        });
				        if( aggregateArr.length > 0 )
				        {
				            component_data = aggregateArr;
				        }
				        console.log('final component_data ..',component_data);
                     }
                 }
                 else
                 {
                     var aggFunction=columns.aggFunction;
                     var columnName = columns.value;
                     var typeOfColumn=columns.type;
                     var groupBy = columns.groupBy;
                     var groupReturn = colms.groupAs;
                     var filterBy = colms.filterBy;
                     if(aggFunction=='SORT_BY')
                     {
                         var order = colms.order;
                         var notNullList = component_data.filter( (x: any) => {return x[columnName]});

                         var nullList = component_data.filter( (x: any) => {return !x[columnName]});

                         console.log('Null array',notNullList);
                         var sortedArray = SORT_BY(notNullList,columnName ,typeOfColumn,order);
                         component_data = sortedArray.concat(nullList);
                         console.log('after sort by',component_data);
                     }
                     else if(aggFunction=='SUM')
                     {
                         component_data = GROUP_BY_KEYS(component_data, groupBy, groupReturn);
                         console.log('After GROUP_BY_KEYS :: ' , groupBy, groupReturn, component_data);
                         component_data = SUM(component_data, columnName);
                         console.log('After SUM :: ' , columnName, component_data);
                     }
                     else if(aggFunction=='AVERAGE')
                     {
                         component_data = GROUP_BY_KEYS(component_data, groupBy, groupReturn);
                         console.log('After GROUP_BY_KEYS :: ' , groupBy, groupReturn, component_data);
                         component_data = AVERAGE(component_data, columnName);
                         console.log('After AVERAGE :: ' , columnName, component_data);
                     }
                     else if(aggFunction=='UNIQUE')
                     {
                         component_data = GROUP_BY_KEYS(component_data, groupBy, groupReturn);
                         console.log('After GROUP_BY_KEYS :: ' , groupBy, groupReturn, component_data);
                         component_data = UNIQUE(component_data);
                         console.log('After UNIQUE :: ' , columnName, component_data);
                     }
                     else if(aggFunction=='RANK')
                     {
                         var filterkey = colms.filterkey;
                         var range = colms.range;
                         var iscontinuous = colms.continuous;
                         //component_data = RANK(component_data, columnName, filterkey, range);
                         component_data = RANK(component_data, columnName, filterkey, range, iscontinuous);
                         console.log('After RANK :: ' ,iscontinuous , columnName, component_data);
                     }
                     else if(groupBy)
                     {
                         component_data = GROUP_BY_KEYS(component_data, groupBy, groupReturn);
                         console.log('Only groupBy \n After GROUP_BY_KEYS :: ' , groupBy, groupReturn, component_data);
                     }
                     else if(filterBy)
                     {
                         component_data = FILTER_DATA(filterBy, columnName, component_data);
                         console.log('Only filterBy \n After FILTER_DATA :: ' , filterBy, component_data);
                     }
                     else if(filterByExpr)
                     {
                         component_data = FILTER_DATA_BY_EXPR(filterByExpr, component_data);
                         console.log('Only filterByExpr \n After FILTER_DATA_BY_EXPR :: ' , filterByExpr, component_data);
                     }
                 }
             }
          }
       }
      if(this.compositeType =='TABLE_PANEL')
      {
          console.log('tableObject', tableObject);
          component_data = component_data.map( (data: any) => {
              var mergeData = Object.assign(data, tableObject);
              return mergeData;
          });
          component_data.unshift(columnCellDataType); //2
          component_data.unshift(columnDisplayValue); //1
          component_data.unshift(columnCellName); //0
          this.tableObjects = component_data;
          console.log('component_data ',component_data);
      }
      else if(this.compositeType =='TAB_PANEL')
      {
          this.tabData = component_data;
          this.tabConfig = UPDATE_TAB_DATA( component_data, this.tabConfig );
          console.log('tabConfig ==>', this.tabConfig);
      }
      else if(this.compositeType =='CHART_PANEL')
      {
          this.chartData = component_data;
      }
      else
      {
          this.compObjects = PREPARE_COMPOSITE_OBJECTS( component_data, this.component_config );
      }
  }

  formatDate(date: any)
  {
    console.log('Date in  formatDate>>>>',date);
    if(date.indexOf('/') > -1)
    {
        var splitDate =date.split("/");
        let firstdate= splitDate[0];
        let month= splitDate[1];
        var dateStr=month+'/'+firstdate+'/'+splitDate[2];
        console.log('updated formatDate::: :',dateStr);
    }
    else
    {
        var splitDate =date.split("-");
        let firstdate= splitDate[0];
        let month= splitDate[1];
        var dateStr=month+'-'+firstdate+'-'+splitDate[2];
        console.log('updated formatDate>>>>',dateStr);
    }
    return dateStr;
  }

  isSelectionAvailable()
  {
      if( this.link_metadata )
      {
          return true;
      }
      else if( this.component_config &&
               this.component_config.detailModel &&
               this.component_config.detailModel.link_metadata )
      {
          return true;
      }
      else
      {
          return false;
      }
  }

  performCustomCellAction(cellData: any)
  {
    console.log('inside dashboard-composite performCustomCellAction', cellData);
    var columnDef = cellData['COL_DEF'];
    var cellAction = columnDef['action'];
    switch(cellAction)
    {
        case 'CELL_ACTION_SAVE_TASK' :
            console.log('Cell Action To Be Performed :' , cellAction);
            this.saveTask(cellData);
            break;
        default :
            console.log('No Cell Action To Performed !');
    }
  }

  saveTask(taskData: any)
  {
    var assignedTo = taskData['EMP_NAME'];
    var userTaskData={
        "USER_ID__ASSIGNED":taskData['EMP_CODE'],
        "USER_ID__REPORT_TO":taskData['REPORT_TO'],
        "TASK_DESCR":taskData['ACTION'],
        "CURR_STATUS":"P",
        "TASK_TYPE": "P",
        "REF_SER" : "SELL-P",
        "REF_ID" :  taskData['TRAN_ID'] + '~' + taskData['LINE_NO']
    };
    console.log("save::userTaskData ", userTaskData);

    var userTaskSubscription = this.userTaskSvc.saveUserTask(userTaskData).subscribe(
        (result: any) => {
          console.log("Result in performCustomCellAction from userTaskService.saveUserTask::",result);
        }
    );
    alert("Task created/changed for " + assignedTo );

    userTaskSubscription.unsubscribe();
  }

  // Added by Pravin K on 18-MAR-20 [To add-task popup]  START
  performAction(link: any)
  {
      console.log("DashboardCompositeComponent performAction", link);
      this.onPerformAction.emit(link);
  }
  // Added by Pravin K on 18-MAR-20 [To add-task popup]  END

  //Added by Prasad on 01/06/2020 [added multiple condition to filter from json] START
  /* Define function for escaping user input to be treated as a literal string within a regular expression */
  escapeRegExp(string: any){
    return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
  }

  /* Define functin to find and replace specified term with replacement string */
  replaceAll(str: any, term: any, replacement: any) {
    return str.replace(new RegExp(this.escapeRegExp(term), 'g'), replacement);
  }
  //Added by Prasad on 01/06/2020 [added multiple condition to filter from json] END

  closeDrillDown() {
    console.log('On Drill Down Close Dashboard Composite Compoenet ');
    this.onDrillDownClose.emit();
  }
}
