/*
* 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 ZRText, { TextProps, TextStyleProps } from 'zrender/src/graphic/Text';
import { Dictionary } from 'zrender/src/core/types';
import Element, { ElementTextConfig } from 'zrender/src/Element';
import Model from '../model/Model';
import {
    LabelOption,
    DisplayState,
    TextCommonOption,
    StatesOptionMixin,
    DisplayStateNonNormal,
    ColorString,
    ZRStyleProps,
    AnimationOptionMixin,
    InterpolatableValue
} from '../util/types';
import GlobalModel from '../model/Global';
import { isFunction, retrieve2, extend, keys, trim } from 'zrender/src/core/util';
import { SPECIAL_STATES, DISPLAY_STATES } from '../util/states';
import { deprecateReplaceLog } from '../util/log';
import { makeInner, interpolateRawValues } from '../util/model';
import SeriesData from '../data/SeriesData';
import { initProps, updateProps } from '../util/graphic';

type TextCommonParams = {
    /**
     * Whether disable drawing box of block (outer most).
     */
    disableBox?: boolean
    /**
     * Specify a color when color is 'inherit',
     * If inheritColor specified, it is used as default textFill.
     */
    inheritColor?: ColorString

    /**
     * Specify a opacity when opacity is not given.
     */
    defaultOpacity?: number

    defaultOutsidePosition?: LabelOption['position']

    /**
     * If support legacy 'auto' for 'inherit' usage.
     */
    // supportLegacyAuto?: boolean

    textStyle?: ZRStyleProps
};
const EMPTY_OBJ = {};

interface SetLabelStyleOpt<TLabelDataIndex> extends TextCommonParams {
    defaultText?: string | ((
        labelDataIndex: TLabelDataIndex,
        opt: SetLabelStyleOpt<TLabelDataIndex>,
        interpolatedValue?: InterpolatableValue
    ) => string);
    // Fetch text by:
    // opt.labelFetcher.getFormattedLabel(
    //     opt.labelDataIndex, 'normal'/'emphasis', null, opt.labelDimIndex, opt.labelProp
    // )
    labelFetcher?: {
        getFormattedLabel: (
            // In MapDraw case it can be string (region name)
            labelDataIndex: TLabelDataIndex,
            status: DisplayState,
            dataType?: string,
            labelDimIndex?: number,
            formatter?: string | ((params: object) => string),
            // If provided, the implementation of `getFormattedLabel` can use it
            // to generate the final label text.
            extendParams?: {
                interpolatedValue: InterpolatableValue
            }
        ) => string;
    };
    labelDataIndex?: TLabelDataIndex;
    labelDimIndex?: number;

    /**
     * Inject a setter of text for the text animation case.
     */
    enableTextSetter?: boolean
}
type LabelModel = Model<LabelOption & {
    formatter?: string | ((params: any) => string);
    showDuringLabel?: boolean // Currently only supported by line charts
}>;
type LabelModelForText = Model<Omit<
    // Remove
    LabelOption, 'position' | 'rotate'> & {
        formatter?: string | ((params: any) => string);
    }>;

type LabelStatesModels<LabelModel> = Partial<Record<DisplayStateNonNormal, LabelModel>> & {normal: LabelModel};

export function setLabelText(label: ZRText, labelTexts: Record<DisplayState, string>) {
    for (let i = 0; i < SPECIAL_STATES.length; i++) {
        const stateName = SPECIAL_STATES[i];
        const text = labelTexts[stateName];
        const state = label.ensureState(stateName);
        state.style = state.style || {};
        state.style.text = text;
    }

    const oldStates = label.currentStates.slice();
    label.clearStates(true);
    label.setStyle({ text: labelTexts.normal });
    label.useStates(oldStates, true);
}

