/*
* 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 {round, mathRound, mathMin, getPrecision} from '../util/number';
import {addCommas} from '../util/format';
import Scale, { ScaleGetTicksOpt } from './Scale';
import { getIntervalPrecision, IntervalScaleGetLabelOpt } from './helper';
import {ScaleTick, ScaleDataValue, NullUndefined, AxisBreakOption} from '../util/types';
import {
    AxisBreakParsingResult, getBreaksUnsafe, getScaleBreakHelper, hasBreaks, simplyParseBreakOption
} from './break';
import { assert, clone } from 'zrender/src/core/util';
import { getMinorTicks } from './minorTicks';
import {
    getScaleExtentForTickUnsafe,
    initBreakOrLinearMapper, ScaleMapperGeneric
} from './scaleMapper';
import { warn } from '../util/log';


export type IntervalScaleConfig = {
    interval: IntervalScaleConfigParsed['interval'];
    intervalPrecision?: IntervalScaleConfigParsed['intervalPrecision'] | NullUndefined;
    intervalCount?: IntervalScaleConfigParsed['intervalCount'] | NullUndefined;
    niceExtent?: IntervalScaleConfigParsed['niceExtent'] | NullUndefined;
};

type IntervalScaleConfigParsed = {
    /**
     * Step of ticks.
     */
    interval: number;
    intervalPrecision: number;
    /**
     * `_intervalCount` effectively specifies the number of "nice segments". This is for special cases,
     * such as `alignTicks: true` and min max are fixed. In this case, `_interval` may be specified with
     * a "not-nice" value and needs to be rounded with `_intervalPrecision` for better appearance. Then
     * merely accumulating `_interval` may generate incorrect number of ticks due to cumulative errors.
     * So `_intervalCount` is required to specify the expected nice ticks number.
     * Should ensure `_intervalCount >= -1`,
     *  where `-1` means no nice tick (e.g., `_extent: [5.2, 5.8], _interval: 1`),
     *  and `0` means only one nice tick (e.g., `_extent: [5, 5.8], _interval: 1`).
     * @see setInterval
     */
    intervalCount: number | NullUndefined;
    /**
     * Should ensure:
     *  `_extent[0] <= _niceExtent[0] && _niceExtent[1] <= _extent[1]`
     * But NOTICE:
     *  `_niceExtent[0] - _niceExtent[1] <= _interval`, rather than always `< 0`,
     *  because `_niceExtent` is typically calculated by
     *  `[ Math.ceil(_extent[0] / _interval) * _interval, Math.floor(_extent[1] / _interval) * _interval ]`.
     *  e.g., `_extent: [5.2, 5.8]` with interval `1` will get `_niceExtent: [6, 5]`.
     *  e.g., `_extent: [5, 5.8]` with interval `1` will get `_niceExtent: [5, 5]`.
     *  e.g., `_extent: [5.7, 5.7]` with interval `1` will get `_niceExtent: [6, 5]`.
     * @see setInterval
     */
    niceExtent: number[] | NullUndefined;
};

type IntervalScaleSetting = {
    // Either `breakOption` or `parsedBreaks` can be specified.
    breakOption?: AxisBreakOption[] | NullUndefined;
    breakParsed?: AxisBreakParsingResult | NullUndefined;
};

/**
 * @final NEVER inherit me!
 */
interface IntervalScale extends ScaleMapperGeneric<IntervalScale> {}
class IntervalScale extends Scale<IntervalScale> {

    static type = 'interval';
    type = 'interval' as const;

    private _cfg: IntervalScaleConfigParsed;


    constructor(setting?: IntervalScaleSetting) {
        super();

        this.parse = IntervalScale.parse;

        setting = setting || {};

        const breakParsed = simplyParseBreakOption(this, setting);

        const res = initBreakOrLinearMapper(this, breakParsed, null);
        // @ts-ignore
        this.brk = res.brk;

        this._cfg = {
            interval: 0,
            intervalPrecision: 2,
            intervalCount: undefined,
            niceExtent: undefined,
        };
    }

