/*
* 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 {
    each,
    isObject,
    isArray,
    createHashMap,
    HashMap,
    map,
    assert,
    isString,
    indexOf,
    isStringSafe
} from 'zrender/src/core/util';
import env from 'zrender/src/core/env';
import GlobalModel from '../model/Global';
import ComponentModel, {ComponentModelConstructor} from '../model/Component';
import List from '../data/List';
import {
    ComponentOption,
    ComponentMainType,
    ComponentSubType,
    DisplayStateHostOption,
    OptionDataItem,
    OptionDataValue,
    TooltipRenderMode,
    Payload,
    OptionId,
    OptionName,
    ParsedValue
} from './types';
import { Dictionary } from 'zrender/src/core/types';
import SeriesModel from '../model/Series';
import CartesianAxisModel from '../coord/cartesian/AxisModel';
import GridModel from '../coord/cartesian/GridModel';
import { isNumeric, getRandomIdBase, getPrecisionSafe, round } from './number';
import { interpolateNumber } from 'zrender/src/animation/Animator';
import { warn } from './log';

/**
 * Make the name displayable. But we should
 * make sure it is not duplicated with user
 * specified name, so use '\0';
 */
const DUMMY_COMPONENT_NAME_PREFIX = 'series\0';

const INTERNAL_COMPONENT_ID_PREFIX = '\0_ec_\0';

/**
 * If value is not array, then translate it to array.
 * @param  {*} value
 * @return {Array} [value] or value
 */
export function normalizeToArray<T>(value?: T | T[]): T[] {
    return value instanceof Array
        ? value
        : value == null
        ? []
        : [value];
}

/**
 * Sync default option between normal and emphasis like `position` and `show`
 * In case some one will write code like
 *     label: {
 *          show: false,
 *          position: 'outside',
 *          fontSize: 18
 *     },
 *     emphasis: {
 *          label: { show: true }
 *     }
 */
export function defaultEmphasis(
    opt: DisplayStateHostOption,
    key: string,
    subOpts: string[]
): void {
    // Caution: performance sensitive.
    if (opt) {
        opt[key] = opt[key] || {};
        opt.emphasis = opt.emphasis || {};
        opt.emphasis[key] = opt.emphasis[key] || {};

        // Default emphasis option from normal
        for (let i = 0, len = subOpts.length; i < len; i++) {
            const subOptName = subOpts[i];
            if (!opt.emphasis[key].hasOwnProperty(subOptName)
                && opt[key].hasOwnProperty(subOptName)
            ) {
                opt.emphasis[key][subOptName] = opt[key][subOptName];
            }
        }
    }
}

export const TEXT_STYLE_OPTIONS = [
    'fontStyle', 'fontWeight', 'fontSize', 'fontFamily',
    'rich', 'tag', 'color', 'textBorderColor', 'textBorderWidth',
    'width', 'height', 'lineHeight', 'align', 'verticalAlign', 'baseline',
    'shadowColor', 'shadowBlur', 'shadowOffsetX', 'shadowOffsetY',
    'textShadowColor', 'textShadowBlur', 'textShadowOffsetX', 'textShadowOffsetY',
    'backgroundColor', 'borderColor', 'borderWidth', 'borderRadius', 'padding'
] as const;

// modelUtil.LABEL_OPTIONS = modelUtil.TEXT_STYLE_OPTIONS.concat([
//     'position', 'offset', 'rotate', 'origin', 'show', 'distance', 'formatter',
//     'fontStyle', 'fontWeight', 'fontSize', 'fontFamily',
//     // FIXME: deprecated, check and remove it.
//     'textStyle'
// ]);

/**
 * The method do not ensure performance.
 * data could be [12, 2323, {value: 223}, [1221, 23], {value: [2, 23]}]
 * This helper method retieves value from data.
 */
export function getDataItemValue(
    dataItem: OptionDataItem
): OptionDataValue | OptionDataValue[] {
    return (isObject(dataItem) && !isArray(dataItem) && !(dataItem instanceof Date))
        ? (dataItem as Dictionary<OptionDataValue>).value : dataItem;
}

/**
 * data could be [12, 2323, {value: 223}, [1221, 23], {value: [2, 23]}]
 * This helper method determine if dataItem has extra option besides value
 */