function getLabelText<TLabelDataIndex>(
    opt: SetLabelStyleOpt<TLabelDataIndex>,
    stateModels: LabelStatesModels<LabelModel>,
    interpolatedValue?: InterpolatableValue
): Record<DisplayState, string> {
    const labelFetcher = opt.labelFetcher;
    const labelDataIndex = opt.labelDataIndex;
    const labelDimIndex = opt.labelDimIndex;
    const normalModel = stateModels.normal;
    let baseText;
    if (labelFetcher) {
        baseText = labelFetcher.getFormattedLabel(
            labelDataIndex, 'normal',
            null,
            labelDimIndex,
            normalModel && normalModel.get('formatter'),
            interpolatedValue != null ? {
                interpolatedValue: interpolatedValue
            } : null
        );
    }
    if (baseText == null) {
        baseText = isFunction(opt.defaultText)
            ? opt.defaultText(labelDataIndex, opt, interpolatedValue)
            : opt.defaultText;
    }

    const statesText = {
        normal: baseText
    } as Record<DisplayState, string>;

    for (let i = 0; i < SPECIAL_STATES.length; i++) {
        const stateName = SPECIAL_STATES[i];
        const stateModel = stateModels[stateName];
        statesText[stateName] = retrieve2(labelFetcher
            ? labelFetcher.getFormattedLabel(
                labelDataIndex,
                stateName,
                null,
                labelDimIndex,
                stateModel && stateModel.get('formatter')
            )
            : null, baseText);
    }
    return statesText;
}
/**
 * Set normal styles and emphasis styles about text on target element
 * If target is a ZRText. It will create a new style object.
 * If target is other Element. It will create or reuse ZRText which is attached on the target.
 * And create a new style object.
 *
 * NOTICE: Because the style on ZRText will be replaced with new(only x, y are keeped).
 * So please update the style on ZRText after use this method.
 */
// eslint-disable-next-line
function setLabelStyle<TLabelDataIndex>(
    targetEl: ZRText,
    labelStatesModels: LabelStatesModels<LabelModelForText>,
    opt?: SetLabelStyleOpt<TLabelDataIndex>,
    stateSpecified?: Partial<Record<DisplayState, TextStyleProps>>
): void;
// eslint-disable-next-line
function setLabelStyle<TLabelDataIndex>(
    targetEl: Element,
    labelStatesModels: LabelStatesModels<LabelModel>,
    opt?: SetLabelStyleOpt<TLabelDataIndex>,
    stateSpecified?: Partial<Record<DisplayState, TextStyleProps>>
): void;
function setLabelStyle<TLabelDataIndex>(
    targetEl: Element,
    labelStatesModels: LabelStatesModels<LabelModel>,
    opt?: SetLabelStyleOpt<TLabelDataIndex>,
    stateSpecified?: Partial<Record<DisplayState, TextStyleProps>>
    // TODO specified position?
) {
    opt = opt || EMPTY_OBJ;
    const isSetOnText = targetEl instanceof ZRText;
    let needsCreateText = false;
    for (let i = 0; i < DISPLAY_STATES.length; i++) {
        const stateModel = labelStatesModels[DISPLAY_STATES[i]];
        if (stateModel && stateModel.getShallow('show')) {
            needsCreateText = true;
            break;
        }
    }
    let textContent = isSetOnText ? targetEl as ZRText : targetEl.getTextContent();
    if (needsCreateText) {
        if (!isSetOnText) {
            // Reuse the previous
            if (!textContent) {
                textContent = new ZRText();
                targetEl.setTextContent(textContent);
            }
            // Use same state proxy
            if (targetEl.stateProxy) {
                textContent.stateProxy = targetEl.stateProxy;
            }
        }
        const labelStatesTexts = getLabelText(opt, labelStatesModels);

        const normalModel = labelStatesModels.normal;
        const showNormal = !!normalModel.getShallow('show');
        const normalStyle = createTextStyle(
            normalModel, stateSpecified && stateSpecified.normal, opt, false, !isSetOnText
        );
        normalStyle.text = labelStatesTexts.normal;
        if (!isSetOnText) {
            // Always create new
            targetEl.setTextConfig(createTextConfig(normalModel, opt, false));
        }

        for (let i = 0; i < SPECIAL_STATES.length; i++) {
            const stateName = SPECIAL_STATES[i];
            const stateModel = labelStatesModels[stateName];

            if (stateModel) {
                const stateObj = textContent.ensureState(stateName);
                const stateShow = !!retrieve2(stateModel.getShallow('show'), showNormal);
                if (stateShow !== showNormal) {
                    stateObj.ignore = !stateShow;
                }
                stateObj.style = createTextStyle(
                    stateModel, stateSpecified && stateSpecified[stateName], opt, true, !isSetOnText
                );
                stateObj.style.text = labelStatesTexts[stateName];

                if (!isSetOnText) {
                    const targetElEmphasisState = targetEl.ensureState(stateName);
                    targetElEmphasisState.textConfig = createTextConfig(stateModel, opt, true);
                }
            }
        }

        // PENDING: if there is many requirements that emphasis position
        // need to be different from normal position, we might consider
        // auto silent is those cases.
        textContent.silent = !!normalModel.getShallow('silent');
        // Keep x and y
        if (textContent.style.x != null) {
            normalStyle.x = textContent.style.x;
        }
        if (textContent.style.y != null) {
            normalStyle.y = textContent.style.y;
        }
        textContent.ignore = !showNormal;
        // Always create new style.
        textContent.useStyle(normalStyle);
        textContent.dirty();

        if (opt.enableTextSetter) {
            labelInner(textContent).setLabelText = function (interpolatedValue: InterpolatableValue) {
                const labelStatesTexts = getLabelText(opt, labelStatesModels, interpolatedValue);
                setLabelText(textContent, labelStatesTexts);
            };
        }
    }
    else if (textContent) {
        // Not display rich text.
        textContent.ignore = true;
    }
    targetEl.dirty();
}
export { setLabelStyle };

