// 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 {formatNumber} from './chart_utils';
import {EChartView} from './echart_view';
import {
  buildAxisOption,
  buildGridOption,
  buildTooltipOption,
} from './chart_option_builder';

/**
 * A single box in a boxplot chart.
 */
export interface BoxplotItem {
  /** Label for this box (category name) */
  readonly label: string;
  /** Minimum value (lower whisker) */
  readonly min: number;
  /** First quartile (Q1 / 25th percentile) */
  readonly q1: number;
  /** Median (Q2 / 50th percentile) */
  readonly median: number;
  /** Third quartile (Q3 / 75th percentile) */
  readonly q3: number;
  /** Maximum value (upper whisker) */
  readonly max: number;
}

/**
 * Data provided to a BoxplotChart.
 */
export interface BoxplotData {
  readonly items: readonly BoxplotItem[];
}

export interface BoxplotAttrs {
  /**
   * Boxplot data to display, or undefined if loading.
   * When undefined, a loading spinner is shown.
   */
  readonly data: BoxplotData | undefined;

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

  /**
   * Label for the category axis.
   */
  readonly categoryLabel?: string;

  /**
   * Label for the value axis.
   */
  readonly valueLabel?: string;

  /**
   * Orientation: 'vertical' (categories on X) or 'horizontal' (categories on Y).
   * Defaults to 'vertical'.
   */
  readonly orientation?: 'vertical' | 'horizontal';

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

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

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

  /**
   * 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 BoxplotChart implements m.ClassComponent<BoxplotAttrs> {
  view({attrs}: m.CVnode<BoxplotAttrs>) {
    const {data, height, fillParent, className} = attrs;

    const isEmpty = data !== undefined && data.items.length === 0;
    const option =
      data !== undefined && !isEmpty
        ? buildBoxplotOption(attrs, data)
        : undefined;

    return m(EChartView, {
      option,
      height,
      fillParent,
      className,
      empty: isEmpty,
    });
  }
}

function buildBoxplotOption(
  attrs: BoxplotAttrs,
  data: BoxplotData,
): EChartsCoreOption {
  const {
    categoryLabel,
    valueLabel,
    orientation = 'vertical',
    formatValue,
    gridLines,
  } = attrs;
  const fmtVal = formatValue ?? formatNumber;
  const horizontal = orientation === 'horizontal';

  const showXAxisGrid = gridLines === 'vertical' || gridLines === 'both';
  const showYAxisGrid = gridLines === 'horizontal' || gridLines === 'both';

  const categories = data.items.map((item) => item.label);
  // ECharts boxplot series data format: [min, Q1, median, Q3, max].
  // In tooltip params.value, ECharts prepends the x-axis index, so the
  // actual values are at indices 1-5.
  const boxData = data.items.map((item) => [
    item.min,
    item.q1,
    item.median,
    item.q3,
    item.max,
  ]);

  const categoryAxis = buildAxisOption(
    {
      type: 'category',
      data: categories,
      name: categoryLabel,
      labelOverflow: 'truncate',
      labelWidth: 80,
      showSplitLine: horizontal ? showYAxisGrid : showXAxisGrid,
    },
    !horizontal,
  );

  const valueAxis = buildAxisOption(
    {
      type: 'value',
      name: valueLabel,
      formatter:
        formatValue !== undefined
          ? (v: number | string) => fmtVal(v as number)
          : undefined,
      scale: true,
      showSplitLine: horizontal ? showXAxisGrid : showYAxisGrid,
    },
    horizontal,
  );

  const option: Record<string, unknown> = {
    animation: false,
    grid: buildGridOption(),
    xAxis: horizontal ? valueAxis : categoryAxis,
    yAxis: horizontal ? categoryAxis : valueAxis,
    tooltip: buildTooltipOption({
      trigger: 'item' as const,
      formatter: (params: {name?: string; value?: number[]}) => {
        const v = params.value;
        if (v === undefined) return '';
        return [
          `<b>${params.name ?? ''}</b>`,
          `Max: ${fmtVal(v[5] ?? v[4])}`,
          `Q3: ${fmtVal(v[4] ?? v[3])}`,
          `Median: ${fmtVal(v[3] ?? v[2])}`,
          `Q1: ${fmtVal(v[2] ?? v[1])}`,
          `Min: ${fmtVal(v[1] ?? v[0])}`,
        ].join('<br>');
      },
    }),
    series: [
      {
        type: 'boxplot',
        data: boxData,
      },
    ],
  };

  return option as EChartsCoreOption;
}