export function isDataItemOption(dataItem: OptionDataItem): boolean {
    return isObject(dataItem)
        && !(dataItem instanceof Array);
        // // markLine data can be array
        // && !(dataItem[0] && isObject(dataItem[0]) && !(dataItem[0] instanceof Array));
}

// Compatible with previous definition: id could be number (but not recommanded).
// number and string are trade the same when compare.
// number id will not be converted to string in option.
// number id will be converted to string in component instance id.
export interface MappingExistingItem {
    id?: OptionId;
    name?: string;
};
/**
 * The array `MappingResult<T>[]` exactly represents the content of the result
 * components array after merge.
 * The indices are the same as the `existings`.
 * Items will not be `null`/`undefined` even if the corresponding `existings` will be removed.
 */
type MappingResult<T> = MappingResultItem<T>[];
interface MappingResultItem<T extends MappingExistingItem = MappingExistingItem> {
    // Existing component instance.
    existing: T;
    // The mapped new component option.
    newOption: ComponentOption;
    // Mark that the new component has nothing to do with any of the old components.
    // So they won't share view. Also see `__requireNewView`.
    brandNew: boolean;
    // keyInfo for new component.
    // All of them will be assigned to a created component instance.
    keyInfo: {
        name: string,
        id: string,
        mainType: ComponentMainType,
        subType: ComponentSubType
    };
}

type MappingToExistsMode = 'normalMerge' | 'replaceMerge' | 'replaceAll';

/**
 * Mapping to existings for merge.
 *
 * Mode "normalMege":
 *     The mapping result (merge result) will keep the order of the existing
 *     component, rather than the order of new option. Because we should ensure
 *     some specified index reference (like xAxisIndex) keep work.
 *     And in most cases, "merge option" is used to update partial option but not
 *     be expected to change the order.
 *
 * Mode "replaceMege":
 *     (1) Only the id mapped components will be merged.
 *     (2) Other existing components (except internal compoonets) will be removed.
 *     (3) Other new options will be used to create new component.
 *     (4) The index of the existing compoents will not be modified.
 *     That means their might be "hole" after the removal.
 *     The new components are created first at those available index.
 *
 * Mode "replaceAll":
 *     This mode try to support that reproduce an echarts instance from another
 *     echarts instance (via `getOption`) in some simple cases.
 *     In this senario, the `result` index are exactly the consistent with the `newCmptOptions`,
 *     which ensures the compoennt index referring (like `xAxisIndex: ?`) corrent. That is,
 *     the "hole" in `newCmptOptions` will also be kept.
 *     On the contrary, other modes try best to eliminate holes.
 *     PENDING: This is an experimental mode yet.
 *
 * @return See the comment of <MappingResult>.
 */
export function mappingToExists<T extends MappingExistingItem>(
    existings: T[],
    newCmptOptions: ComponentOption[],
    mode: MappingToExistsMode
): MappingResult<T> {

    const isNormalMergeMode = mode === 'normalMerge';
    const isReplaceMergeMode = mode === 'replaceMerge';
    const isReplaceAllMode = mode === 'replaceAll';
    existings = existings || [];
    newCmptOptions = (newCmptOptions || []).slice();
    const existingIdIdxMap = createHashMap<number>();

    // Validate id and name on user input option.
    each(newCmptOptions, function (cmptOption, index) {
        if (!isObject<ComponentOption>(cmptOption)) {
            newCmptOptions[index] = null;
            return;
        }

        if (__DEV__) {
            // There is some legacy case that name is set as `false`.
            // But should work normally rather than throw error.
            if (cmptOption.id != null && !isValidIdOrName(cmptOption.id)) {
                warnInvalidateIdOrName(cmptOption.id);
            }
            if (cmptOption.name != null && !isValidIdOrName(cmptOption.name)) {
                warnInvalidateIdOrName(cmptOption.name);
            }
        }
    });

    const result = prepareResult(existings, existingIdIdxMap, mode);

    if (isNormalMergeMode || isReplaceMergeMode) {
        mappingById(result, existings, existingIdIdxMap, newCmptOptions);
    }

    if (isNormalMergeMode) {
        mappingByName(result, newCmptOptions);
    }

    if (isNormalMergeMode || isReplaceMergeMode) {
        mappingByIndex(result, newCmptOptions, isReplaceMergeMode);
    }
    else if (isReplaceAllMode) {
        mappingInReplaceAllMode(result, newCmptOptions);
    }

    makeIdAndName(result);

    // The array `result` MUST NOT contain elided items, otherwise the
    // forEach will ommit those items and result in incorrect result.
    return result;
}

