// Copyright (C) 2026 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

import m from 'mithril';
import type {EChartsCoreOption} from 'echarts/core';
import {extractBrushRect, formatNumber} from './chart_utils';
import {EChartView, type EChartEventHandler} from './echart_view';
import type {LegendPosition} from './common';
import {
  buildChartOption,
  buildLegendOption,
  buildSelectionMarkArea,
} from './chart_option_builder';

/**
 * A single data point in a scatter chart.
 */
export interface ScatterChartPoint {
  /** X-axis value */
  readonly x: number;
  /** Y-axis value */
  readonly y: number;
  /** Optional bubble size (for bubble charts) */
  readonly size?: number;
  /** Optional per-point color */
  readonly color?: string;
  /** Optional tooltip label */
  readonly label?: string;
}

/**
 * A series (group) of points in the scatter chart.
 */
export interface ScatterChartSeries {
  /** Display name for this series (shown in legend) */
  readonly name: string;
  /** Data points for this series */
  readonly points: readonly ScatterChartPoint[];
  /** Optional custom color for this series (applies to all points without individual color) */
  readonly color?: string;
}

/**
 * Data provided to a ScatterChart.
 */
export interface ScatterChartData {
  /** The series to display */
  readonly series: readonly ScatterChartSeries[];
}

export interface ScatterChartAttrs {
  /**
   * Scatter chart data to display, or undefined if loading.
   * When undefined, a loading spinner is shown.
   */
  readonly data: ScatterChartData | undefined;

  /**
   * Height of the chart in pixels. Defaults to 200.
   */
  readonly height?: number;

  /**
   * Label for the X axis.
   */
  readonly xAxisLabel?: string;

  /**
   * Label for the Y axis.
   */
  readonly yAxisLabel?: string;

  /**
   * Callback when brush selection completes (on mouseup).
   * Called with the selected X/Y rectangle.
   */
  readonly onBrush?: (range: {
    xMin: number;
    xMax: number;
    yMin: number;
    yMax: number;
  }) => void;

  /**
   * Selection rectangle to highlight on the chart. When provided, a shaded
   * region is drawn. The consumer controls this state — typically by feeding
   * the `onBrush` output back in.
   */
  readonly selection?: {
    readonly xMin: number;
    readonly xMax: number;
    readonly yMin: number;
    readonly yMax: number;
  };

  /**
   * Fill parent container. Defaults to false.
   */
  readonly fillParent?: boolean;

  /**
   * Custom class name for the container.
   */
  readonly className?: string;

  /**
   * Format function for X axis tick values.
   */
  readonly formatXValue?: (value: number) => string;

  /**
   * Format function for Y axis tick values.
   */
  readonly formatYValue?: (value: number) => string;

  /**
   * Use logarithmic scale for X axis. Defaults to false.
   */
  readonly logScaleX?: boolean;

  /**
   * Use logarithmic scale for Y axis. Defaults to false.
   */
  readonly logScaleY?: boolean;

  /**
   * Show legend. Defaults to true when multiple series.
   */
  readonly showLegend?: boolean;

  /**
   * Where the legend sits relative to the chart. Defaults to 'top'.
   */
  readonly legendPosition?: LegendPosition;

  /**
   * Default symbol size for points without explicit size.
   * Defaults to 8.
   */
  readonly symbolSize?: number;

  /**
   * Min/max symbol size for bubble charts (when points have size values).
   * Defaults to [5, 30].
   */
  readonly symbolSizeRange?: [number, number];

  /**
   * When true, axis ranges are computed from data min/max instead of
   * always including zero. Defaults to false.
   */
  readonly scaleAxes?: boolean;

  /**
   * Show grid lines. 'horizontal' draws lines parallel to the X axis,
   * 'vertical' draws lines parallel to the Y axis, 'both' shows both.
   * Defaults to no grid lines.
   */
  readonly gridLines?: 'horizontal' | 'vertical' | 'both';
}

export class Scatterplot implements m.ClassComponent<ScatterChartAttrs> {
  view({attrs}: m.Vnode<ScatterChartAttrs>) {
    const {data, height, fillParent, className, onBrush} = attrs;

    const isEmpty =
      data !== undefined &&
      (data.series.length === 0 ||
        data.series.every((s) => s.points.length === 0));
    const option =
      data !== undefined && !isEmpty
        ? buildScatterOption(attrs, data)
        : undefined;

    return m(EChartView, {
      option,
      height,
      fillParent,
      className,
      empty: isEmpty,
      eventHandlers: buildScatterEventHandlers(attrs),
      activeBrushType: onBrush !== undefined ? 'rect' : undefined,
    });
  }
}

