/*
* 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 * as zrUtil from 'zrender/src/core/util';
import visualDefault from '../../visual/visualDefault';
import VisualMapping, { VisualMappingOption } from '../../visual/VisualMapping';
import * as visualSolution from '../../visual/visualSolution';
import * as modelUtil from '../../util/model';
import * as numberUtil from '../../util/number';
import {
    ComponentOption,
    BoxLayoutOptionMixin,
    LabelOption,
    ColorString,
    ZRColor,
    BorderOptionMixin,
    OptionDataValue,
    BuiltinVisualProperty,
    DimensionIndex
} from '../../util/types';
import ComponentModel from '../../model/Component';
import Model from '../../model/Model';
import GlobalModel from '../../model/Global';
import SeriesModel from '../../model/Series';
import SeriesData from '../../data/SeriesData';

const mapVisual = VisualMapping.mapVisual;
const eachVisual = VisualMapping.eachVisual;
const isArray = zrUtil.isArray;
const each = zrUtil.each;
const asc = numberUtil.asc;
const linearMap = numberUtil.linearMap;

type VisualOptionBase = {[key in BuiltinVisualProperty]?: any};

type LabelFormatter = (min: OptionDataValue, max?: OptionDataValue) => string;

type VisualState = VisualMapModel['stateList'][number];
export interface VisualMapOption<T extends VisualOptionBase = VisualOptionBase> extends
    ComponentOption,
    BoxLayoutOptionMixin,
    BorderOptionMixin {

    mainType?: 'visualMap'

    show?: boolean

    align?: string

    realtime?: boolean
    /**
     * 'all' or null/undefined: all series.
     * A number or an array of number: the specified series.
     * set min: 0, max: 200, only for campatible with ec2.
     * In fact min max should not have default value.
     */
    seriesIndex?: 'all' | number[] | number

    /**
     * min value, must specified if pieces is not specified.
     */
    min?: number

    /**
     * max value, must specified if pieces is not specified.
     */
    max?: number
    /**
     * Dimension to be encoded
     */
    dimension?: number

    /**
     * Visual configuration for the data in selection
     */
    inRange?: T
    /**
     * Visual configuration for the out of selection
     */
    outOfRange?: T

    controller?: {
        inRange?: T
        outOfRange?: T
    }
    target?: {
        inRange?: T
        outOfRange?: T
    }

    /**
     * Width of the display item
     */
    itemWidth?: number
    /**
     * Height of the display item
     */
    itemHeight?: number

    inverse?: boolean

    orient?: 'horizontal' | 'vertical'

    backgroundColor?: ZRColor
    contentColor?: ZRColor

    inactiveColor?: ZRColor

    /**
     * Padding of the component. Can be an array similar to CSS
     */
    padding?: number[] | number
    /**
     * Gap between text and item
     */
    textGap?: number

    precision?: number

    /**
     * @deprecated
     * Option from version 2
     */
    color?: ColorString[]

    formatter?: string | LabelFormatter

    /**
     * Text on the both end. Such as ['High', 'Low']
     */
    text?: string[]

    textStyle?: LabelOption


    categories?: unknown
}

export interface VisualMeta {
    stops: { value: number, color: ColorString}[]
    outerColors: ColorString[]

    dimension?: DimensionIndex
}

class VisualMapModel<Opts extends VisualMapOption = VisualMapOption> extends ComponentModel<Opts> {

    static type = 'visualMap';
    type = VisualMapModel.type;

    static readonly dependencies = ['series'];

    readonly stateList = ['inRange', 'outOfRange'] as const;

    readonly replacableOptionKeys = [
        'inRange', 'outOfRange', 'target', 'controller', 'color'
    ] as const;

    readonly layoutMode = {
        type: 'box', ignoreSize: true
    } as const;

    /**
     * [lowerBound, upperBound]
     */
    dataBound = [-Infinity, Infinity];

    protected _dataExtent: [number, number];

    targetVisuals = {} as ReturnType<typeof visualSolution.createVisualMappings>;

    controllerVisuals = {} as ReturnType<typeof visualSolution.createVisualMappings>;

    textStyleModel: Model<LabelOption>;

    itemSize: number[];

    init(option: Opts, parentModel: Model, ecModel: GlobalModel) {
        this.mergeDefaultAndTheme(option, ecModel);
    }