function prepareResult<T extends MappingExistingItem>(
    existings: T[],
    existingIdIdxMap: HashMap<number>,
    mode: MappingToExistsMode
): MappingResultItem<T>[] {
    const result: MappingResultItem<T>[] = [];

    if (mode === 'replaceAll') {
        return result;
    }

    // Do not use native `map` to in case that the array `existings`
    // contains elided items, which will be ommited.
    for (let index = 0; index < existings.length; index++) {
        const existing = existings[index];
        // Because of replaceMerge, `existing` may be null/undefined.
        if (existing && existing.id != null) {
            existingIdIdxMap.set(existing.id, index);
        }
        // For non-internal-componnets:
        //     Mode "normalMerge": all existings kept.
        //     Mode "replaceMerge": all existing removed unless mapped by id.
        // For internal-components:
        //     go with "replaceMerge" approach in both mode.
        result.push({
            existing: (mode === 'replaceMerge' || isComponentIdInternal(existing))
                ? null
                : existing,
            newOption: null,
            keyInfo: null,
            brandNew: null
        });
    }
    return result;
}

function mappingById<T extends MappingExistingItem>(
    result: MappingResult<T>,
    existings: T[],
    existingIdIdxMap: HashMap<number>,
    newCmptOptions: ComponentOption[]
): void {
    // Mapping by id if specified.
    each(newCmptOptions, function (cmptOption, index) {
        if (!cmptOption || cmptOption.id == null) {
            return;
        }
        const optionId = makeComparableKey(cmptOption.id);
        const existingIdx = existingIdIdxMap.get(optionId);
        if (existingIdx != null) {
            const resultItem = result[existingIdx];
            assert(
                !resultItem.newOption,
                'Duplicated option on id "' + optionId + '".'
            );
            resultItem.newOption = cmptOption;
            // In both mode, if id matched, new option will be merged to
            // the existings rather than creating new component model.
            resultItem.existing = existings[existingIdx];
            newCmptOptions[index] = null;
        }
    });
}

function mappingByName<T extends MappingExistingItem>(
    result: MappingResult<T>,
    newCmptOptions: ComponentOption[]
): void {
    // Mapping by name if specified.
    each(newCmptOptions, function (cmptOption, index) {
        if (!cmptOption || cmptOption.name == null) {
            return;
        }
        for (let i = 0; i < result.length; i++) {
            const existing = result[i].existing;
            if (!result[i].newOption // Consider name: two map to one.
                // Can not match when both ids existing but different.
                && existing
                && (existing.id == null || cmptOption.id == null)
                && !isComponentIdInternal(cmptOption)
                && !isComponentIdInternal(existing)
                && keyExistAndEqual('name', existing, cmptOption)
            ) {
                result[i].newOption = cmptOption;
                newCmptOptions[index] = null;
                return;
            }
        }
    });
}

function mappingByIndex<T extends MappingExistingItem>(
    result: MappingResult<T>,
    newCmptOptions: ComponentOption[],
    brandNew: boolean
): void {
    each(newCmptOptions, function (cmptOption) {
        if (!cmptOption) {
            return;
        }

        // Find the first place that not mapped by id and not internal component (consider the "hole").
        let resultItem;
        let nextIdx = 0;
        while (
            // Be `!resultItem` only when `nextIdx >= result.length`.
            (resultItem = result[nextIdx])
            // (1) Existing models that already have id should be able to mapped to. Because
            // after mapping performed, model will always be assigned with an id if user not given.
            // After that all models have id.
            // (2) If new option has id, it can only set to a hole or append to the last. It should
            // not be merged to the existings with different id. Because id should not be overwritten.
            // (3) Name can be overwritten, because axis use name as 'show label text'.
            && (
                resultItem.newOption
                || isComponentIdInternal(resultItem.existing)
                || (
                    // In mode "replaceMerge", here no not-mapped-non-internal-existing.
                    resultItem.existing
                    && cmptOption.id != null
                    && !keyExistAndEqual('id', cmptOption, resultItem.existing)
                )
            )
        ) {
            nextIdx++;
        }

        if (resultItem) {
            resultItem.newOption = cmptOption;
            resultItem.brandNew = brandNew;
        }
        else {
            result.push({
                newOption: cmptOption,
                brandNew: brandNew,
                existing: null,
                keyInfo: null
            });
        }
        nextIdx++;
    });
}

