/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you 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 * as zrUtil from 'zrender/src/core/util';
import * as numberUtil from '../../util/number';
import sliderMove from '../helper/sliderMove';
import GlobalModel from '../../model/Global';
import SeriesModel from '../../model/Series';
import ExtensionAPI from '../../core/ExtensionAPI';
import { Dictionary } from '../../util/types';
// TODO Polar?
import DataZoomModel from './DataZoomModel';
import { AxisBaseModel } from '../../coord/AxisBaseModel';
import { unionAxisExtentFromData } from '../../coord/axisHelper';
import { ensureScaleRawExtentInfo } from '../../coord/scaleRawExtentInfo';
import { getAxisMainType, isCoordSupported, DataZoomAxisDimension } from './helper';
import { SINGLE_REFERRING } from '../../util/model';

const each = zrUtil.each;
const asc = numberUtil.asc;

interface MinMaxSpan {
    minSpan: number
    maxSpan: number
    minValueSpan: number
    maxValueSpan: number
}

type SupportedAxis = 'xAxis' | 'yAxis' | 'angleAxis' | 'radiusAxis' | 'singleAxis';

/**
 * Operate single axis.
 * One axis can only operated by one axis operator.
 * Different dataZoomModels may be defined to operate the same axis.
 * (i.e. 'inside' data zoom and 'slider' data zoom components)
 * So dataZoomModels share one axisProxy in that case.
 */
class AxisProxy {

    ecModel: GlobalModel;

    private _dimName: DataZoomAxisDimension;
    private _axisIndex: number;

    private _valueWindow: [number, number];
    private _percentWindow: [number, number];

    private _dataExtent: [number, number];

    private _minMaxSpan: MinMaxSpan;

    private _dataZoomModel: DataZoomModel;

    constructor(
        dimName: DataZoomAxisDimension,
        axisIndex: number,
        dataZoomModel: DataZoomModel,
        ecModel: GlobalModel
    ) {
        this._dimName = dimName;

        this._axisIndex = axisIndex;

        this.ecModel = ecModel;

        this._dataZoomModel = dataZoomModel;

        // /**
        //  * @readOnly
        //  * @private
        //  */
        // this.hasSeriesStacked;
    }

    /**
     * Whether the axisProxy is hosted by dataZoomModel.
     */
    hostedBy(dataZoomModel: DataZoomModel): boolean {
        return this._dataZoomModel === dataZoomModel;
    }

    /**
     * @return Value can only be NaN or finite value.
     */
    getDataValueWindow() {
        return this._valueWindow.slice() as [number, number];
    }

    /**
     * @return {Array.<number>}
     */
    getDataPercentWindow() {
        return this._percentWindow.slice() as [number, number];
    }

    getTargetSeriesModels() {
        const seriesModels: SeriesModel[] = [];

        this.ecModel.eachSeries(function (seriesModel) {
            if (isCoordSupported(seriesModel)) {
                const axisMainType = getAxisMainType(this._dimName);
                const axisModel = seriesModel.getReferringComponents(axisMainType, SINGLE_REFERRING).models[0];
                if (axisModel && this._axisIndex === axisModel.componentIndex) {
                    seriesModels.push(seriesModel);
                }
            }
        }, this);

        return seriesModels;
    }

    getAxisModel(): AxisBaseModel {
        return this.ecModel.getComponent(this._dimName + 'Axis', this._axisIndex) as AxisBaseModel;
    }

    getMinMaxSpan() {
        return zrUtil.clone(this._minMaxSpan);
    }