export function getLabelStatesModels<LabelName extends string = 'label'>(
    itemModel: Model<StatesOptionMixin<any, any> & Partial<Record<LabelName, any>>>,
    labelName?: LabelName
): Record<DisplayState, LabelModel> {
    labelName = (labelName || 'label') as LabelName;
    const statesModels = {
        normal: itemModel.getModel(labelName) as LabelModel
    } as Record<DisplayState, LabelModel>;
    for (let i = 0; i < SPECIAL_STATES.length; i++) {
        const stateName = SPECIAL_STATES[i];
        statesModels[stateName] = itemModel.getModel([stateName, labelName]);
    }
    return statesModels;
}
/**
 * Set basic textStyle properties.
 */
export function createTextStyle(
    textStyleModel: Model,
    specifiedTextStyle?: TextStyleProps, // Fixed style in the code. Can't be set by model.
    opt?: Pick<TextCommonParams, 'inheritColor' | 'disableBox'>,
    isNotNormal?: boolean,
    isAttached?: boolean // If text is attached on an element. If so, auto color will handling in zrender.
) {
    const textStyle: TextStyleProps = {};
    setTextStyleCommon(textStyle, textStyleModel, opt, isNotNormal, isAttached);
    specifiedTextStyle && extend(textStyle, specifiedTextStyle);
    // textStyle.host && textStyle.host.dirty && textStyle.host.dirty(false);
    return textStyle;
}
export function createTextConfig(
    textStyleModel: Model,
    opt?: Pick<TextCommonParams, 'defaultOutsidePosition' | 'inheritColor'>,
    isNotNormal?: boolean
) {
    opt = opt || {};
    const textConfig: ElementTextConfig = {};
    let labelPosition;
    let labelRotate = textStyleModel.getShallow('rotate');
    const labelDistance = retrieve2(textStyleModel.getShallow('distance'), isNotNormal ? null : 5);
    const labelOffset = textStyleModel.getShallow('offset');
    labelPosition = textStyleModel.getShallow('position')
        || (isNotNormal ? null : 'inside');
    // 'outside' is not a valid zr textPostion value, but used
    // in bar series, and magric type should be considered.
    labelPosition === 'outside' && (labelPosition = opt.defaultOutsidePosition || 'top');
    if (labelPosition != null) {
        textConfig.position = labelPosition;
    }
    if (labelOffset != null) {
        textConfig.offset = labelOffset;
    }
    if (labelRotate != null) {
        labelRotate *= Math.PI / 180;
        textConfig.rotation = labelRotate;
    }
    if (labelDistance != null) {
        textConfig.distance = labelDistance;
    }
    // fill and auto is determined by the color of path fill if it's not specified by developers.
    textConfig.outsideFill = textStyleModel.get('color') === 'inherit'
        ? (opt.inheritColor || null)
        : 'auto';
    return textConfig;
}
/**
 * The uniform entry of set text style, that is, retrieve style definitions
 * from `model` and set to `textStyle` object.
 *
 * Never in merge mode, but in overwrite mode, that is, all of the text style
 * properties will be set. (Consider the states of normal and emphasis and
 * default value can be adopted, merge would make the logic too complicated
 * to manage.)
 */