function mappingInReplaceAllMode<T extends MappingExistingItem>(
    result: MappingResult<T>,
    newCmptOptions: ComponentOption[]
): void {
    each(newCmptOptions, function (cmptOption) {
        // The feature "reproduce" requires "hole" will also reproduced
        // in case that compoennt index referring are broken.
        result.push({
            newOption: cmptOption,
            brandNew: true,
            existing: null,
            keyInfo: null
        });
    });
}

/**
 * Make id and name for mapping result (result of mappingToExists)
 * into `keyInfo` field.
 */
function makeIdAndName(
    mapResult: MappingResult<MappingExistingItem>
): void {
    // We use this id to hash component models and view instances
    // in echarts. id can be specified by user, or auto generated.

    // The id generation rule ensures new view instance are able
    // to mapped to old instance when setOption are called in
    // no-merge mode. So we generate model id by name and plus
    // type in view id.

    // name can be duplicated among components, which is convenient
    // to specify multi components (like series) by one name.

    // Ensure that each id is distinct.
    const idMap = createHashMap();

    each(mapResult, function (item) {
        const existing = item.existing;
        existing && idMap.set(existing.id, item);
    });

    each(mapResult, function (item) {
        const opt = item.newOption;

        // Force ensure id not duplicated.
        assert(
            !opt || opt.id == null || !idMap.get(opt.id) || idMap.get(opt.id) === item,
            'id duplicates: ' + (opt && opt.id)
        );

        opt && opt.id != null && idMap.set(opt.id, item);
        !item.keyInfo && (item.keyInfo = {} as MappingResultItem['keyInfo']);
    });

    // Make name and id.
    each(mapResult, function (item, index) {
        const existing = item.existing;
        const opt = item.newOption;
        const keyInfo = item.keyInfo;

        if (!isObject<ComponentOption>(opt)) {
            return;
        }

        // name can be overwitten. Consider case: axis.name = '20km'.
        // But id generated by name will not be changed, which affect
        // only in that case: setOption with 'not merge mode' and view
        // instance will be recreated, which can be accepted.
        keyInfo.name = opt.name != null
            ? makeComparableKey(opt.name)
            : existing
            ? existing.name
            // Avoid diffferent series has the same name,
            // because name may be used like in color pallet.
            : DUMMY_COMPONENT_NAME_PREFIX + index;

        if (existing) {
            keyInfo.id = makeComparableKey(existing.id);
        }
        else if (opt.id != null) {
            keyInfo.id = makeComparableKey(opt.id);
        }
        else {
            // Consider this situatoin:
            //  optionA: [{name: 'a'}, {name: 'a'}, {..}]
            //  optionB [{..}, {name: 'a'}, {name: 'a'}]
            // Series with the same name between optionA and optionB
            // should be mapped.
            let idNum = 0;
            do {
                keyInfo.id = '\0' + keyInfo.name + '\0' + idNum++;
            }
            while (idMap.get(keyInfo.id));
        }

        idMap.set(keyInfo.id, item);
    });
}

function keyExistAndEqual(
    attr: 'id' | 'name',
    obj1: { id?: OptionId, name?: OptionName },
    obj2: { id?: OptionId, name?: OptionName }
): boolean {
    const key1 = convertOptionIdName(obj1[attr], null);
    const key2 = convertOptionIdName(obj2[attr], null);
    // See `MappingExistingItem`. `id` and `name` trade string equals to number.
    return key1 != null && key2 != null && key1 === key2;
}

/**
 * @return return null if not exist.
 */
function makeComparableKey(val: unknown): string {
    if (__DEV__) {
        if (val == null) {
            throw new Error();
        }
    }
    return convertOptionIdName(val, '');
}

export function convertOptionIdName(idOrName: unknown, defaultValue: string): string {
    if (idOrName == null) {
        return defaultValue;
    }
    const type = typeof idOrName;
    return type === 'string'
        ? idOrName as string
        : (type === 'number' || isStringSafe(idOrName))
        ? idOrName + ''
        : defaultValue;
}