    static parse(val: ScaleDataValue): number {
        // `Scale#parse` (and its overrids) are typically applied at the axis values input
        // in echarts option. e.g., `axis.min/max`, `dataZoom.min/max`, etc.
        // but `series.data` is not included, which uses `dataValueHelper.ts`#`parseDataValue`.
        // `Scale#parse` originally introduced in fb8c813215098b9d2458966229bb95c510883d5e
        // at 2016 for dataZoom start/end settings (See `parseAxisModelMinMax`).
        //
        // Historically `scale/Interval.ts` returns the input value directly. But numeric
        // values (such as a number-like string '123') effectively passed through here and
        // were involved in calculations, which was error-prone and inconsistent with the
        // declared TS return type. Previously such issues are fixed separately in different
        // places case by case (such as #2475).
        //
        // Now, we perform actual parse to ensure its `number` type here. The parsing rule
        // follows the series data parsing rule (`dataValueHelper.ts`#`parseDataValue`)
        // and maintains compatibility as much as possible (thus a more strict parsing
        // `number.ts`#`numericToNumber` is not used here.)
        //
        // FIXME: `ScaleDataValue` also need to be modified to include numeric string type,
        //  since it effectively does.
        return (val == null || val === '')
            ? NaN
            // If string (like '-'), using '+' parse to NaN
            // If object, also parse to NaN
            : Number(val);
    }

    getConfig(): IntervalScaleConfigParsed {
        return clone(this._cfg);
    }

    setConfig(cfg: IntervalScaleConfig): void {
        const extent = getScaleExtentForTickUnsafe(this);

        if (__DEV__) {
            assert(cfg.interval != null);
            if (cfg.intervalCount != null) {
                assert(
                    cfg.intervalCount >= -1
                    && cfg.intervalPrecision != null
                    // Do not support intervalCount on axis break currently.
                    && !hasBreaks(this)
                );
            }
            if (cfg.niceExtent != null) {
                assert(isFinite(cfg.niceExtent[0]) && isFinite(cfg.niceExtent[1]));
                assert(extent[0] <= cfg.niceExtent[0] && cfg.niceExtent[1] <= extent[1]);
                assert(round(cfg.niceExtent[0] - cfg.niceExtent[1], getPrecision(cfg.interval)) <= cfg.interval);
            }
        }

        // Reset all.
        this._cfg = cfg = clone(cfg) as IntervalScaleConfigParsed;
        if (cfg.niceExtent == null) {
            // Dropped the auto calculated niceExtent and use user-set extent.
            // We assume users want to set both interval and extent to get a better result.
            cfg.niceExtent = extent.slice() as [number, number];
        }
        if (cfg.intervalPrecision == null) {
            cfg.intervalPrecision = getIntervalPrecision(cfg.interval);
        }
    }