function setTextStyleCommon(
    textStyle: TextStyleProps,
    textStyleModel: Model,
    opt?: Pick<TextCommonParams, 'inheritColor' | 'defaultOpacity' | 'disableBox'>,
    isNotNormal?: boolean,
    isAttached?: boolean
) {
    // Consider there will be abnormal when merge hover style to normal style if given default value.
    opt = opt || EMPTY_OBJ;
    const ecModel = textStyleModel.ecModel;
    const globalTextStyle = ecModel && ecModel.option.textStyle;
    // Consider case:
    // {
    //     data: [{
    //         value: 12,
    //         label: {
    //             rich: {
    //                 // no 'a' here but using parent 'a'.
    //             }
    //         }
    //     }],
    //     rich: {
    //         a: { ... }
    //     }
    // }
    const richItemNames = getRichItemNames(textStyleModel);
    let richResult: TextStyleProps['rich'];
    if (richItemNames) {
        richResult = {};
        for (const name in richItemNames) {
            if (richItemNames.hasOwnProperty(name)) {
                // Cascade is supported in rich.
                const richTextStyle = textStyleModel.getModel(['rich', name]);
                // In rich, never `disableBox`.
                // FIXME: consider `label: {formatter: '{a|xx}', color: 'blue', rich: {a: {}}}`,
                // the default color `'blue'` will not be adopted if no color declared in `rich`.
                // That might confuses users. So probably we should put `textStyleModel` as the
                // root ancestor of the `richTextStyle`. But that would be a break change.
                setTokenTextStyle(
                    richResult[name] = {}, richTextStyle, globalTextStyle, opt, isNotNormal, isAttached, false, true
                );
            }
        }
    }
    if (richResult) {
        textStyle.rich = richResult;
    }
    const overflow = textStyleModel.get('overflow');
    if (overflow) {
        textStyle.overflow = overflow;
    }
    const margin = textStyleModel.get('minMargin');
    if (margin != null) {
        textStyle.margin = margin;
    }
    setTokenTextStyle(textStyle, textStyleModel, globalTextStyle, opt, isNotNormal, isAttached, true, false);
}
// Consider case:
// {
//     data: [{
//         value: 12,
//         label: {
//             rich: {
//                 // no 'a' here but using parent 'a'.
//             }
//         }
//     }],
//     rich: {
//         a: { ... }
//     }
// }
// TODO TextStyleModel
function getRichItemNames(textStyleModel: Model<LabelOption>) {
    // Use object to remove duplicated names.
    let richItemNameMap: Dictionary<number>;
    while (textStyleModel && textStyleModel !== textStyleModel.ecModel) {
        const rich = (textStyleModel.option || EMPTY_OBJ as LabelOption).rich;
        if (rich) {
            richItemNameMap = richItemNameMap || {};
            const richKeys = keys(rich);
            for (let i = 0; i < richKeys.length; i++) {
                const richKey = richKeys[i];
                richItemNameMap[richKey] = 1;
            }
        }
        textStyleModel = textStyleModel.parentModel;
    }
    return richItemNameMap;
}
const TEXT_PROPS_WITH_GLOBAL = [
    'fontStyle', 'fontWeight', 'fontSize', 'fontFamily',
    'textShadowColor', 'textShadowBlur', 'textShadowOffsetX', 'textShadowOffsetY'
] as const;
const TEXT_PROPS_SELF = [
    'align', 'lineHeight', 'width', 'height', 'tag', 'verticalAlign'
] as const;
const TEXT_PROPS_BOX = [
    'padding', 'borderWidth', 'borderRadius', 'borderDashOffset',
    'backgroundColor', 'borderColor',
    'shadowColor', 'shadowBlur', 'shadowOffsetX', 'shadowOffsetY'
] as const;