function warnInvalidateIdOrName(idOrName: unknown) {
    if (__DEV__) {
        warn('`' + idOrName + '` is invalid id or name. Must be a string or number.');
    }
}

function isValidIdOrName(idOrName: unknown): boolean {
    return isStringSafe(idOrName) || isNumeric(idOrName);
}

export function isNameSpecified(componentModel: ComponentModel): boolean {
    const name = componentModel.name;
    // Is specified when `indexOf` get -1 or > 0.
    return !!(name && name.indexOf(DUMMY_COMPONENT_NAME_PREFIX));
}

/**
 * @public
 * @param {Object} cmptOption
 * @return {boolean}
 */
export function isComponentIdInternal(cmptOption: { id?: MappingExistingItem['id'] }): boolean {
    return cmptOption
        && cmptOption.id != null
        && makeComparableKey(cmptOption.id).indexOf(INTERNAL_COMPONENT_ID_PREFIX) === 0;
}

export function makeInternalComponentId(idSuffix: string) {
    return INTERNAL_COMPONENT_ID_PREFIX + idSuffix;
}

export function setComponentTypeToKeyInfo(
    mappingResult: MappingResult<MappingExistingItem & { subType?: ComponentSubType }>,
    mainType: ComponentMainType,
    componentModelCtor: ComponentModelConstructor
): void {
    // Set mainType and complete subType.
    each(mappingResult, function (item) {
        const newOption = item.newOption;
        if (isObject(newOption)) {
            item.keyInfo.mainType = mainType;
            item.keyInfo.subType = determineSubType(mainType, newOption, item.existing, componentModelCtor);
        }
    });
}

function determineSubType(
    mainType: ComponentMainType,
    newCmptOption: ComponentOption,
    existComponent: { subType?: ComponentSubType },
    componentModelCtor: ComponentModelConstructor
): ComponentSubType {
    const subType = newCmptOption.type
        ? newCmptOption.type
        : existComponent
        ? existComponent.subType
        // Use determineSubType only when there is no existComponent.
        : (componentModelCtor as ComponentModelConstructor).determineSubType(mainType, newCmptOption);

    // tooltip, markline, markpoint may always has no subType
    return subType;
}


type BatchItem = {
    seriesId: OptionId,
    dataIndex: number | number[]
};
/**
 * A helper for removing duplicate items between batchA and batchB,
 * and in themselves, and categorize by series.
 *
 * @param batchA Like: [{seriesId: 2, dataIndex: [32, 4, 5]}, ...]
 * @param batchB Like: [{seriesId: 2, dataIndex: [32, 4, 5]}, ...]
 * @return result: [resultBatchA, resultBatchB]
 */
export function compressBatches(
    batchA: BatchItem[],
    batchB: BatchItem[]
): [BatchItem[], BatchItem[]] {

    type InnerMap = {
        [seriesId: string]: {
            [dataIndex: string]: 1
        }
    };
    const mapA = {} as InnerMap;
    const mapB = {} as InnerMap;

    makeMap(batchA || [], mapA);
    makeMap(batchB || [], mapB, mapA);

    return [mapToArray(mapA), mapToArray(mapB)];

    function makeMap(sourceBatch: BatchItem[], map: InnerMap, otherMap?: InnerMap): void {
        for (let i = 0, len = sourceBatch.length; i < len; i++) {
            const seriesId = convertOptionIdName(sourceBatch[i].seriesId, null);
            if (seriesId == null) {
                return;
            }
            const dataIndices = normalizeToArray(sourceBatch[i].dataIndex);
            const otherDataIndices = otherMap && otherMap[seriesId];

            for (let j = 0, lenj = dataIndices.length; j < lenj; j++) {
                const dataIndex = dataIndices[j];

                if (otherDataIndices && otherDataIndices[dataIndex]) {
                    otherDataIndices[dataIndex] = null;
                }
                else {
                    (map[seriesId] || (map[seriesId] = {}))[dataIndex] = 1;
                }
            }
        }
    }

    function mapToArray(map: Dictionary<any>, isData?: boolean): any[] {
        const result = [];
        for (const i in map) {
            if (map.hasOwnProperty(i) && map[i] != null) {
                if (isData) {
                    result.push(+i);
                }
                else {
                    const dataIndices = mapToArray(map[i], true);
                    dataIndices.length && result.push({seriesId: i, dataIndex: dataIndices});
                }
            }
        }
        return result;
    }
}