    /**
     * Only calculate by given range and this._dataExtent, do not change anything.
     */
    calculateDataWindow(opt?: {
        start?: number
        end?: number
        startValue?: number
        endValue?: number
    }) {
        const dataExtent = this._dataExtent;
        const axisModel = this.getAxisModel();
        const scale = axisModel.axis.scale;
        const rangePropMode = this._dataZoomModel.getRangePropMode();
        const percentExtent = [0, 100];
        const percentWindow = [] as unknown as [number, number];
        const valueWindow = [] as unknown as [number, number];
        let hasPropModeValue;

        each(['start', 'end'] as const, function (prop, idx) {
            let boundPercent = opt[prop];
            let boundValue = opt[prop + 'Value' as 'startValue' | 'endValue'];

            // Notice: dataZoom is based either on `percentProp` ('start', 'end') or
            // on `valueProp` ('startValue', 'endValue'). (They are based on the data extent
            // but not min/max of axis, which will be calculated by data window then).
            // The former one is suitable for cases that a dataZoom component controls multiple
            // axes with different unit or extent, and the latter one is suitable for accurate
            // zoom by pixel (e.g., in dataZoomSelect).
            // we use `getRangePropMode()` to mark which prop is used. `rangePropMode` is updated
            // only when setOption or dispatchAction, otherwise it remains its original value.
            // (Why not only record `percentProp` and always map to `valueProp`? Because
            // the map `valueProp` -> `percentProp` -> `valueProp` probably not the original
            // `valueProp`. consider two axes constrolled by one dataZoom. They have different
            // data extent. All of values that are overflow the `dataExtent` will be calculated
            // to percent '100%').

            if (rangePropMode[idx] === 'percent') {
                boundPercent == null && (boundPercent = percentExtent[idx]);
                // Use scale.parse to math round for category or time axis.
                boundValue = scale.parse(numberUtil.linearMap(
                    boundPercent, percentExtent, dataExtent
                ));
            }
            else {
                hasPropModeValue = true;
                boundValue = boundValue == null ? dataExtent[idx] : scale.parse(boundValue);
                // Calculating `percent` from `value` may be not accurate, because
                // This calculation can not be inversed, because all of values that
                // are overflow the `dataExtent` will be calculated to percent '100%'
                boundPercent = numberUtil.linearMap(
                    boundValue, dataExtent, percentExtent
                );
            }

            // valueWindow[idx] = round(boundValue);
            // percentWindow[idx] = round(boundPercent);
            valueWindow[idx] = boundValue;
            percentWindow[idx] = boundPercent;
        });

        asc(valueWindow);
        asc(percentWindow);

        // The windows from user calling of `dispatchAction` might be out of the extent,
        // or do not obey the `min/maxSpan`, `min/maxValueSpan`. But we dont restrict window
        // by `zoomLock` here, because we see `zoomLock` just as a interaction constraint,
        // where API is able to initialize/modify the window size even though `zoomLock`
        // specified.
        const spans = this._minMaxSpan;
        hasPropModeValue
            ? restrictSet(valueWindow, percentWindow, dataExtent, percentExtent, false)
            : restrictSet(percentWindow, valueWindow, percentExtent, dataExtent, true);

        function restrictSet(
            fromWindow: number[],
            toWindow: number[],
            fromExtent: number[],
            toExtent: number[],
            toValue: boolean
        ) {
            const suffix = toValue ? 'Span' : 'ValueSpan';
            sliderMove(
                0, fromWindow, fromExtent, 'all',
                spans['min' + suffix as 'minSpan' | 'minValueSpan'],
                spans['max' + suffix as 'maxSpan' | 'maxValueSpan']
            );
            for (let i = 0; i < 2; i++) {
                toWindow[i] = numberUtil.linearMap(fromWindow[i], fromExtent, toExtent, true);
                toValue && (toWindow[i] = scale.parse(toWindow[i]));
            }
        }

        return {
            valueWindow: valueWindow,
            percentWindow: percentWindow
        };
    }

    /**
     * Notice: reset should not be called before series.restoreData() called,
     * so it is recommanded to be called in "process stage" but not "model init
     * stage".
     */
    reset(dataZoomModel: DataZoomModel) {
        if (dataZoomModel !== this._dataZoomModel) {
            return;
        }

        const targetSeries = this.getTargetSeriesModels();
        // Culculate data window and data extent, and record them.
        this._dataExtent = calculateDataExtent(this, this._dimName, targetSeries);

        // this.hasSeriesStacked = false;
        // each(targetSeries, function (series) {
            // let data = series.getData();
            // let dataDim = data.mapDimension(this._dimName);
            // let stackedDimension = data.getCalculationInfo('stackedDimension');
            // if (stackedDimension && stackedDimension === dataDim) {
                // this.hasSeriesStacked = true;
            // }
        // }, this);

        // `calculateDataWindow` uses min/maxSpan.
        this._updateMinMaxSpan();

        const dataWindow = this.calculateDataWindow(dataZoomModel.settledOption);

        this._valueWindow = dataWindow.valueWindow;
        this._percentWindow = dataWindow.percentWindow;

        // Update axis setting then.
        this._setAxisModel();
    }