function setTokenTextStyle(
    textStyle: TextStyleProps['rich'][string],
    textStyleModel: Model<LabelOption>,
    globalTextStyle: LabelOption,
    opt?: Pick<TextCommonParams, 'inheritColor' | 'defaultOpacity' | 'disableBox'>,
    isNotNormal?: boolean,
    isAttached?: boolean,
    isBlock?: boolean,
    inRich?: boolean
) {
    // In merge mode, default value should not be given.
    globalTextStyle = !isNotNormal && globalTextStyle || EMPTY_OBJ;
    const inheritColor = opt && opt.inheritColor;
    let fillColor = textStyleModel.getShallow('color');
    let strokeColor = textStyleModel.getShallow('textBorderColor');
    let opacity = retrieve2(textStyleModel.getShallow('opacity'), globalTextStyle.opacity);
    if (fillColor === 'inherit' || fillColor === 'auto') {
        if (__DEV__) {
            if (fillColor === 'auto') {
                deprecateReplaceLog('color: \'auto\'', 'color: \'inherit\'');
            }
        }
        if (inheritColor) {
            fillColor = inheritColor;
        }
        else {
            fillColor = null;
        }
    }
    if (strokeColor === 'inherit' || (strokeColor === 'auto')) {
        if (__DEV__) {
            if (strokeColor === 'auto') {
                deprecateReplaceLog('color: \'auto\'', 'color: \'inherit\'');
            }
        }
        if (inheritColor) {
            strokeColor = inheritColor;
        }
        else {
            strokeColor = null;
        }
    }
    if (!isAttached) {
        // Only use default global textStyle.color if text is individual.
        // Otherwise it will use the strategy of attached text color because text may be on a path.
        fillColor = fillColor || globalTextStyle.color;
        strokeColor = strokeColor || globalTextStyle.textBorderColor;
    }
    if (fillColor != null) {
        textStyle.fill = fillColor;
    }
    if (strokeColor != null) {
        textStyle.stroke = strokeColor;
    }
    const textBorderWidth = retrieve2(textStyleModel.getShallow('textBorderWidth'), globalTextStyle.textBorderWidth);
    if (textBorderWidth != null) {
        textStyle.lineWidth = textBorderWidth;
    }
    const textBorderType = retrieve2(textStyleModel.getShallow('textBorderType'), globalTextStyle.textBorderType);
    if (textBorderType != null) {
        textStyle.lineDash = textBorderType as any;
    }
    const textBorderDashOffset = retrieve2(
        textStyleModel.getShallow('textBorderDashOffset'), globalTextStyle.textBorderDashOffset
    );
    if (textBorderDashOffset != null) {
        textStyle.lineDashOffset = textBorderDashOffset;
    }

    if (!isNotNormal && (opacity == null) && !inRich) {
        opacity = opt && opt.defaultOpacity;
    }
    if (opacity != null) {
        textStyle.opacity = opacity;
    }

    // TODO
    if (!isNotNormal && !isAttached) {
        // Set default finally.
        if (textStyle.fill == null && opt.inheritColor) {
            textStyle.fill = opt.inheritColor;
        }
    }
    // Do not use `getFont` here, because merge should be supported, where
    // part of these properties may be changed in emphasis style, and the
    // others should remain their original value got from normal style.
    for (let i = 0; i < TEXT_PROPS_WITH_GLOBAL.length; i++) {
        const key = TEXT_PROPS_WITH_GLOBAL[i];
        const val = retrieve2(textStyleModel.getShallow(key), globalTextStyle[key]);
        if (val != null) {
            (textStyle as any)[key] = val;
        }
    }
    for (let i = 0; i < TEXT_PROPS_SELF.length; i++) {
        const key = TEXT_PROPS_SELF[i];
        const val = textStyleModel.getShallow(key);
        if (val != null) {
            (textStyle as any)[key] = val;
        }
    }
    if (textStyle.verticalAlign == null) {
        const baseline = textStyleModel.getShallow('baseline');
        if (baseline != null) {
            textStyle.verticalAlign = baseline;
        }
    }
    if (!isBlock || !opt.disableBox) {
        for (let i = 0; i < TEXT_PROPS_BOX.length; i++) {
            const key = TEXT_PROPS_BOX[i];
            const val = textStyleModel.getShallow(key);
            if (val != null) {
                (textStyle as any)[key] = val;
            }
        }

        const borderType = textStyleModel.getShallow('borderType');
        if (borderType != null) {
            textStyle.borderDash = borderType as any;
        }

        if ((textStyle.backgroundColor === 'auto' || textStyle.backgroundColor === 'inherit') && inheritColor) {
            if (__DEV__) {
                if (textStyle.backgroundColor === 'auto') {
                    deprecateReplaceLog('backgroundColor: \'auto\'', 'backgroundColor: \'inherit\'');
                }
            }
            textStyle.backgroundColor = inheritColor;
        }
        if ((textStyle.borderColor === 'auto' || textStyle.borderColor === 'inherit') && inheritColor) {
            if (__DEV__) {
                if (textStyle.borderColor === 'auto') {
                    deprecateReplaceLog('borderColor: \'auto\'', 'borderColor: \'inherit\'');
                }
            }
            textStyle.borderColor = inheritColor;
        }
    }
}