/**
 * @param payload Contains dataIndex (means rawIndex) / dataIndexInside / name
 *                         each of which can be Array or primary type.
 * @return dataIndex If not found, return undefined/null.
 */
export function queryDataIndex(data: List, payload: Payload & {
    dataIndexInside?: number | number[]
    dataIndex?: number | number[]
    name?: string | string[]
}): number | number[] {
    if (payload.dataIndexInside != null) {
        return payload.dataIndexInside;
    }
    else if (payload.dataIndex != null) {
        return isArray(payload.dataIndex)
            ? map(payload.dataIndex, function (value) {
                return data.indexOfRawIndex(value);
            })
            : data.indexOfRawIndex(payload.dataIndex);
    }
    else if (payload.name != null) {
        return isArray(payload.name)
            ? map(payload.name, function (value) {
                return data.indexOfName(value);
            })
            : data.indexOfName(payload.name);
    }
}

/**
 * Enable property storage to any host object.
 * Notice: Serialization is not supported.
 *
 * For example:
 * let inner = zrUitl.makeInner();
 *
 * function some1(hostObj) {
 *      inner(hostObj).someProperty = 1212;
 *      ...
 * }
 * function some2() {
 *      let fields = inner(this);
 *      fields.someProperty1 = 1212;
 *      fields.someProperty2 = 'xx';
 *      ...
 * }
 *
 * @return {Function}
 */
export function makeInner<T, Host extends object>() {
    const key = '__ec_inner_' + innerUniqueIndex++;
    return function (hostObj: Host): T {
        return (hostObj as any)[key] || ((hostObj as any)[key] = {});
    };
}
let innerUniqueIndex = getRandomIdBase();

/**
 * If string, e.g., 'geo', means {geoIndex: 0}.
 * If Object, could contain some of these properties below:
 * {
 *     seriesIndex, seriesId, seriesName,
 *     geoIndex, geoId, geoName,
 *     bmapIndex, bmapId, bmapName,
 *     xAxisIndex, xAxisId, xAxisName,
 *     yAxisIndex, yAxisId, yAxisName,
 *     gridIndex, gridId, gridName,
 *     ... (can be extended)
 * }
 * Each properties can be number|string|Array.<number>|Array.<string>
 * For example, a finder could be
 * {
 *     seriesIndex: 3,
 *     geoId: ['aa', 'cc'],
 *     gridName: ['xx', 'rr']
 * }
 * xxxIndex can be set as 'all' (means all xxx) or 'none' (means not specify)
 * If nothing or null/undefined specified, return nothing.
 * If both `abcIndex`, `abcId`, `abcName` specified, only one work.
 * The priority is: index > id > name, the same with `ecModel.queryComponents`.
 */
export type ModelFinderIndexQuery = number | number[] | 'all' | 'none' | false;
export type ModelFinderIdQuery = OptionId | OptionId[];
export type ModelFinderNameQuery = OptionId | OptionId[];
// If string, like 'series', means { seriesIndex: 0 }.
export type ModelFinder = string | ModelFinderObject;
export type ModelFinderObject = {
    seriesIndex?: ModelFinderIndexQuery, seriesId?: ModelFinderIdQuery, seriesName?: ModelFinderNameQuery
    geoIndex?: ModelFinderIndexQuery, geoId?: ModelFinderIdQuery, geoName?: ModelFinderNameQuery
    bmapIndex?: ModelFinderIndexQuery, bmapId?: ModelFinderIdQuery, bmapName?: ModelFinderNameQuery
    xAxisIndex?: ModelFinderIndexQuery, xAxisId?: ModelFinderIdQuery, xAxisName?: ModelFinderNameQuery
    yAxisIndex?: ModelFinderIndexQuery, yAxisId?: ModelFinderIdQuery, yAxisName?: ModelFinderNameQuery
    gridIndex?: ModelFinderIndexQuery, gridId?: ModelFinderIdQuery, gridName?: ModelFinderNameQuery
       // ... (can be extended)
    [key: string]: unknown
};
/**
 * {
 *     seriesModels: [seriesModel1, seriesModel2],
 *     seriesModel: seriesModel1, // The first model
 *     geoModels: [geoModel1, geoModel2],
 *     geoModel: geoModel1, // The first model
 *     ...
 * }
 */