    /**
     * In ascending order.
     */
    getTicks(opt?: ScaleGetTicksOpt): ScaleTick[] {
        opt = opt || {};
        const cfg = this._cfg;
        const interval = cfg.interval;
        const extent = getScaleExtentForTickUnsafe(this);
        const niceExtent = cfg.niceExtent;
        const intervalPrecision = cfg.intervalPrecision;
        const scaleBreakHelper = getScaleBreakHelper();
        const brk = this.brk;
        const brkAvailable = scaleBreakHelper && brk;

        const ticks = [] as ScaleTick[];
        // If interval is 0, return [];
        if (!interval) {
            return ticks;
        }

        if (opt.breakTicks === 'only_break' && brkAvailable) {
            scaleBreakHelper.addBreaksToTicks(ticks, brk.breaks, extent);
            return ticks;
        }

        if (__DEV__) {
            assert(niceExtent != null);
        }

        // [CAVEAT]: If changing this logic, must sync it to `axisAlignTicks.ts`.

        // A fail-safe is required since `interval` can be user specified, or for the case
        // that using dataZoom toolbox and zoom repeatedly.
        const safeLimit = 3000;

        if (extent[0] < niceExtent[0]) {
            ticks.push({
                value: opt.expandToNicedExtent
                    ? round(niceExtent[0] - interval, intervalPrecision)
                    : extent[0]
            });
        }

        const estimateNiceMultiple = (tickVal: number, targetTick: number) => {
            return mathRound((targetTick - tickVal) / interval);
        };

        const intervalCount = cfg.intervalCount;
        for (
            let tick = niceExtent[0], niceTickIdx = 0;
            ;
            niceTickIdx++
        ) {
            // Consider case `_extent: [5.2, 5.8], _niceExtent: [6, 5], interval: 1`,
            //  `_intervalCount` makes sense iff `-1`.
            // Consider case `_extent: [5, 5.8], _niceExtent: [5, 5], interval: 1`,
            //  `_intervalCount` makes sense iff `0`.
            if (intervalCount == null) {
                if (tick > niceExtent[1] || !isFinite(tick) || !isFinite(niceExtent[1])) {
                    break;
                }
            }
            else {
                if (niceTickIdx > intervalCount) { // nice ticks number should be `intervalCount + 1`
                    break;
                }
                // Consider cumulative error, especially caused by rounding, the last nice
                // `tick` may be less than or greater than `niceExtent[1]` slightly.
                tick = mathMin(tick, niceExtent[1]);
                if (niceTickIdx === intervalCount) {
                    tick = niceExtent[1];
                }
            }

            ticks.push({value: tick});

            // Avoid rounding error
            tick = round(tick + interval, intervalPrecision);

            if (brk) {
                const moreMultiple = brk.calcNiceTickMultiple(tick, estimateNiceMultiple);
                if (moreMultiple >= 0) {
                    tick = round(tick + moreMultiple * interval, intervalPrecision);
                }
            }

            if (ticks.length > 0 && tick === ticks[ticks.length - 1].value) {
                // Consider out of safe float point, e.g.,
                // -3711126.9907707 + 2e-10 === -3711126.9907707
                break;
            }
            if (ticks.length > safeLimit) {
                if (__DEV__) {
                    warn('Exceed safe limit in IntervalScale["getTicks"].');
                }
                return [];
            }
        }

        // Consider this case: the last item of ticks is smaller
        // than niceExtent[1] and niceExtent[1] === extent[1].
        const lastNiceTick = ticks.length ? ticks[ticks.length - 1].value : niceExtent[1];
        if (extent[1] > lastNiceTick) {
            ticks.push({
                value: opt.expandToNicedExtent
                    ? round(lastNiceTick + interval, intervalPrecision)
                    : extent[1]
            });
        }

        if (brkAvailable) {
            scaleBreakHelper.pruneTicksByBreak(
                opt.pruneByBreak,
                ticks,
                brk.breaks,
                item => item.value,
                cfg.interval,
                extent
            );
        }
        if (brkAvailable && opt.breakTicks !== 'none') {
            scaleBreakHelper.addBreaksToTicks(ticks, brk.breaks, extent);
        }

        return ticks;
    }

    getMinorTicks(splitNumber: number): number[][] {
        return getMinorTicks(
            this,
            splitNumber,
            getBreaksUnsafe(this),
            this._cfg.interval
        );
    }

    getLabel(
        tick: ScaleTick,
        opt?: IntervalScaleGetLabelOpt
    ): string {
        if (tick == null) {
            return '';
        }

        let precision = opt && opt.precision;

        if (precision == null) {
            precision = getPrecision(tick.value) || 0;
        }
        else if (precision === 'auto') {
            // Should be more precise then tick.
            precision = this._cfg.intervalPrecision;
        }

        // (1) If `precision` is set, 12.005 should be display as '12.00500'.
        // (2) Use `round` (toFixed) to avoid scientific notation like '3.5e-7'.
        const dataNum = round(tick.value, precision as number, true);

        return addCommas(dataNum);
    }

}

Scale.registerClass(IntervalScale);

export default IntervalScale;