export function getFont(
    opt: Pick<TextCommonOption, 'fontStyle' | 'fontWeight' | 'fontSize' | 'fontFamily'>,
    ecModel: GlobalModel
) {
    const gTextStyleModel = ecModel && ecModel.getModel('textStyle');
    return trim([
        // FIXME in node-canvas fontWeight is before fontStyle
        opt.fontStyle || gTextStyleModel && gTextStyleModel.getShallow('fontStyle') || '',
        opt.fontWeight || gTextStyleModel && gTextStyleModel.getShallow('fontWeight') || '',
        (opt.fontSize || gTextStyleModel && gTextStyleModel.getShallow('fontSize') || 12) + 'px',
        opt.fontFamily || gTextStyleModel && gTextStyleModel.getShallow('fontFamily') || 'sans-serif'
    ].join(' '));
}

export const labelInner = makeInner<{
    /**
     * Previous target value stored used for label.
     * It's mainly for text animation
     */
    prevValue?: InterpolatableValue
    /**
     * Target value stored used for label.
     */
    value?: InterpolatableValue
    /**
     * Current value in text animation.
     */
    interpolatedValue?: InterpolatableValue
    /**
     * If enable value animation
     */
    valueAnimation?: boolean
    /**
     * Label value precision during animation.
     */
    precision?: number | 'auto'

    /**
     * If enable value animation
     */
    statesModels?: LabelStatesModels<LabelModelForText>
    /**
     * Default text getter during interpolation
     */
    defaultInterpolatedText?: (value: InterpolatableValue) => string
    /**
     * Change label text from interpolated text during animation
     */
    setLabelText?: (interpolatedValue?: InterpolatableValue) => void

}, ZRText>();

export function setLabelValueAnimation(
    label: ZRText,
    labelStatesModels: LabelStatesModels<LabelModelForText>,
    value: InterpolatableValue,
    getDefaultText: (value: InterpolatableValue) => string
) {
    if (!label) {
        return;
    }

    const obj = labelInner(label);
    obj.prevValue = obj.value;
    obj.value = value;
    const normalLabelModel = labelStatesModels.normal;

    obj.valueAnimation = normalLabelModel.get('valueAnimation');

    if (obj.valueAnimation) {
        obj.precision = normalLabelModel.get('precision');
        obj.defaultInterpolatedText = getDefaultText;
        obj.statesModels = labelStatesModels;
    }
}

export function animateLabelValue(
    textEl: ZRText,
    dataIndex: number,
    data: SeriesData,
    animatableModel: Model<AnimationOptionMixin>,
    labelFetcher: SetLabelStyleOpt<number>['labelFetcher']
) {
    const labelInnerStore = labelInner(textEl);
    if (!labelInnerStore.valueAnimation || labelInnerStore.prevValue === labelInnerStore.value) {
        // Value not changed, no new label animation
        return;
    }

    const defaultInterpolatedText = labelInnerStore.defaultInterpolatedText;
    // Consider the case that being animating, do not use the `obj.value`,
    // Otherwise it will jump to the `obj.value` when this new animation started.
    const currValue = retrieve2(labelInnerStore.interpolatedValue, labelInnerStore.prevValue);
    const targetValue = labelInnerStore.value;

    function during(percent: number) {
        const interpolated = interpolateRawValues(
            data,
            labelInnerStore.precision,
            currValue,
            targetValue,
            percent
        );

        labelInnerStore.interpolatedValue = percent === 1 ? null : interpolated;

        const labelText = getLabelText({
            labelDataIndex: dataIndex,
            labelFetcher: labelFetcher,
            defaultText: defaultInterpolatedText
                ? defaultInterpolatedText(interpolated)
                : interpolated + ''
        }, labelInnerStore.statesModels, interpolated);

        setLabelText(textEl, labelText);
    }

    (textEl as ZRText & {percent?: number}).percent = 0;
    (labelInnerStore.prevValue == null
        ? initProps
        : updateProps
    )<TextProps & {percent?: number}>(textEl, {
        // percent is used to prevent animation from being aborted #15916
        percent: 1
    }, animatableModel, dataIndex, null, during);
}
