/* global echarts */
(function nativeObservabilityReportPreviewBehavior(
  Drupal,
  once,
  drupalSettings,
) {
  function buildTimeseriesOption(settings) {
    return {
      animation: true,
      tooltip: { trigger: 'axis' },
      legend: {
        top: 0,
        left: 'center',
        data: (settings.series || []).map((serie) => serie.name || ''),
      },
      grid: { left: 56, right: 72, top: 56, bottom: 40 },
      xAxis: {
        type: 'category',
        boundaryGap: false,
        data: settings.labels || [],
      },
      yAxis: settings.y_axes || [{ type: 'value', name: '', position: 'left' }],
      series: (settings.series || []).map((serie) => ({
        name: serie.name || '',
        type: serie.type || 'line',
        smooth: serie.smooth !== false,
        symbol: serie.symbol || 'none',
        yAxisIndex: Number(serie.y_axis_index || 0),
        areaStyle: serie.area ? {} : undefined,
        data: serie.data || [],
      })),
    };
  }

  function buildScatterOption(settings) {
    const points = settings.points || [];

    return {
      animation: true,
      tooltip: {
        trigger: 'item',
        formatter(params) {
          const point =
            params.data && params.data.meta ? params.data.meta : null;
          if (!point) {
            return '';
          }

          return [
            `<strong>${point.label || ''}</strong>`,
            Drupal.t('Request time: @value ms', {
              '@value': point.request_duration_ms || 0,
            }),
            Drupal.t('DB time: @value ms', { '@value': point.db_time_ms || 0 }),
            Drupal.t('Requests: @value', {
              '@value': point.request_count || 0,
            }),
            Drupal.t('Slow rate: @value%', { '@value': point.slow_rate || 0 }),
          ].join('<br>');
        },
      },
      grid: { left: 56, right: 32, top: 32, bottom: 48 },
      xAxis: { type: 'value', name: Drupal.t('Request Time (ms)') },
      yAxis: { type: 'value', name: Drupal.t('DB Time (ms)') },
      series: [
        {
          type: 'scatter',
          symbolSize(value) {
            return Math.max(10, Math.min(42, Number(value[2] || 10)));
          },
          data: points.map((point) => ({
            value: [
              Number(point.request_duration_ms || 0),
              Number(point.db_time_ms || 0),
              Number(point.request_count || 0),
            ],
            meta: point,
          })),
        },
      ],
    };
  }

  function buildPieOption(settings) {
    return {
      animation: true,
      tooltip: { trigger: 'item' },
      legend: { top: 0, left: 'center' },
      series: [
        {
          name: settings.series_name || '',
          type: 'pie',
          radius: ['42%', '68%'],
          center: ['50%', '58%'],
          avoidLabelOverlap: true,
          label: { formatter: '{b}: {d}%' },
          data: settings.data || [],
        },
      ],
    };
  }

  function buildGaugeOption(settings) {
    return {
      animation: true,
      series: [
        {
          name: settings.series_name || '',
          type: 'gauge',
          min: 0,
          max: Number(settings.max || 100),
          detail: {
            valueAnimation: true,
            formatter(value) {
              return `${Math.round(value)}/${Number(settings.max || 100)}`;
            },
          },
          data: [
            {
              value: Number(settings.value || 0),
              name: settings.series_name || '',
            },
          ],
        },
      ],
    };
  }

  function buildRadarOption(settings) {
    return {
      animation: true,
      tooltip: {},
      radar: {
        indicator: settings.indicators || [],
      },
      series: [
        {
          name: settings.series_name || '',
          type: 'radar',
          data: [
            { value: settings.values || [], name: settings.series_name || '' },
          ],
        },
      ],
    };
  }

  function buildCategoryBarOption(settings) {
    return {
      animation: true,
      tooltip: { trigger: 'axis' },
      legend: { top: 0, left: 'center' },
      grid: { left: 56, right: 32, top: 56, bottom: 48 },
      xAxis: {
        type: 'category',
        data: settings.categories || [],
        axisLabel: { interval: 0, rotate: 18 },
      },
      yAxis: { type: 'value' },
      series: (settings.series || []).map((serie) => ({
        name: serie.name || '',
        type: 'bar',
        data: serie.data || [],
      })),
    };
  }

  function buildHorizontalBarOption(settings) {
    return {
      animation: true,
      tooltip: { trigger: 'axis' },
      legend: { top: 0, left: 'center' },
      grid: { left: 160, right: 32, top: 56, bottom: 24 },
      xAxis: { type: 'value' },
      yAxis: {
        type: 'category',
        data: settings.categories || [],
      },
      series: (settings.series || []).map((serie) => ({
        name: serie.name || '',
        type: 'bar',
        data: serie.data || [],
      })),
    };
  }

  function resolveOptionBuilder(renderer) {
    switch (renderer) {
      case 'scatter':
        return buildScatterOption;
      case 'pie':
        return buildPieOption;
      case 'gauge':
        return buildGaugeOption;
      case 'radar':
        return buildRadarOption;
      case 'category_bar':
        return buildCategoryBarOption;
      case 'horizontal_bar':
        return buildHorizontalBarOption;
      case 'timeseries':
      default:
        return buildTimeseriesOption;
    }
  }

  function initChart(element, settings) {
    if (element.dataset.chartReady === 'true') {
      return;
    }

    if (typeof echarts === 'undefined') {
      element.innerHTML = `<div class="no-report-preview__chart-fallback">${Drupal.t('Apache ECharts is not available.')}</div>`;
      return;
    }

    if (!element.clientWidth || !element.clientHeight) {
      window.requestAnimationFrame(function retryReportPreviewChartInit() {
        initChart(element, settings);
      });
      return;
    }

    const optionBuilder = resolveOptionBuilder(
      settings.renderer || 'timeseries',
    );
    if (!optionBuilder) {
      element.innerHTML = `<div class="no-report-preview__chart-fallback">${Drupal.t('Unsupported chart renderer.')}</div>`;
      return;
    }

    const chart = echarts.init(element);
    chart.setOption(optionBuilder(settings));
    chart.resize();

    window.addEventListener('resize', function resizeReportPreviewChart() {
      chart.resize();
    });

    if (typeof ResizeObserver !== 'undefined') {
      const observer = new ResizeObserver(
        function observeReportPreviewResize() {
          chart.resize();
        },
      );
      observer.observe(element);
    }

    element.dataset.chartReady = 'true';
  }

  Drupal.behaviors.nativeObservabilityReportPreview = {
    attach(context) {
      const charts =
        drupalSettings.nativeObservabilityReport?.previewCharts || {};

      once(
        'native-observability-report-preview',
        '[data-no-report-chart-id]',
        context,
      ).forEach((element) => {
        const chartId = element.getAttribute('data-no-report-chart-id');
        if (!chartId || !charts[chartId]) {
          return;
        }

        initChart(element, charts[chartId]);
      });
    },
  };
})(Drupal, once, drupalSettings);
