/*
* 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.
*/

/* global Uint32Array, Float64Array, Float32Array */

import SeriesModel from '../../model/Series';
import SeriesData from '../../data/SeriesData';
import { concatArray, mergeAll, map, isNumber } from 'zrender/src/core/util';
import CoordinateSystem from '../../core/CoordinateSystem';
import {
    SeriesOption,
    SeriesOnCartesianOptionMixin,
    SeriesOnGeoOptionMixin,
    SeriesOnPolarOptionMixin,
    SeriesOnCalendarOptionMixin,
    SeriesLargeOptionMixin,
    LineStyleOption,
    OptionDataValue,
    StatesOptionMixin,
    SeriesLineLabelOption,
    DimensionDefinitionLoose,
    DefaultStatesMixinEmphasis,
    ZRColor,
    CallbackDataParams
} from '../../util/types';
import GlobalModel from '../../model/Global';
import type { LineDrawModelOption } from '../helper/LineDraw';
import { createTooltipMarkup } from '../../component/tooltip/tooltipMarkup';

const Uint32Arr = typeof Uint32Array === 'undefined' ? Array : Uint32Array;
const Float64Arr = typeof Float64Array === 'undefined' ? Array : Float64Array;

function compatEc2(seriesOpt: LinesSeriesOption) {
    const data = seriesOpt.data;
    if (data && data[0] && (data as LegacyDataItemOption[][])[0][0] && (data as LegacyDataItemOption[][])[0][0].coord) {
        if (__DEV__) {
            console.warn('Lines data configuration has been changed to'
                + ' { coords:[[1,2],[2,3]] }');
        }
        seriesOpt.data = map(data as LegacyDataItemOption[][], function (itemOpt) {
            const coords = [
                itemOpt[0].coord, itemOpt[1].coord
            ];
            const target: LinesDataItemOption = {
                coords: coords
            };
            if (itemOpt[0].name) {
                target.fromName = itemOpt[0].name;
            }
            if (itemOpt[1].name) {
                target.toName = itemOpt[1].name;
            }
            return mergeAll([target, itemOpt[0], itemOpt[1]]);
        });
    }
}

type LinesCoords = number[][];

type LinesValue = OptionDataValue | OptionDataValue[];

interface LinesLineStyleOption<TClr> extends LineStyleOption<TClr> {
    curveness?: number
}

// @deprecated
interface LegacyDataItemOption {
    coord: number[]
    name: string
}

interface LinesStatesMixin {
    emphasis?: DefaultStatesMixinEmphasis
}
export interface LinesStateOption<TCbParams = never> {
    lineStyle?: LinesLineStyleOption<(TCbParams extends never ? never : (params: TCbParams) => ZRColor) | ZRColor>
    label?: SeriesLineLabelOption
}

export interface LinesDataItemOption extends LinesStateOption,
    StatesOptionMixin<LinesStateOption, LinesStatesMixin> {
    name?: string

    fromName?: string
    toName?: string

    symbol?: string[] | string
    symbolSize?: number[] | number

    coords?: LinesCoords

    value?: LinesValue

    effect?: LineDrawModelOption['effect']
}

export interface LinesSeriesOption
    extends SeriesOption<LinesStateOption, LinesStatesMixin>, LinesStateOption<CallbackDataParams>,
    SeriesOnCartesianOptionMixin, SeriesOnGeoOptionMixin, SeriesOnPolarOptionMixin,
    SeriesOnCalendarOptionMixin, SeriesLargeOptionMixin {

    type?: 'lines'

    coordinateSystem?: string

    symbol?: string[] | string
    symbolSize?: number[] | number

    effect?: LineDrawModelOption['effect']

    /**
     * If lines are polyline
     * polyline not support curveness, label, animation
     */
    polyline?: boolean
    /**
     * If clip the overflow.
     * Available when coordinateSystem is cartesian or polar.
     */
    clip?: boolean

    data?: LinesDataItemOption[]
        // Stored as a flat array. In format
        // Points Count(2) | x | y | x | y | Points Count(3) | x |  y | x | y | x | y |
        | ArrayLike<number>

    dimensions?: DimensionDefinitionLoose | DimensionDefinitionLoose[]
}