    /**
     * @protected
     */
    optionUpdated(newOption: Opts, isInit?: boolean) {
        const thisOption = this.option;

        !isInit && visualSolution.replaceVisualOption(
            thisOption, newOption, this.replacableOptionKeys
        );

        this.textStyleModel = this.getModel('textStyle');

        this.resetItemSize();

        this.completeVisualOption();
    }

    /**
     * @protected
     */
    resetVisual(
        supplementVisualOption: (this: this, mappingOption: VisualMappingOption, state: string) => void
    ) {
        const stateList = this.stateList;
        supplementVisualOption = zrUtil.bind(supplementVisualOption, this);

        this.controllerVisuals = visualSolution.createVisualMappings(
            this.option.controller, stateList, supplementVisualOption
        );
        this.targetVisuals = visualSolution.createVisualMappings(
            this.option.target, stateList, supplementVisualOption
        );
    }

    /**
     * @public
     */
    getItemSymbol(): string {
        return null;
    }

    /**
     * @protected
     * @return {Array.<number>} An array of series indices.
     */
    getTargetSeriesIndices() {
        const optionSeriesIndex = this.option.seriesIndex;
        let seriesIndices: number[] = [];

        if (optionSeriesIndex == null || optionSeriesIndex === 'all') {
            this.ecModel.eachSeries(function (seriesModel, index) {
                seriesIndices.push(index);
            });
        }
        else {
            seriesIndices = modelUtil.normalizeToArray(optionSeriesIndex);
        }

        return seriesIndices;
    }

    /**
     * @public
     */
    eachTargetSeries<Ctx>(
        callback: (this: Ctx, series: SeriesModel) => void,
        context?: Ctx
    ) {
        zrUtil.each(this.getTargetSeriesIndices(), function (seriesIndex) {
            const seriesModel = this.ecModel.getSeriesByIndex(seriesIndex);
            if (seriesModel) {
                callback.call(context, seriesModel);
            }
        }, this);
    }

    /**
     * @pubilc
     */
    isTargetSeries(seriesModel: SeriesModel) {
        let is = false;
        this.eachTargetSeries(function (model) {
            model === seriesModel && (is = true);
        });
        return is;
    }

    /**
     * @example
     * this.formatValueText(someVal); // format single numeric value to text.
     * this.formatValueText(someVal, true); // format single category value to text.
     * this.formatValueText([min, max]); // format numeric min-max to text.
     * this.formatValueText([this.dataBound[0], max]); // using data lower bound.
     * this.formatValueText([min, this.dataBound[1]]); // using data upper bound.
     *
     * @param value Real value, or this.dataBound[0 or 1].
     * @param isCategory Only available when value is number.
     * @param edgeSymbols Open-close symbol when value is interval.
     * @protected
     */
    formatValueText(
        value: number | string | number[],
        isCategory?: boolean,
        edgeSymbols?: string[]
    ): string {
        const option = this.option;
        const precision = option.precision;
        const dataBound = this.dataBound;
        const formatter = option.formatter;
        let isMinMax: boolean;
        edgeSymbols = edgeSymbols || ['<', '>'] as [string, string];

        if (zrUtil.isArray(value)) {
            value = value.slice();
            isMinMax = true;
        }

        const textValue = isCategory
            ? value as string   // Value is string when isCategory
            : (isMinMax
                ? [toFixed((value as number[])[0]), toFixed((value as number[])[1])]
                : toFixed(value as number)
            );

        if (zrUtil.isString(formatter)) {
            return formatter
                .replace('{value}', isMinMax ? (textValue as string[])[0] : textValue as string)
                .replace('{value2}', isMinMax ? (textValue as string[])[1] : textValue as string);
        }
        else if (zrUtil.isFunction(formatter)) {
            return isMinMax
                ? formatter((value as number[])[0], (value as number[])[1])
                : formatter(value as number);
        }

        if (isMinMax) {
            if ((value as number[])[0] === dataBound[0]) {
                return edgeSymbols[0] + ' ' + textValue[1];
            }
            else if ((value as number[])[1] === dataBound[1]) {
                return edgeSymbols[1] + ' ' + textValue[0];
            }
            else {
                return textValue[0] + ' - ' + textValue[1];
            }
        }
        else { // Format single value (includes category case).
            return textValue as string;
        }

        function toFixed(val: number) {
            return val === dataBound[0]
                ? 'min'
                : val === dataBound[1]
                ? 'max'
                : (+val).toFixed(Math.min(precision, 20));
        }
    }

