import * as Models from '../../models/models';
import { Chart, ChartColor, ChartData, ChartDataSets, ChartElementsOptions, ChartOptions, ChartTooltipItem } from 'chart.js';

export class HtmlScriptsFunctions{
  public suite: Models.ExtendedReport;
  public document: Document = {} as Document;
  // public centerNumber: string;


  public constructor( suite: Models.ExtendedReport ){
    this.suite = suite;
  }

  public dataFeatures = ( suite: Models.ExtendedReport ): ChartData => ( {
    datasets: [{
      backgroundColor: [
        '#228B22',
        '#E74C3C',
        '#b73122'
      ],
      data: [
        suite.results.features.passed,
        suite.results.features.failed,
        suite.results.features.ambiguous],
    }],
    labels: [
      'Passed',
      'Failed',
      'Ambiguous'
    ]
  } );

  public dataScenarios = ( suite: Models.ExtendedReport ): any => ( {
    datasets: [{
      backgroundColor: [
        '#228B22',
        '#E74C3C',
        '#FFD119',
        '#3498DB',
        '#b73122',
        '#F39C12'
      ],
      data: [
        suite.results.scenarios.passed,
        suite.results.scenarios.failed,
        suite.results.scenarios.pending,
        suite.results.scenarios.skipped,
        suite.results.scenarios.ambiguous,
        suite.results.scenarios.undefined,
      ]
    }],
    labels: [
      'Passed',
      'Failed',
      'Pending',
      'Skipped',
      'Ambiguous',
      'Undefined'
    ]
  } );

  public dataSteps = ( suiteOrFeature: Models.ExtendedReport| Models.Feature ): any => ( {
    datasets: [{
      backgroundColor: [
        '#228B22',
        '#E74C3C',
        '#FFD119',
        '#3498DB',
        '#b73122',
        '#F39C12'
      ],
      data: [
        suiteOrFeature.results.steps.passed,
        suiteOrFeature.results.steps.failed,
        suiteOrFeature.results.steps.pending,
        suiteOrFeature.results.steps.skipped,
        suiteOrFeature.results.steps.ambiguous,
        suiteOrFeature.results.steps.undefined
      ]
    }],
    labels: [
      'Passed',
      'Failed',
      'Pending',
      'Skipped',
      'Ambiguous',
      'Undefined'
    ]
  } );

  public graphOptions = (): ChartOptions => <ChartOptions> {
    // add numbers to donut pieces
    animation: {
      duration: 500,
      easing: 'easeOutQuart',
      onComplete ( ): void{
        const ctx = this.chart?.ctx as CanvasRenderingContext2D;
        // eslint-disable-next-line @typescript-eslint/no-unsafe-call
        ctx.font = Chart.helpers.fontString( Chart.defaults.global.defaultFontFamily, 'normal', Chart.defaults.global.defaultFontFamily ) as string;
        ctx.textAlign = 'center';
        ctx.textBaseline = 'bottom';
        ( this.chart as Chart ).height = 50;
        ( ( this.chart as Chart ).data.datasets as ChartDataSets[] ).forEach( ( dataset: ChartDataSets ) => {

          for ( let i = 0; i < ( dataset.data as number[] ).length; i++ ) {
            const model = ( this.chart as Chart ).getDatasetMeta( 0 ).data[i]._model;
            const midRadius = model.innerRadius as number + ( ( model.outerRadius as number ) - ( model.innerRadius as number ) ) / 2;
            const startAngle = model.startAngle;
            const endAngle = model.endAngle;
            const midAngle = startAngle as number + ( endAngle as number - ( startAngle as number ) ) / 2;
            const x = midRadius * Math.cos( midAngle );
            const y = midRadius * Math.sin( midAngle );

            ctx.fillStyle = '#fff';
            if ( i === 3 ) { // Darker text color for lighter background
              ctx.fillStyle = '#444';
            }
            // const percent = String( Math.round( dataset.data[i] / total * 100 ) ) + '%';
            if ( ( dataset.data as number[] )[i] !== 0 ) {
              ctx.fillText( ( dataset.data as number[] )[i].toString(), model.x + x, model.y + y );
            }
            // Display percent in another line, line break doesn't work for fillText
            /* if(percent != "0%" ){
                        ctx.fillText(percent, model.x + x, model.y + y + 15);
                        } */
          }
        } );
      }
    },
    elements: {
      center: {
        text: 'test'
      }
    },
    events:  ['true'],
    legend: {
      display: false
    },
    maintainAspectRatio: true,
    responsive: false,
    showTooltips: true,
    title: {
      display: true,
      text: 'chart'
    },
    tooltips: {
      callbacks: {
        label: ( tooltipItem: ChartTooltipItem, data: ChartData ): string => {
          const dataset = ( data?.datasets as ChartDataSets[] )[tooltipItem?.datasetIndex as number];
          const total = ( dataset.data as number[] )
            .reduce( ( previousValue: number, currentValue: number ) => previousValue + currentValue );
          const current = ( dataset.data as number[] )[tooltipItem.index as number];
          const precentage = Math.floor( ( ( current / total ) * 100 ) + 0.5 );
          return `${precentage}  %`;
        }
      }
    }
  };

