/*
* 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 SeriesModel from '../../model/Series';
import createDimensions from '../../data/helper/createDimensions';
import {getDimensionTypeByAxis} from '../../data/helper/dimensionHelper';
import List from '../../data/List';
import * as zrUtil from 'zrender/src/core/util';
import {groupData, SINGLE_REFERRING} from '../../util/model';
import LegendVisualProvider from '../../visual/LegendVisualProvider';
import {
    SeriesOption,
    SeriesOnSingleOptionMixin,
    OptionDataValueDate,
    OptionDataValueNumeric,
    ItemStyleOption,
    BoxLayoutOptionMixin,
    ZRColor,
    Dictionary,
    SeriesLabelOption
} from '../../util/types';
import SingleAxis from '../../coord/single/SingleAxis';
import GlobalModel from '../../model/Global';
import Single from '../../coord/single/Single';
import { createTooltipMarkup } from '../../component/tooltip/tooltipMarkup';

const DATA_NAME_INDEX = 2;

interface ThemeRiverSeriesLabelOption extends SeriesLabelOption {
    margin?: number
}

type ThemerRiverDataItem = [OptionDataValueDate, OptionDataValueNumeric, string];

export interface ThemeRiverStateOption {
    label?: ThemeRiverSeriesLabelOption
    itemStyle?: ItemStyleOption
}

export interface ThemeRiverSeriesOption extends SeriesOption<ThemeRiverStateOption>, ThemeRiverStateOption,
    SeriesOnSingleOptionMixin, BoxLayoutOptionMixin {
    type?: 'themeRiver'

    color?: ZRColor[]

    coordinateSystem?: 'singleAxis'

    /**
     * gap in axis's orthogonal orientation
     */
    boundaryGap?: (string | number)[]
    /**
     * [date, value, name]
     */
    data?: ThemerRiverDataItem[]
}

class ThemeRiverSeriesModel extends SeriesModel<ThemeRiverSeriesOption> {
    static readonly type = 'series.themeRiver';
    readonly type = ThemeRiverSeriesModel.type;

    static readonly dependencies = ['singleAxis'];

    nameMap: zrUtil.HashMap<number, string>;

    coordinateSystem: Single;

    /**
     * @override
     */
    init(option: ThemeRiverSeriesOption) {
        // eslint-disable-next-line
        super.init.apply(this, arguments as any);

        // Put this function here is for the sake of consistency of code style.
        // Enable legend selection for each data item
        // Use a function instead of direct access because data reference may changed
        this.legendVisualProvider = new LegendVisualProvider(
            zrUtil.bind(this.getData, this), zrUtil.bind(this.getRawData, this)
        );
    }

    /**
     * If there is no value of a certain point in the time for some event,set it value to 0.
     *
     * @param {Array} data  initial data in the option
     * @return {Array}
     */
    fixData(data: ThemeRiverSeriesOption['data']) {
        let rawDataLength = data.length;
        /**
         * Make sure every layer data get the same keys.
         * The value index tells which layer has visited.
         * {
         *  2014/01/01: -1
         * }
         */
        const timeValueKeys: Dictionary<number> = {};

        // grouped data by name
        const groupResult = groupData(data, (item: ThemerRiverDataItem) => {
            if (!timeValueKeys.hasOwnProperty(item[0] + '')) {
                timeValueKeys[item[0] + ''] = -1;
            }
            return item[2];
        });
        const layerData: {name: string, dataList: ThemerRiverDataItem[]}[] = [];
        groupResult.buckets.each(function (items, key) {
            layerData.push({
                name: key, dataList: items
            });
        });
        const layerNum = layerData.length;

        for (let k = 0; k < layerNum; ++k) {
            const name = layerData[k].name;
            for (let j = 0; j < layerData[k].dataList.length; ++j) {
                const timeValue = layerData[k].dataList[j][0] + '';
                timeValueKeys[timeValue] = k;
            }

            for (const timeValue in timeValueKeys) {
                if (timeValueKeys.hasOwnProperty(timeValue) && timeValueKeys[timeValue] !== k) {
                    timeValueKeys[timeValue] = k;
                    data[rawDataLength] = [timeValue, 0, name];
                    rawDataLength++;
                }
            }

        }
        return data;
    }

