import { ChartType, IDataset } from './chart-type';

interface IOptions {
  type: ChartType;
  color: string;
  innerRadius: number;
  radius: string | number;
}

interface IArea {
  top: number;
  right: number;
  bottom: number;
  left: number;
}

interface IChart {
  chartArea: IArea;
  config: { type: ChartType };
  ctx: CanvasRenderingContext2D;
  data: { datasets: IDataset[] };
}

export class PluginNodata {
  static config() {
    const calculate = (radius: number, config: string | number): number => {
      if (typeof config === 'string' && config.indexOf('%') > -1) {
        const value = +config.replace('%', '') / 100;
        return value * radius;
      } else {
        return config as number;
      }
    };

    return {
      id: 'nodata',
      afterDraw(chart: IChart, args: any, options: IOptions) {
        const { datasets } = chart.data ?? { datasets: [] };
        const { type, color, innerRadius, radius } = options;

        const hasData: boolean = datasets
          .map((ds: IDataset) => ds.data?.length > 0)
          .reduce((acc: boolean, cur: boolean) => acc || cur, false);

        if (!hasData) {
          const {
            chartArea: { left, top, right, bottom },
            ctx,
          } = chart;

          if (type === ChartType.Pie) {
            const centerX = (left + right) / 2;
            const centerY = (top + bottom) / 2;
            const r = Math.min(right - left, bottom - top) / 2;
            const ir = calculate(r, innerRadius);
            const or = calculate(r, radius);
            const width = or - ir;

            ctx.beginPath();
            ctx.lineWidth = width;
            ctx.strokeStyle = color ?? 'rgba(250, 250, 250, 0.5)';
            ctx.arc(centerX, centerY, or - width / 2, 0, 2 * Math.PI);
            ctx.stroke();
          }
        }
      },
      defaults: {
        type: ChartType.Pie,
        color: 'rgba(250, 250, 250, 0.5)',
        innerRadius: 0,
        radius: '100%',
      } as IOptions,
    };
  }
}
