// ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
// ┃ ██████ ██████ ██████       █      █      █      █      █ █▄  ▀███ █       ┃
// ┃ ▄▄▄▄▄█ █▄▄▄▄▄ ▄▄▄▄▄█  ▀▀▀▀▀█▀▀▀▀▀ █ ▀▀▀▀▀█ ████████▌▐███ ███▄  ▀█ █ ▀▀▀▀▀ ┃
// ┃ █▀▀▀▀▀ █▀▀▀▀▀ █▀██▀▀ ▄▄▄▄▄ █ ▄▄▄▄▄█ ▄▄▄▄▄█ ████████▌▐███ █████▄   █ ▄▄▄▄▄ ┃
// ┃ █      ██████ █  ▀█▄       █ ██████      █      ███▌▐███ ███████▄ █       ┃
// ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
// ┃ Copyright (c) 2017, the Perspective Authors.                              ┃
// ┃ ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ ┃
// ┃ This file is part of the Perspective library, distributed under the terms ┃
// ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃
// ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛

import type { PlotLayout } from "../../layout/plot-layout";
import type { AxisDomain } from "../../axis/numeric-axis";
import type {
    CategoricalDomain,
    CategoricalLevel,
} from "../../axis/categorical-axis";
import type { ZoomConfig } from "../../interaction/zoom-controller";
import { AbstractChart } from "../chart-base";

/**
 * Common base for charts with a categorical X axis, a numeric Y (value)
 * axis, and an optional zoom-on-categorical interaction. Today that's
 * Bar (all four Y-family plugins + X Bar) and Candlestick/OHLC.
 *
 * The class is deliberately thin: it consolidates the bookkeeping that
 * genuinely repeats across those chart families (categorical domain
 * state, last-frame cache for overlay-only redraws, value-axis lock
 * default, shared GL-program + corner-buffer fields) and nothing more.
 * Glyph rendering, hit-testing, build pipelines, and horizontal / dual-
 * axis variance live in the concrete subclasses because they diverge
 * too much to usefully share.
 */
export abstract class CategoricalYChart extends AbstractChart {
    //  Categorical X axis state
    /**
     * Row-path levels (group_by hierarchy) for X-axis tick rendering.
     */
    _rowPaths: CategoricalLevel[] = [];

    /**
     * Number of categories on the X axis.
     */
    _numCategories = 0;

    /**
     * Offset into the aggregated-row stream (total-rows are skipped).
     */
    _rowOffset = 0;

    //  Shared GL resources
    _program: WebGLProgram | null = null;
    _cornerBuffer: WebGLBuffer | null = null;

    //  Last-frame cache (for chrome-only redraws)
    _lastLayout: PlotLayout | null = null;
    _lastXDomain: CategoricalDomain | null = null;
    _lastYDomain: AxisDomain | null = null;
    _lastYTicks: number[] | null = null;

    //  Auto-fit value axis (opt-in per chart)
    /**
     * When true, the value axis refits to the visible categorical
     * window each frame — so zooming the categorical axis tightens the
     * value axis to just the bars / candles in view. Subclasses own
     * the per-frame cache object because the cache key shape varies
     * (bar needs `hiddenSeries`, candlestick doesn't; bar may have
     * dual-axis extents, candlestick is single-axis).
     */
    _autoFitValue = true;

    /**
     * Lock the value axis by default — user wheel/pan should only
     * scroll the categorical axis. Subclasses override to flip
     * orientation (e.g. X Bar where the value axis is on X).
     */
    protected override getZoomConfig(): ZoomConfig {
        return { lockAxis: "y" };
    }
}