    /**
     * @protected
     */
    resetExtent() {
        const thisOption = this.option;

        // Can not calculate data extent by data here.
        // Because series and data may be modified in processing stage.
        // So we do not support the feature "auto min/max".

        const extent = asc([thisOption.min, thisOption.max] as [number, number]);

        this._dataExtent = extent;
    }

    /**
     * PENDING:
     * delete this method if no outer usage.
     *
     * Return  Concrete dimention. If return null/undefined, no dimension used.
     */
    // getDataDimension(data: SeriesData) {
    //     const optDim = this.option.dimension;

    //     if (optDim != null) {
    //         return data.getDimension(optDim);
    //     }

    //     const dimNames = data.dimensions;
    //     for (let i = dimNames.length - 1; i >= 0; i--) {
    //         const dimName = dimNames[i];
    //         const dimInfo = data.getDimensionInfo(dimName);
    //         if (!dimInfo.isCalculationCoord) {
    //             return dimName;
    //         }
    //     }
    // }

    getDataDimensionIndex(data: SeriesData): DimensionIndex {
        const optDim = this.option.dimension;

        if (optDim != null) {
            return data.getDimensionIndex(optDim);
        }

        const dimNames = data.dimensions;
        for (let i = dimNames.length - 1; i >= 0; i--) {
            const dimName = dimNames[i];
            const dimInfo = data.getDimensionInfo(dimName);
            if (!dimInfo.isCalculationCoord) {
                return dimInfo.storeDimIndex;
            }
        }
    }

    getExtent() {
        return this._dataExtent.slice() as [number, number];
    }

    completeVisualOption() {

        const ecModel = this.ecModel;
        const thisOption = this.option;
        const base = {
            inRange: thisOption.inRange,
            outOfRange: thisOption.outOfRange
        };

        const target = thisOption.target || (thisOption.target = {});
        const controller = thisOption.controller || (thisOption.controller = {});

        zrUtil.merge(target, base); // Do not override
        zrUtil.merge(controller, base); // Do not override

        const isCategory = this.isCategory();

        completeSingle.call(this, target);
        completeSingle.call(this, controller);
        completeInactive.call(this, target, 'inRange', 'outOfRange');
        // completeInactive.call(this, target, 'outOfRange', 'inRange');
        completeController.call(this, controller);

        function completeSingle(this: VisualMapModel, base: VisualMapOption['target']) {
            // Compatible with ec2 dataRange.color.
            // The mapping order of dataRange.color is: [high value, ..., low value]
            // whereas inRange.color and outOfRange.color is [low value, ..., high value]
            // Notice: ec2 has no inverse.
            if (isArray(thisOption.color)
                // If there has been inRange: {symbol: ...}, adding color is a mistake.
                // So adding color only when no inRange defined.
                && !base.inRange
            ) {
                base.inRange = {color: thisOption.color.slice().reverse()};
            }

            // Compatible with previous logic, always give a defautl color, otherwise
            // simple config with no inRange and outOfRange will not work.
            // Originally we use visualMap.color as the default color, but setOption at
            // the second time the default color will be erased. So we change to use
            // constant DEFAULT_COLOR.
            // If user do not want the default color, set inRange: {color: null}.
            base.inRange = base.inRange || {color: ecModel.get('gradientColor')};
        }

        function completeInactive(
            this: VisualMapModel,
            base: VisualMapOption['target'],
            stateExist: VisualState,
            stateAbsent: VisualState
        ) {
            const optExist = base[stateExist];
            let optAbsent = base[stateAbsent];

            if (optExist && !optAbsent) {
                optAbsent = base[stateAbsent] = {};
                each(optExist, function (visualData, visualType: BuiltinVisualProperty) {
                    if (!VisualMapping.isValidType(visualType)) {
                        return;
                    }

                    const defa = visualDefault.get(visualType, 'inactive', isCategory);

                    if (defa != null) {
                        optAbsent[visualType] = defa;

                        // Compatibable with ec2:
                        // Only inactive color to rgba(0,0,0,0) can not
                        // make label transparent, so use opacity also.
                        if (visualType === 'color'
                            && !optAbsent.hasOwnProperty('opacity')
                            && !optAbsent.hasOwnProperty('colorAlpha')
                        ) {
                            optAbsent.opacity = [0, 0];
                        }
                    }
                });
            }
        }

        function completeController(this: VisualMapModel, controller?: VisualMapOption['controller']) {
            const symbolExists = (controller.inRange || {}).symbol
                || (controller.outOfRange || {}).symbol;
            const symbolSizeExists = (controller.inRange || {}).symbolSize
                || (controller.outOfRange || {}).symbolSize;
            const inactiveColor = this.get('inactiveColor');
            const itemSymbol = this.getItemSymbol();
            const defaultSymbol = itemSymbol || 'roundRect';

            each(this.stateList, function (state: VisualState) {

                const itemSize = this.itemSize;
                let visuals = controller[state];

                // Set inactive color for controller if no other color
                // attr (like colorAlpha) specified.
                if (!visuals) {
                    visuals = controller[state] = {
                        color: isCategory ? inactiveColor : [inactiveColor]
                    };
                }

                // Consistent symbol and symbolSize if not specified.
                if (visuals.symbol == null) {
                    visuals.symbol = symbolExists
                        && zrUtil.clone(symbolExists)
                        || (isCategory ? defaultSymbol : [defaultSymbol]);
                }
                if (visuals.symbolSize == null) {
                    visuals.symbolSize = symbolSizeExists
                        && zrUtil.clone(symbolSizeExists)
                        || (isCategory ? itemSize[0] : [itemSize[0], itemSize[0]]);
                }

                // Filter none
                visuals.symbol = mapVisual(visuals.symbol, function (symbol) {
                    return symbol === 'none' ? defaultSymbol : symbol;
                });

                // Normalize symbolSize
                const symbolSize = visuals.symbolSize;

                if (symbolSize != null) {
                    let max = -Infinity;
                    // symbolSize can be object when categories defined.
                    eachVisual(symbolSize, function (value) {
                        value > max && (max = value);
                    });
                    visuals.symbolSize = mapVisual(symbolSize, function (value) {
                        return linearMap(value, [0, max], [0, itemSize[0]], true);
                    });
                }

            }, this);
        }
    }