class LinesSeriesModel extends SeriesModel<LinesSeriesOption> {

    static readonly type = 'series.lines';
    readonly type = LinesSeriesModel.type;

    static readonly dependencies = ['grid', 'polar', 'geo', 'calendar'];

    visualStyleAccessPath = 'lineStyle';
    visualDrawType = 'stroke' as const;

    private _flatCoords: ArrayLike<number>;
    private _flatCoordsOffset: ArrayLike<number>;

    init(option: LinesSeriesOption) {
        // The input data may be null/undefined.
        option.data = option.data || [];

        // Not using preprocessor because mergeOption may not have series.type
        compatEc2(option);

        const result = this._processFlatCoordsArray(option.data);
        this._flatCoords = result.flatCoords;
        this._flatCoordsOffset = result.flatCoordsOffset;
        if (result.flatCoords) {
            option.data = new Float32Array(result.count);
        }

        super.init.apply(this, arguments as any);
    }

    mergeOption(option: LinesSeriesOption) {
        compatEc2(option);

        if (option.data) {
            // Only update when have option data to merge.
            const result = this._processFlatCoordsArray(option.data);
            this._flatCoords = result.flatCoords;
            this._flatCoordsOffset = result.flatCoordsOffset;
            if (result.flatCoords) {
                option.data = new Float32Array(result.count);
            }
        }

        super.mergeOption.apply(this, arguments as any);
    }

    appendData(params: Pick<LinesSeriesOption, 'data'>) {
        const result = this._processFlatCoordsArray(params.data);
        if (result.flatCoords) {
            if (!this._flatCoords) {
                this._flatCoords = result.flatCoords;
                this._flatCoordsOffset = result.flatCoordsOffset;
            }
            else {
                this._flatCoords = concatArray(this._flatCoords, result.flatCoords);
                this._flatCoordsOffset = concatArray(this._flatCoordsOffset, result.flatCoordsOffset);
            }
            params.data = new Float32Array(result.count);
        }

        this.getRawData().appendData(params.data);
    }

    _getCoordsFromItemModel(idx: number) {
        const itemModel = this.getData().getItemModel<LinesDataItemOption>(idx);
        const coords = (itemModel.option instanceof Array)
            ? itemModel.option : itemModel.getShallow('coords');

        if (__DEV__) {
            if (!(coords instanceof Array && coords.length > 0 && coords[0] instanceof Array)) {
                throw new Error(
                    'Invalid coords ' + JSON.stringify(coords) + '. Lines must have 2d coords array in data item.'
                );
            }
        }
        return coords;
    }

    getLineCoordsCount(idx: number) {
        if (this._flatCoordsOffset) {
            return this._flatCoordsOffset[idx * 2 + 1];
        }
        else {
            return this._getCoordsFromItemModel(idx).length;
        }
    }

    getLineCoords(idx: number, out: number[][]) {
        if (this._flatCoordsOffset) {
            const offset = this._flatCoordsOffset[idx * 2];
            const len = this._flatCoordsOffset[idx * 2 + 1];
            for (let i = 0; i < len; i++) {
                out[i] = out[i] || [];
                out[i][0] = this._flatCoords[offset + i * 2];
                out[i][1] = this._flatCoords[offset + i * 2 + 1];
            }
            return len;
        }
        else {
            const coords = this._getCoordsFromItemModel(idx);
            for (let i = 0; i < coords.length; i++) {
                out[i] = out[i] || [];
                out[i][0] = coords[i][0];
                out[i][1] = coords[i][1];
            }
            return coords.length;
        }
    }