export type ParsedModelFinder = {
    // other components
    [key: string]: ComponentModel | ComponentModel[] | undefined;
};

export type ParsedModelFinderKnown = ParsedModelFinder & {
    seriesModels?: SeriesModel[];
    seriesModel?: SeriesModel;
    xAxisModels?: CartesianAxisModel[];
    xAxisModel?: CartesianAxisModel;
    yAxisModels?: CartesianAxisModel[];
    yAxisModel?: CartesianAxisModel;
    gridModels?: GridModel[];
    gridModel?: GridModel;
    dataIndex?: number;
    dataIndexInside?: number;
};

/**
 * The same behavior as `component.getReferringComponents`.
 */
export function parseFinder(
    ecModel: GlobalModel,
    finderInput: ModelFinder,
    opt?: {
        // If no main type specified, use this main type.
        defaultMainType?: ComponentMainType;
        // If pervided, types out of this list will be ignored.
        includeMainTypes?: ComponentMainType[];
        enableAll?: boolean;
        enableNone?: boolean;
    }
): ParsedModelFinder {
    let finder: ModelFinderObject;
    if (isString(finderInput)) {
        const obj = {};
        (obj as any)[finderInput + 'Index'] = 0;
        finder = obj;
    }
    else {
        finder = finderInput;
    }

    const queryOptionMap = createHashMap<QueryReferringUserOption, ComponentMainType>();
    const result = {} as ParsedModelFinderKnown;
    let mainTypeSpecified = false;

    each(finder, function (value, key) {
        // Exclude 'dataIndex' and other illgal keys.
        if (key === 'dataIndex' || key === 'dataIndexInside') {
            result[key] = value as number;
            return;
        }

        const parsedKey = key.match(/^(\w+)(Index|Id|Name)$/) || [];
        const mainType = parsedKey[1];
        const queryType = (parsedKey[2] || '').toLowerCase() as keyof QueryReferringUserOption;

        if (
            !mainType
            || !queryType
            || (opt && opt.includeMainTypes && indexOf(opt.includeMainTypes, mainType) < 0)
        ) {
            return;
        }

        mainTypeSpecified = mainTypeSpecified || !!mainType;

        const queryOption = queryOptionMap.get(mainType) || queryOptionMap.set(mainType, {});
        queryOption[queryType] = value as any;
    });

    const defaultMainType = opt ? opt.defaultMainType : null;
    if (!mainTypeSpecified && defaultMainType) {
        queryOptionMap.set(defaultMainType, {});
    }

    queryOptionMap.each(function (queryOption, mainType) {
        const queryResult = queryReferringComponents(
            ecModel,
            mainType,
            queryOption,
            {
                useDefault: defaultMainType === mainType,
                enableAll: (opt && opt.enableAll != null) ? opt.enableAll : true,
                enableNone: (opt && opt.enableNone != null) ? opt.enableNone : true
            }
        );
        result[mainType + 'Models'] = queryResult.models;
        result[mainType + 'Model'] = queryResult.models[0];
    });

    return result;
}

export type QueryReferringUserOption = {
    index?: ModelFinderIndexQuery,
    id?: ModelFinderIdQuery,
    name?: ModelFinderNameQuery,
};

export const SINGLE_REFERRING: QueryReferringOpt = { useDefault: true, enableAll: false, enableNone: false };
export const MULTIPLE_REFERRING: QueryReferringOpt = { useDefault: false, enableAll: true, enableNone: true };

export type QueryReferringOpt = {
    // Whether to use the first componet as the default if none of index/id/name are specified.
    useDefault?: boolean;
    // Whether to enable `'all'` on index option.
    enableAll?: boolean;
    // Whether to enable `'none'`/`false` on index option.
    enableNone?: boolean;
};