    resetItemSize() {
        this.itemSize = [
            parseFloat(this.get('itemWidth') as unknown as string),
            parseFloat(this.get('itemHeight') as unknown as string)
        ];
    }

    isCategory() {
        return !!this.option.categories;
    }

    /**
     * @public
     * @abstract
     */
    setSelected(selected?: any) {}

    getSelected(): any {
        return null;
    }

    /**
     * @public
     * @abstract
     */
    getValueState(value: any): VisualMapModel['stateList'][number] {
        return null;
    }

    /**
     * FIXME
     * Do not publish to thirt-part-dev temporarily
     * util the interface is stable. (Should it return
     * a function but not visual meta?)
     *
     * @pubilc
     * @abstract
     * @param getColorVisual
     *        params: value, valueState
     *        return: color
     * @return {Object} visualMeta
     *        should includes {stops, outerColors}
     *        outerColor means [colorBeyondMinValue, colorBeyondMaxValue]
     */
    getVisualMeta(getColorVisual: (value: number, valueState: VisualState) => string): VisualMeta {
        return null;
    }


    static defaultOption: VisualMapOption = {
        show: true,

        // zlevel: 0,
        z: 4,

        seriesIndex: 'all',

        min: 0,
        max: 200,

        left: 0,
        right: null,
        top: null,
        bottom: 0,

        itemWidth: null,
        itemHeight: null,
        inverse: false,
        orient: 'vertical',        // 'horizontal' ¦ 'vertical'

        backgroundColor: 'rgba(0,0,0,0)',
        borderColor: '#ccc',       // 值域边框颜色
        contentColor: '#5793f3',
        inactiveColor: '#aaa',
        borderWidth: 0,
        padding: 5,
                                    // 接受数组分别设定上右下左边距，同css
        textGap: 10,               //
        precision: 0,              // 小数精度，默认为0，无小数点

        textStyle: {
            color: '#333'          // 值域文字颜色
        }
    };
}

export default VisualMapModel;