function buildScatterOption(
  attrs: ScatterChartAttrs,
  data: ScatterChartData,
): EChartsCoreOption {
  const {
    xAxisLabel,
    yAxisLabel,
    formatXValue,
    formatYValue,
    logScaleX = false,
    logScaleY = false,
    showLegend,
    symbolSize = 8,
    symbolSizeRange = [5, 30],
  } = attrs;
  const fmtX = formatXValue ?? formatNumber;
  const fmtY = formatYValue ?? formatNumber;
  const displayLegend = showLegend ?? data.series.length > 1;

  // Compute size range for normalization if any points have sizes
  let minSize = Infinity;
  let maxSize = -Infinity;
  for (const s of data.series) {
    for (const p of s.points) {
      if (p.size !== undefined) {
        minSize = Math.min(minSize, p.size);
        maxSize = Math.max(maxSize, p.size);
      }
    }
  }
  const hasSizes = minSize !== Infinity;
  const sizeRange = maxSize - minSize || 1;

  const series = data.series.map((s, i) => {
    const base: Record<string, unknown> = {
      type: 'scatter' as const,
      name: s.name,
      // ECharts scatter series requires data as arrays with positional indices:
      // [0]: x value (number)
      // [1]: y value (number)
      // [2]: size value (number | null) - used for bubble sizing
      // [3]: label (string | undefined) - used for tooltip display
      // This positional format is mandated by ECharts API for scatter/bubble.
      data: s.points.map((p) => {
        const pointData: [number, number, ...unknown[]] = [p.x, p.y];
        if (p.size !== undefined) {
          pointData.push(p.size);
        } else if (p.label !== undefined) {
          // Placeholder null so label is always at index 3
          pointData.push(null);
        }
        if (p.label !== undefined) pointData.push(p.label);
        return {
          value: pointData,
          itemStyle: p.color !== undefined ? {color: p.color} : undefined,
        };
      }),
      symbolSize: hasSizes
        ? (value: Array<number | null>) => {
            const size = value.length > 2 ? value[2] : undefined;
            if (size === undefined || size === null) return symbolSize;
            const normalized = (size - minSize) / sizeRange;
            return (
              symbolSizeRange[0] +
              normalized * (symbolSizeRange[1] - symbolSizeRange[0])
            );
          }
        : symbolSize,
      itemStyle: s.color !== undefined ? {color: s.color} : undefined,
      emphasis: {
        itemStyle: {borderWidth: 2},
      },
    };

    // Render selection highlight on the first series only.
    if (i === 0 && attrs.selection !== undefined) {
      const sel = attrs.selection;
      base.markArea = buildSelectionMarkArea([
        [
          {xAxis: sel.xMin, yAxis: sel.yMin},
          {xAxis: sel.xMax, yAxis: sel.yMax},
        ],
      ]);
    }
    return base;
  });

  const option = buildChartOption({
    xAxis: {
      type: logScaleX ? 'log' : 'value',
      name: xAxisLabel,
      formatter:
        formatXValue !== undefined
          ? (v) => formatXValue(v as number)
          : undefined,
      // When brush is enabled, always scale axes to data range so that after
      // filtering the axes fit the selected region rather than anchoring at 0.
      scale: attrs.onBrush !== undefined || attrs.scaleAxes,
      showSplitLine:
        attrs.gridLines === 'vertical' || attrs.gridLines === 'both',
    },
    yAxis: {
      type: logScaleY ? 'log' : 'value',
      name: yAxisLabel,
      formatter:
        formatYValue !== undefined
          ? (v) => formatYValue(v as number)
          : undefined,
      scale: attrs.onBrush !== undefined || attrs.scaleAxes,
      showSplitLine:
        attrs.gridLines === 'horizontal' || attrs.gridLines === 'both',
    },
    tooltip: {
      trigger: 'item' as const,
      formatter: (params: {
        seriesName?: string;
        value?: [number, number, (number | null)?, string?];
        color?: string;
        marker?: string;
      }) => {
        const value = params.value;
        if (value === undefined) return '';
        const [x, y, size, label] = value;
        const lines = [
          `${params.marker ?? ''} ${params.seriesName ?? ''}`,
          `X: ${fmtX(x)}`,
          `Y: ${fmtY(y)}`,
        ];
        if (size !== undefined && size !== null) {
          lines.push(`Size: ${formatNumber(size)}`);
        }
        if (label !== undefined) lines.push(label);
        return lines.join('<br>');
      },
    },
    brush: attrs.onBrush
      ? {xAxisIndex: 0, yAxisIndex: 0, brushType: 'rect' as const}
      : undefined,
    legend: displayLegend
      ? buildLegendOption(attrs.legendPosition)
      : {show: false},
  });

  (option as Record<string, unknown>).series = series;
  return option;
}

function buildScatterEventHandlers(
  attrs: ScatterChartAttrs,
): ReadonlyArray<EChartEventHandler> {
  if (!attrs.onBrush) return [];
  const onBrush = attrs.onBrush;

  return [
    {
      eventName: 'brushEnd',
      handler: (params) => {
        const range = extractBrushRect(params);
        if (range !== undefined) {
          onBrush(range);
        }
      },
    },
  ];
}