  public legendCallback = ( chart: Chart ): string => {
    const data = chart.data;
    const datasets = data.datasets as ChartDataSets[];
    // const labels = data.labels;
    // console.log(chart.id);
    const text = [];
    text.push( `<table class=' + 1 + '-legend">
          <thead class="pb-7"><tr>
                      <th colspan="2" style="color: rgb(83,83,83); padding-bottom: 1em;">Status</th>
                      <th colspan="1" style="color: rgb(83,83,83); padding-bottom: 1em;">Progress</th>
                      </tr></thead><tbody>` );

    for ( let i = 0; i < ( ( chart.data.datasets as ChartDataSets[] )[0].data as number[] ).length; i++ ) {

      let labelIcon = null;
      switch( ( chart.data.labels as string[] )[i] ){
      case 'Passed':
        labelIcon = 'mr-5 fas fa-check-circle passed-color';
        break;
      case 'Failed':
        labelIcon = 'mr-5 fas fa-exclamation-circle failed-color';
        break;
      case 'Pending':
        labelIcon = 'mr-5 fas fa-minus-circle';
        break;
      case 'Skipped':
        labelIcon = 'mr-5 fas fa-arrow-circle-right';
        break;
      case 'Ambiguous':
        labelIcon = 'mr-5 fas fa-bolt';
        break;
      case 'Undefined':
        labelIcon = 'mr-5 fas fa-question-circle undefined-color';
        break;
      }

      const labelStyle = `style= "background-color:${( <ChartColor[]>( chart.data.datasets as ChartDataSets[] )[0].backgroundColor )[i] as string};color:white; "`;
      text.push( `<tr><td align="right"><i class=" ${labelIcon as string} "></i></td>` );
      text.push( `<td><span class="justify-content-begin" ${labelStyle} > ${( chart.data.labels as string[] )[i]} </span></td>` );
      text.push( `<td align="right"><span  >${ ( datasets[0].data as number[] )[i]} % </span></td></tr>` );


    }
    text.push( '</tbody></table>' );
    return text.join( '' );
  };

  // add numbers to donut pieces
  public pluginBeforeDrawOptions = ( chart: Chart ): void => {
    const width = chart.width;
    const height = chart.height;
    const ctx = chart.ctx as CanvasRenderingContext2D;

    ctx.restore();
    // const centerConfig = chart.config.options.elements.center;
    // const fontStyle = centerConfig.fontStyle || 'Arial';
    // const txtvalue = centerConfig.text;
    // const color = centerConfig.color || '#000';
    // const maxFontSize = centerConfig.maxFontSize || 75;
    // const sidePadding = centerConfig.sidePadding || 20;
    // const sidePaddingCalculated = ( sidePadding / 100 ) * ( chart.innerRadius * 2 );

    const fontSize = ( height as number / 114 ).toFixed( 2 );
    ctx.font = fontSize + 'em sans-serif';
    // ctx.font = "30px " + fontStyle;
    ctx.textBaseline = 'middle';

    const text = ( ( chart.config.options as ChartOptions ).elements as ChartElementsOptions ).text;
    const textX = Math.round( ( width as number - ctx.measureText( text as string ).width ) / 2 );
    const textY = ( height as number + chart.chartArea.top ) / 2;

    ctx.fillStyle = '#696969';
    ctx.fillText( text as string, textX, textY );
    ctx.save();
  };


  public generateChart = ( chartName: string, chartData: ChartData, graphOptions: ChartOptions,
                           pluginBeforeDrawOptions: ( chart: Chart ) => any ,
                           legendCallback: ( chart: Chart ) => string, chartCenterValue: string ): Chart =>{
    const canvas = <HTMLCanvasElement> document.getElementById( chartName );
    const ctx = canvas.getContext( '2d' ) as CanvasRenderingContext2D;
    graphOptions.legendCallback = legendCallback;
    ( graphOptions.elements as ChartElementsOptions ).text = chartCenterValue;
    Chart.pluginService.register( {
      beforeDraw: pluginBeforeDrawOptions
    } );
    const chart = new Chart( ctx, {
      data: chartData,
      options: graphOptions,
      type: 'doughnut'
      // tooltipFillColor: 'rgba(51, 51, 51, 0.55)',
    } );

    ( document.getElementById( chartName + '-chart' ) as HTMLElement ).innerHTML = chart.generateLegend().toString();
    ( document.getElementById( chartName + '-chart' ) as HTMLElement ).className = 'd-flex flex-row mt-2 mr-0';

    return chart;
  };
}