    /**
     * @override
     * @param  option  the initial option that user gived
     * @param  ecModel  the model object for themeRiver option
     */
    getInitialData(option: ThemeRiverSeriesOption, ecModel: GlobalModel): List {

        const singleAxisModel = this.getReferringComponents('singleAxis', SINGLE_REFERRING).models[0];

        const axisType = singleAxisModel.get('type');

        // filter the data item with the value of label is undefined
        const filterData = zrUtil.filter(option.data, function (dataItem) {
            return dataItem[2] !== undefined;
        });

        // ??? TODO design a stage to transfer data for themeRiver and lines?
        const data = this.fixData(filterData || []);
        const nameList = [];
        const nameMap = this.nameMap = zrUtil.createHashMap();
        let count = 0;

        for (let i = 0; i < data.length; ++i) {
            nameList.push(data[i][DATA_NAME_INDEX]);
            if (!nameMap.get(data[i][DATA_NAME_INDEX] as string)) {
                nameMap.set(data[i][DATA_NAME_INDEX] as string, count);
                count++;
            }
        }

        const dimensionsInfo = createDimensions(data, {
            coordDimensions: ['single'],
            dimensionsDefine: [
                {
                    name: 'time',
                    type: getDimensionTypeByAxis(axisType)
                },
                {
                    name: 'value',
                    type: 'float'
                },
                {
                    name: 'name',
                    type: 'ordinal'
                }
            ],
            encodeDefine: {
                single: 0,
                value: 1,
                itemName: 2
            }
        });

        const list = new List(dimensionsInfo, this);
        list.initData(data);

        return list;
    }

    /**
     * The raw data is divided into multiple layers and each layer
     *     has same name.
     */
    getLayerSeries() {
        const data = this.getData();
        const lenCount = data.count();
        const indexArr = [];

        for (let i = 0; i < lenCount; ++i) {
            indexArr[i] = i;
        }

        const timeDim = data.mapDimension('single');

        // data group by name
        const groupResult = groupData(indexArr, function (index) {
            return data.get('name', index) as string;
        });
        const layerSeries: {
            name: string
            indices: number[]
        }[] = [];
        groupResult.buckets.each(function (items: number[], key: string) {
            items.sort(function (index1: number, index2: number) {
                return data.get(timeDim, index1) as number - (data.get(timeDim, index2) as number);
            });
            layerSeries.push({
                name: key,
                indices: items
            });
        });

        return layerSeries;
    }

    /**
     * Get data indices for show tooltip content
     */
    getAxisTooltipData(dim: string | string[], value: number, baseAxis: SingleAxis) {
        if (!zrUtil.isArray(dim)) {
            dim = dim ? [dim] : [];
        }

        const data = this.getData();
        const layerSeries = this.getLayerSeries();
        const indices = [];
        const layerNum = layerSeries.length;
        let nestestValue;

        for (let i = 0; i < layerNum; ++i) {
            let minDist = Number.MAX_VALUE;
            let nearestIdx = -1;
            const pointNum = layerSeries[i].indices.length;
            for (let j = 0; j < pointNum; ++j) {
                const theValue = data.get(dim[0], layerSeries[i].indices[j]) as number;
                const dist = Math.abs(theValue - value);
                if (dist <= minDist) {
                    nestestValue = theValue;
                    minDist = dist;
                    nearestIdx = layerSeries[i].indices[j];
                }
            }
            indices.push(nearestIdx);
        }

        return {dataIndices: indices, nestestValue: nestestValue};
    }

    formatTooltip(
        dataIndex: number,
        multipleSeries: boolean,
        dataType: string
    ) {
        const data = this.getData();
        const name = data.getName(dataIndex);
        const value = data.get(data.mapDimension('value'), dataIndex);

        return createTooltipMarkup('nameValue', { name: name, value: value });
    }

    static defaultOption: ThemeRiverSeriesOption = {
        zlevel: 0,
        z: 2,

        colorBy: 'data',
        coordinateSystem: 'singleAxis',

        // gap in axis's orthogonal orientation
        boundaryGap: ['10%', '10%'],

        // legendHoverLink: true,

        singleAxisIndex: 0,

        animationEasing: 'linear',

        label: {
            margin: 4,
            show: true,
            position: 'left',
            fontSize: 11
        },

        emphasis: {

            label: {
                show: true
            }
        }
    };
}

export default ThemeRiverSeriesModel;