export function queryReferringComponents(
    ecModel: GlobalModel,
    mainType: ComponentMainType,
    userOption: QueryReferringUserOption,
    opt?: QueryReferringOpt
): {
    // Always be array rather than null/undefined, which is convenient to use.
    models: ComponentModel[];
    // Whether there is indexOption/id/name specified
    specified: boolean;
} {
    opt = opt || SINGLE_REFERRING as QueryReferringOpt;
    let indexOption = userOption.index;
    let idOption = userOption.id;
    let nameOption = userOption.name;

    const result = {
        models: null as ComponentModel[],
        specified: indexOption != null || idOption != null || nameOption != null
    };

    if (!result.specified) {
        // Use the first as default if `useDefault`.
        let firstCmpt;
        result.models = (
            opt.useDefault && (firstCmpt = ecModel.getComponent(mainType))
        ) ? [firstCmpt] : [];
        return result;
    }

    if (indexOption === 'none' || indexOption === false) {
        assert(opt.enableNone, '`"none"` or `false` is not a valid value on index option.');
        result.models = [];
        return result;
    }

    // `queryComponents` will return all components if
    // both all of index/id/name are null/undefined.
    if (indexOption === 'all') {
        assert(opt.enableAll, '`"all"` is not a valid value on index option.');
        indexOption = idOption = nameOption = null;
    }
    result.models = ecModel.queryComponents({
        mainType: mainType,
        index: indexOption as number | number[],
        id: idOption,
        name: nameOption
    });
    return result;
}

export function setAttribute(dom: HTMLElement, key: string, value: any) {
    dom.setAttribute
        ? dom.setAttribute(key, value)
        : ((dom as any)[key] = value);
}

export function getAttribute(dom: HTMLElement, key: string): any {
    return dom.getAttribute
        ? dom.getAttribute(key)
        : (dom as any)[key];
}

export function getTooltipRenderMode(renderModeOption: TooltipRenderMode | 'auto'): TooltipRenderMode {
    if (renderModeOption === 'auto') {
        // Using html when `document` exists, use richText otherwise
        return env.domSupported ? 'html' : 'richText';
    }
    else {
        return renderModeOption || 'html';
    }
}

/**
 * Group a list by key.
 */
export function groupData<T, R extends string | number>(
    array: T[],
    getKey: (item: T) => R // return key
): {
    keys: R[],
    buckets: HashMap<T[], R> // hasmap key: the key returned by `getKey`.
} {
    const buckets = createHashMap<T[], R>();
    const keys: R[] = [];

    each(array, function (item) {
        const key = getKey(item);
        (buckets.get(key)
            || (keys.push(key), buckets.set(key, []))
        ).push(item);
    });

    return {
        keys: keys,
        buckets: buckets
    };
}


/**
 * Interpolate raw values of a series with percent
 *
 * @param data         data
 * @param labelModel   label model of the text element
 * @param sourceValue  start value. May be null/undefined when init.
 * @param targetValue  end value
 * @param percent      0~1 percentage; 0 uses start value while 1 uses end value
 * @return             interpolated values
 */
export function interpolateRawValues(
    data: List,
    precision: number | 'auto',
    sourceValue: ParsedValue[] | ParsedValue,
    targetValue: ParsedValue[] | ParsedValue,
    percent: number
): (string | number)[] | string | number {
    const isAutoPrecision = precision == null || precision === 'auto';

    if (targetValue == null) {
        return targetValue;
    }

    if (typeof targetValue === 'number') {
        const value = interpolateNumber(
            sourceValue as number || 0,
            targetValue as number,
            percent
        );
        return round(
            value,
            isAutoPrecision ? Math.max(
                getPrecisionSafe(sourceValue as number || 0),
                getPrecisionSafe(targetValue as number)
            )
            : precision as number
        );
    }
    else if (typeof targetValue === 'string') {
        return percent < 1 ? sourceValue : targetValue;
    }
    else {
        const interpolated = [];
        const leftArr = sourceValue as (string | number)[];
        const rightArr = targetValue as (string | number[]);
        const length = Math.max(leftArr ? leftArr.length : 0, rightArr.length);
        for (let i = 0; i < length; ++i) {
            const info = data.getDimensionInfo(i);
            // Don't interpolate ordinal dims
            if (info.type === 'ordinal') {
                // In init, there is no `sourceValue`, but should better not to get undefined result.
                interpolated[i] = (percent < 1 && leftArr ? leftArr : rightArr)[i] as number;
            }
            else {
                const leftVal = leftArr && leftArr[i] ? leftArr[i] as number : 0;
                const rightVal = rightArr[i] as number;
                const value = interpolateNumber(leftVal, rightVal, percent);
                interpolated[i] = round(
                    value,
                    isAutoPrecision ? Math.max(
                        getPrecisionSafe(leftVal),
                        getPrecisionSafe(rightVal)
                    )
                    : precision as number
                );
            }
        }
        return interpolated;
    }
}