    filterData(dataZoomModel: DataZoomModel, api: ExtensionAPI) {
        if (dataZoomModel !== this._dataZoomModel) {
            return;
        }

        const axisDim = this._dimName;
        const seriesModels = this.getTargetSeriesModels();
        const filterMode = dataZoomModel.get('filterMode');
        const valueWindow = this._valueWindow;

        if (filterMode === 'none') {
            return;
        }

        // FIXME
        // Toolbox may has dataZoom injected. And if there are stacked bar chart
        // with NaN data, NaN will be filtered and stack will be wrong.
        // So we need to force the mode to be set empty.
        // In fect, it is not a big deal that do not support filterMode-'filter'
        // when using toolbox#dataZoom, utill tooltip#dataZoom support "single axis
        // selection" some day, which might need "adapt to data extent on the
        // otherAxis", which is disabled by filterMode-'empty'.
        // But currently, stack has been fixed to based on value but not index,
        // so this is not an issue any more.
        // let otherAxisModel = this.getOtherAxisModel();
        // if (dataZoomModel.get('$fromToolbox')
        //     && otherAxisModel
        //     && otherAxisModel.hasSeriesStacked
        // ) {
        //     filterMode = 'empty';
        // }

        // TODO
        // filterMode 'weakFilter' and 'empty' is not optimized for huge data yet.

        each(seriesModels, function (seriesModel) {
            let seriesData = seriesModel.getData();
            const dataDims = seriesData.mapDimensionsAll(axisDim);

            if (!dataDims.length) {
                return;
            }

            if (filterMode === 'weakFilter') {
                seriesData.filterSelf(function (dataIndex) {
                    let leftOut;
                    let rightOut;
                    let hasValue;
                    for (let i = 0; i < dataDims.length; i++) {
                        const value = seriesData.get(dataDims[i], dataIndex) as number;
                        const thisHasValue = !isNaN(value);
                        const thisLeftOut = value < valueWindow[0];
                        const thisRightOut = value > valueWindow[1];
                        if (thisHasValue && !thisLeftOut && !thisRightOut) {
                            return true;
                        }
                        thisHasValue && (hasValue = true);
                        thisLeftOut && (leftOut = true);
                        thisRightOut && (rightOut = true);
                    }
                    // If both left out and right out, do not filter.
                    return hasValue && leftOut && rightOut;
                });
            }
            else {
                each(dataDims, function (dim) {
                    if (filterMode === 'empty') {
                        seriesModel.setData(
                            seriesData = seriesData.map(dim, function (value: number) {
                                return !isInWindow(value) ? NaN : value;
                            })
                        );
                    }
                    else {
                        const range: Dictionary<[number, number]> = {};
                        range[dim] = valueWindow;

                        // console.time('select');
                        seriesData.selectRange(range);
                        // console.timeEnd('select');
                    }
                });
            }

            each(dataDims, function (dim) {
                seriesData.setApproximateExtent(valueWindow, dim);
            });
        });

        function isInWindow(value: number) {
            return value >= valueWindow[0] && value <= valueWindow[1];
        }
    }

    private _updateMinMaxSpan() {
        const minMaxSpan = this._minMaxSpan = {} as MinMaxSpan;
        const dataZoomModel = this._dataZoomModel;
        const dataExtent = this._dataExtent;

        each(['min', 'max'], function (minMax) {
            let percentSpan = dataZoomModel.get(minMax + 'Span' as 'minSpan' | 'maxSpan');
            let valueSpan = dataZoomModel.get(minMax + 'ValueSpan' as 'minValueSpan' | 'maxValueSpan');
            valueSpan != null && (valueSpan = this.getAxisModel().axis.scale.parse(valueSpan));

            // minValueSpan and maxValueSpan has higher priority than minSpan and maxSpan
            if (valueSpan != null) {
                percentSpan = numberUtil.linearMap(
                    dataExtent[0] + valueSpan, dataExtent, [0, 100], true
                );
            }
            else if (percentSpan != null) {
                valueSpan = numberUtil.linearMap(
                    percentSpan, [0, 100], dataExtent, true
                ) - dataExtent[0];
            }

            minMaxSpan[minMax + 'Span' as 'minSpan' | 'maxSpan'] = percentSpan;
            minMaxSpan[minMax + 'ValueSpan' as 'minValueSpan' | 'maxValueSpan'] = valueSpan;
        }, this);
    }

    private _setAxisModel() {

        const axisModel = this.getAxisModel();

        const percentWindow = this._percentWindow;
        const valueWindow = this._valueWindow;

        if (!percentWindow) {
            return;
        }

        // [0, 500]: arbitrary value, guess axis extent.
        let precision = numberUtil.getPixelPrecision(valueWindow, [0, 500]);
        precision = Math.min(precision, 20);

        // For value axis, if min/max/scale are not set, we just use the extent obtained
        // by series data, which may be a little different from the extent calculated by
        // `axisHelper.getScaleExtent`. But the different just affects the experience a
        // little when zooming. So it will not be fixed until some users require it strongly.
        const rawExtentInfo = axisModel.axis.scale.rawExtentInfo;
        if (percentWindow[0] !== 0) {
            rawExtentInfo.setDeterminedMinMax('min', +valueWindow[0].toFixed(precision));
        }
        if (percentWindow[1] !== 100) {
            rawExtentInfo.setDeterminedMinMax('max', +valueWindow[1].toFixed(precision));
        }
        rawExtentInfo.freeze();
    }
}

function calculateDataExtent(axisProxy: AxisProxy, axisDim: string, seriesModels: SeriesModel[]) {
    const dataExtent = [Infinity, -Infinity];

    each(seriesModels, function (seriesModel) {
        unionAxisExtentFromData(dataExtent, seriesModel.getData(), axisDim);
    });

    // It is important to get "consistent" extent when more then one axes is
    // controlled by a `dataZoom`, otherwise those axes will not be synchronized
    // when zooming. But it is difficult to know what is "consistent", considering
    // axes have different type or even different meanings (For example, two
    // time axes are used to compare data of the same date in different years).
    // So basically dataZoom just obtains extent by series.data (in category axis
    // extent can be obtained from axis.data).
    // Nevertheless, user can set min/max/scale on axes to make extent of axes
    // consistent.
    const axisModel = axisProxy.getAxisModel();
    const rawExtentResult = ensureScaleRawExtentInfo(axisModel.axis.scale, axisModel, dataExtent).calculate();

    return [rawExtentResult.min, rawExtentResult.max] as [number, number];
}

export default AxisProxy;