    _processFlatCoordsArray(data: LinesSeriesOption['data']) {
        let startOffset = 0;
        if (this._flatCoords) {
            startOffset = this._flatCoords.length;
        }
        // Stored as a typed array. In format
        // Points Count(2) | x | y | x | y | Points Count(3) | x |  y | x | y | x | y |
        if (isNumber(data[0])) {
            const len = data.length;
            // Store offset and len of each segment
            const coordsOffsetAndLenStorage = new Uint32Arr(len) as Uint32Array;
            const coordsStorage = new Float64Arr(len) as Float64Array;
            let coordsCursor = 0;
            let offsetCursor = 0;
            let dataCount = 0;
            for (let i = 0; i < len;) {
                dataCount++;
                const count = data[i++] as number;
                // Offset
                coordsOffsetAndLenStorage[offsetCursor++] = coordsCursor + startOffset;
                // Len
                coordsOffsetAndLenStorage[offsetCursor++] = count;
                for (let k = 0; k < count; k++) {
                    const x = data[i++] as number;
                    const y = data[i++] as number;
                    coordsStorage[coordsCursor++] = x;
                    coordsStorage[coordsCursor++] = y;

                    if (i > len) {
                        if (__DEV__) {
                            throw new Error('Invalid data format.');
                        }
                    }
                }
            }

            return {
                flatCoordsOffset: new Uint32Array(coordsOffsetAndLenStorage.buffer, 0, offsetCursor),
                flatCoords: coordsStorage,
                count: dataCount
            };
        }

        return {
            flatCoordsOffset: null,
            flatCoords: null,
            count: data.length
        };
    }

    getInitialData(option: LinesSeriesOption, ecModel: GlobalModel) {
        if (__DEV__) {
            const CoordSys = CoordinateSystem.get(option.coordinateSystem);
            if (!CoordSys) {
                throw new Error('Unknown coordinate system ' + option.coordinateSystem);
            }
        }

        const lineData = new SeriesData(['value'], this);
        lineData.hasItemOption = false;

        lineData.initData(option.data, [], function (dataItem, dimName, dataIndex, dimIndex) {
            // dataItem is simply coords
            if (dataItem instanceof Array) {
                return NaN;
            }
            else {
                lineData.hasItemOption = true;
                const value = dataItem.value;
                if (value != null) {
                    return value instanceof Array ? value[dimIndex] : value;
                }
            }
        });

        return lineData;
    }

    formatTooltip(
        dataIndex: number,
        multipleSeries: boolean,
        dataType: string
    ) {
        const data = this.getData();
        const itemModel = data.getItemModel<LinesDataItemOption>(dataIndex);
        const name = itemModel.get('name');
        if (name) {
            return name;
        }
        const fromName = itemModel.get('fromName');
        const toName = itemModel.get('toName');
        const nameArr = [];
        fromName != null && nameArr.push(fromName);
        toName != null && nameArr.push(toName);

        return createTooltipMarkup('nameValue', {
            name: nameArr.join(' > ')
        });
    }

    preventIncremental() {
        return !!this.get(['effect', 'show']);
    }

    getProgressive() {
        const progressive = this.option.progressive;
        if (progressive == null) {
            return this.option.large ? 1e4 : this.get('progressive');
        }
        return progressive;
    }

    getProgressiveThreshold() {
        const progressiveThreshold = this.option.progressiveThreshold;
        if (progressiveThreshold == null) {
            return this.option.large ? 2e4 : this.get('progressiveThreshold');
        }
        return progressiveThreshold;
    }

    getZLevelKey() {
        const effectModel = this.getModel('effect');
        const trailLength = effectModel.get('trailLength');
        return this.getData().count() > this.getProgressiveThreshold()
            // Each progressive series has individual key.
            ? this.id
            : (effectModel.get('show') && trailLength > 0 ? trailLength + '' : '');
    }

    static defaultOption: LinesSeriesOption = {
        coordinateSystem: 'geo',
        // zlevel: 0,
        z: 2,
        legendHoverLink: true,

        // Cartesian coordinate system
        xAxisIndex: 0,
        yAxisIndex: 0,

        symbol: ['none', 'none'],
        symbolSize: [10, 10],
        // Geo coordinate system
        geoIndex: 0,

        effect: {
            show: false,
            period: 4,
            constantSpeed: 0,
            symbol: 'circle',
            symbolSize: 3,
            loop: true,
            trailLength: 0.2
        },

        large: false,
        // Available when large is true
        largeThreshold: 2000,

        polyline: false,

        clip: true,

        label: {
            show: false,
            position: 'end'
            // distance: 5,
            // formatter: 标签文本格式器，同Tooltip.formatter，不支持异步回调
        },

        lineStyle: {
            opacity: 0.5
        }
    };
}

export default LinesSeriesModel;
